@portive/client
Version:
Client to connect to and use Portive's cloud services for open source components
101 lines (100 loc) • 4.46 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 { DEFAULT_ORIGIN_URL } from "../upload/constants";
import { resolve } from "resolvable-value";
import axios from "axios";
/**
* Create a `Client` object and return it.
*/
export function createClient(options) {
return new Client(options);
}
/**
* Create a `Client` object that we pass to the API functions.
*
* We enforce the creation of a `Client` object for a few reasons:
*
* 1. It helps us not have to deal with `authTokenable` separately for every
* API function call.
* 2. It makes it easy for any components to support any initialization changes
* by just initializing with `ClienOptions`. For example, if we wanted to
* add a `path` property back in the future, we just have to implement at
* one place.
* 3. It's self documenting on what you should probably accept as part of your
* initialization if you want to fully support all the options. For example,
* we can see here that `apiOrigin` is an option to support. If it's
* part of multiple function signature like in `upload`, then it may not
* be so easy to remember to pass all the values through at each function
* invocation location.
*/
export class Client {
constructor({ apiKey, authToken, apiOrigin = DEFAULT_ORIGIN_URL, }) {
if (apiKey == null && authToken == null) {
throw new Error(`apiKey or authToken must be defined but neither are defined`);
}
if (apiOrigin.endsWith("/"))
throw new Error("apiOrigin should not end with a '/'");
if (!apiOrigin.startsWith("http"))
throw new Error(`Expected apiOrigin to start with http`);
// this.authTokenable = authToken
this.unresolvedApiKey = apiKey;
this.unresolvedAuthToken = authToken;
this.apiOrigin = apiOrigin;
}
/**
* Posts at the given path with the `apiKey` or `authToken`.
*/
post(path, data) {
return __awaiter(this, void 0, void 0, function* () {
if (!path.startsWith("/"))
throw new Error(`Expected path to start with "/" but is ${JSON.stringify(path)}`);
const url = `${this.apiOrigin}${path}`;
const post = {
data,
};
const authToken = yield this.getAuthToken();
const apiKey = yield this.getApiKey();
if (typeof authToken === "string" && typeof apiKey === "string") {
throw new Error(`Expected one of 'authToken' or 'apiKey' to be defined but both are defined which is ambiguous`);
}
else if (typeof authToken === "string") {
post.authToken = authToken;
}
else if (typeof apiKey === "string") {
post.apiKey = apiKey;
}
else {
throw new Error(`Expected either 'authToken' or 'apiKey' to be defined but neither are defined`);
}
const axiosResponse = yield axios.post(url, post);
return axiosResponse.data;
});
}
/**
* Gets the apiKey for the client. If it is a function, it gets the return
* value of the function. If that returns a promise, it awaits it.
*/
getApiKey() {
return __awaiter(this, void 0, void 0, function* () {
return this.unresolvedApiKey ? resolve(this.unresolvedApiKey) : undefined;
});
}
/**
* Gets the authToken for the client. If it is a function, it gets the return
* value of the function. If that returns a promise, it awaits it.
*/
getAuthToken() {
return __awaiter(this, void 0, void 0, function* () {
return this.unresolvedAuthToken
? resolve(this.unresolvedAuthToken)
: undefined;
});
}
}