eightsleep
Version:
eightsleep api client
139 lines (127 loc) • 4.29 kB
text/typescript
import { IncomingMessage, Server, ServerResponse, createServer } from 'http'
import AbstractStartable from 'abstract-startable'
import concat from 'concat-stream'
import deviceResponse from './deviceResponse'
import oauthResponse from './oauthResponse'
import ownerUserResponse from './ownerUserResponse'
import partnerUserResponse from './partnerUserResponse'
export const PORT = process.env.PORT || 3131
export default class MockEightClientAPIServer extends AbstractStartable {
server: Server | undefined
private _handleRequest(req: IncomingMessage, res: ServerResponse) {
const { method, url } = req
// login route
if (method === 'POST' && /^\/login/.test(url)) {
req.pipe(
concat((body) => {
const { email, password } = JSON.parse(body.toString())
if (email === 'owner@email.com' && password === 'ownerpassword') {
res.statusCode = 200
res.end(
JSON.stringify({
session: {
expirationDate: '3020-06-30T05:40:30.880Z',
userId: '1234567890abcdef123456789011111',
token:
'1234567890abcdef1234567890abcdef-1234567890abcdef1234567890abcdef',
},
}),
)
} else {
res.statusCode = 400
res.end(
JSON.stringify({
status: 400,
code: 'BadRequest',
error: 'Error logging in.',
}),
)
}
}),
)
return
}
// authorized routes
if (
req.headers['session-token'] !==
'1234567890abcdef1234567890abcdef-1234567890abcdef1234567890abcdef'
) {
res.statusCode = 401
res.end(JSON.stringify({ status: 401, code: 'Unauthorized' }))
return
}
// authorization is valid
if (method === 'PUT' && /^\/users\/me$/.test(url)) {
res.pipe(
concat((body) => {
res.statusCode = 200
const user = {
ownerUserResponse,
...JSON.parse(body.toString()),
}
const result = filterByQuery(user, url)
if (result) return res.end(JSON.stringify({ result }))
res.end(JSON.stringify({ user }))
}),
)
} else if (
method === 'GET' &&
/^\/users\/(me|1234567890abcdef123456789011111)$/.test(url)
) {
res.statusCode = 200
const result = filterByQuery(ownerUserResponse, url)
if (result) return res.end(JSON.stringify({ result }))
res.end(JSON.stringify({ user: ownerUserResponse }))
} else if (
method === 'GET' &&
/^\/users\/(1234567890abcdef123456789022222)$/.test(url)
) {
res.statusCode = 200
const result = filterByQuery(partnerUserResponse, url)
if (result) return res.end(JSON.stringify({ result }))
res.end(JSON.stringify({ user: partnerUserResponse }))
} else if (
method === 'GET' &&
/^\/devices\/123456789012345678901234/.test(url)
) {
res.statusCode = 200
const result = filterByQuery(deviceResponse, url)
if (result) return res.end(JSON.stringify({ result }))
res.end(JSON.stringify({ result: deviceResponse }))
} else if (method === 'POST' && /^\/users\/oauth-token$/) {
res.statusCode = 200
res.end(JSON.stringify(oauthResponse))
} else {
res.statusCode = 404
res.end()
}
}
protected async _start(): Promise<void> {
return new Promise((resolve, reject) => {
const server = (this.server = createServer(this._handleRequest))
server.once('error', reject)
server.listen(PORT, () => {
server.off('error', reject)
resolve()
})
})
}
protected async _stop(): Promise<void> {
return new Promise((resolve, reject) => {
this.server.close((err) => (err ? reject(err) : resolve()))
delete this.server
})
}
}
function filterByQuery(obj: {}, url: string): {} | null {
let match = url.match(/filter=([^&]*)/)
if (!match || !match[1]) return null
const keys = match[1].split(',')
return pick(obj, keys)
}
function pick(obj: {}, keys: Array<string>): {} {
return keys.reduce((out, key) => {
out[key] = obj[key]
return out
}, {})
}