eightsleep
Version:
eightsleep api client
177 lines • 7.44 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import ApiClient, { setFetch, } from 'simple-api-client';
import validateOauth from './validateOauth';
import validateSession from './validateSession';
import BaseError from 'baseerr';
import { EightSleepAppApi } from './EightSleepAppApi';
import fetch from 'cross-fetch';
import memoizeConcurrent from 'memoize-concurrent';
import stringify from 'fast-safe-stringify';
import validateDevice from './validateDevice';
import validateUser from './validateUser';
export { Sides } from './EightSleepAppApi';
export { NetworkError, StatusCodeError, InvalidResponseError, } from 'simple-api-client';
setFetch(fetch);
const defaultInit = {
headers: {
'user-agent': 'Eight%20Sleep/1000018 CFNetwork/1237 Darwin/20.4.0',
'accept-language': 'en-us',
'accept-encoding': 'gzip, deflate, br',
},
backoff: {
statusCodes: /^5..$/,
timeouts: [100, 200],
},
throttle: {
statusCodes: [429],
timeout: 60 * 1000,
},
};
export default class EightSleepClientApi extends ApiClient {
constructor({ email, password, oauthClient, oauthSession, session, }) {
super('https://client-api.8slp.net/v1', (path, init) => __awaiter(this, void 0, void 0, function* () {
var _a;
// @ts-ignore
const session = ((_a = init === null || init === void 0 ? void 0 : init.json) === null || _a === void 0 ? void 0 : _a.email) == null ? yield this.login() : null;
const headers = Object.assign(Object.assign({}, defaultInit.headers), init === null || init === void 0 ? void 0 : init.headers);
if (session) {
Object.assign(headers, {
'user-id': session.userId,
'session-token': session.token,
});
}
return Object.assign(Object.assign(Object.assign({}, init), defaultInit), { headers });
}));
this.login = memoizeConcurrent(() => __awaiter(this, void 0, void 0, function* () {
if (this.session != null)
return yield this.refreshSession();
const { email, password } = this.auth;
const json = yield this.post('login', 200, {
json: {
email,
password,
},
});
this.session = validateSession(json.session);
return this.session;
}), {
cacheKey: () => 'all',
});
this.oauth = memoizeConcurrent(() => __awaiter(this, void 0, void 0, function* () {
if (this.oauthClient == null) {
throw new BaseError('missing oauth client info');
}
if (this.oauthSession != null)
return yield this.refreshOauth();
const json = yield this.post('users/oauth-token', {
json: {
client_id: this.oauthClient.id,
client_secret: this.oauthClient.secret,
},
});
this.oauthSession = validateOauth(json);
return this.oauthSession;
}));
this.getUser = memoizeConcurrent((id, query) => __awaiter(this, void 0, void 0, function* () {
const json = yield this.get(`users/${id}`, 200, {
query,
});
// @ts-ignore
if (query === null || query === void 0 ? void 0 : query.filter)
return json.result;
return validateUser(json.user);
}), {
cacheKey: ([id, query]) => `${id}:${stringify(query !== null && query !== void 0 ? query : {})}`,
});
this.getDevice = memoizeConcurrent((id, query) => __awaiter(this, void 0, void 0, function* () {
const json = yield this.get(`devices/${id}`, 200, {
query,
});
// @ts-ignore
if (query === null || query === void 0 ? void 0 : query.filter)
return json.result;
return validateDevice(json.result);
}), {
cacheKey: ([id, query]) => `${id}:${stringify(query !== null && query !== void 0 ? query : {})}`,
});
this.auth = { email, password };
this.oauthClient = oauthClient;
if (oauthClient) {
this.appApiClient = new EightSleepAppApi({
clientApi: this,
defaultInit,
});
}
this.oauthSession = oauthSession;
this.session = session;
}
toJSON() {
return Object.assign(Object.assign({}, this.auth), { oauthClient: this.oauthClient, oauthSession: this.oauthSession, session: this.session });
}
refreshSession() {
return __awaiter(this, void 0, void 0, function* () {
if (this.auth == null || this.session == null) {
// no auth or session
throw new BaseError('unauthorized', {
login: this.auth,
session: this.session,
});
}
if (this.session.expirationDate.valueOf() < Date.now() - 100) {
// session is expired, login again
delete this.session;
return yield this.login();
}
return this.session;
});
}
getAppApiClient() {
if (!this.appApiClient) {
throw new BaseError('appApiClient is missing (client should be instantiated with oauthClient)');
}
return this.appApiClient;
}
refreshOauth() {
return __awaiter(this, void 0, void 0, function* () {
if (this.oauthClient == null) {
throw new BaseError('missing oauth client info');
}
if (this.oauthSession == null) {
// no oauth session to refresh
throw new BaseError('unauthorized');
}
if (this.oauthSession.expiresIn.valueOf() < Date.now() - 100) {
// oauth session is expired, login again
delete this.oauthSession;
return yield this.oauth();
}
return this.oauthSession;
});
}
getMe(query) {
return __awaiter(this, void 0, void 0, function* () {
return this.getUser('me', query);
});
}
updateMe(json, query) {
return __awaiter(this, void 0, void 0, function* () {
const resJSON = yield this.put('users/me', 200, {
json,
query,
});
// @ts-ignore
if (query === null || query === void 0 ? void 0 : query.filter)
return resJSON.result;
return validateUser(resJSON.user);
});
}
}
//# sourceMappingURL=index.js.map