@jesseditson/dnsimple
Version:
A Node.JS client for the DNSimple API.
273 lines (272 loc) • 10.8 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
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());
});
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DNSimple = exports.ServerError = exports.ClientError = exports.TooManyRequestsError = exports.MethodNotAllowedError = exports.NotFoundError = exports.AuthenticationError = exports.RequestError = exports.TimeoutError = exports.toQueryString = void 0;
const pkg = require("../package.json");
const accounts_1 = require("./accounts");
const billing_1 = require("./billing");
const certificates_1 = require("./certificates");
const contacts_1 = require("./contacts");
const domains_1 = require("./domains");
const identity_1 = require("./identity");
const oauth_1 = require("./oauth");
const registrar_1 = require("./registrar");
const services_1 = require("./services");
const templates_1 = require("./templates");
const tlds_1 = require("./tlds");
const vanity_name_servers_1 = require("./vanity_name_servers");
const webhooks_1 = require("./webhooks");
const zones_1 = require("./zones");
__exportStar(require("./types"), exports);
const toQueryString = (params) => {
const queryParams = [];
for (const [name, value] of Object.entries(params)) {
if (value == null || value === false) {
continue;
}
let queryString = encodeURIComponent(name);
if (value !== true) {
queryString += "=" + encodeURIComponent(value.toString());
}
queryParams.push(queryString);
}
return queryParams.join("&");
};
exports.toQueryString = toQueryString;
const versionedPath = (path, params) => {
let versionedPath = `/v2${path}`;
const queryString = (0, exports.toQueryString)(params);
if (queryString) {
versionedPath = `${versionedPath}?${queryString}`;
}
return versionedPath;
};
class TimeoutError extends Error {
}
exports.TimeoutError = TimeoutError;
class RequestError extends Error {
constructor(status, description) {
super(description);
this.status = status;
}
}
exports.RequestError = RequestError;
class AuthenticationError extends RequestError {
constructor(data) {
super(401, "Authentication error");
this.data = data;
}
}
exports.AuthenticationError = AuthenticationError;
class NotFoundError extends RequestError {
constructor(data) {
super(404, "Not found");
this.data = data;
}
}
exports.NotFoundError = NotFoundError;
class MethodNotAllowedError extends RequestError {
constructor() {
super(405, "Method not allowed");
}
}
exports.MethodNotAllowedError = MethodNotAllowedError;
class TooManyRequestsError extends RequestError {
constructor() {
super(429, "Too many requests");
}
}
exports.TooManyRequestsError = TooManyRequestsError;
class ClientError extends RequestError {
constructor(status, data) {
super(status, "Bad request");
this.data = data;
}
// This is a standard method across all our clients to get the errors from a failed response.
attributeErrors() {
return this.data.errors;
}
}
exports.ClientError = ClientError;
class ServerError extends RequestError {
constructor(status, data) {
super(status, "Server error");
this.data = data;
}
}
exports.ServerError = ServerError;
// Cloudflare workers will hoist requires when compiling, so we can't use
// require conditionally. Instead, hoist them manually and store the error if we
// have one, so that if we feature detect node and they still fail, we can throw
// the right error.
let NODE_IMPORTS;
let NODE_IMPORT_ERR;
try {
const { Buffer } = require("buffer");
const https = require("https");
NODE_IMPORTS = { Buffer, https };
}
catch (e) {
NODE_IMPORT_ERR = e;
}
const getFetcherForPlatform = () => {
if (
// @ts-ignore detect browser
typeof window == "object" ||
// @ts-ignore detect web worker or cloudflare worker
typeof WorkerGlobalScope !== undefined) {
return (_a) => __awaiter(void 0, void 0, void 0, function* () {
var { url, timeout } = _a, req = __rest(_a, ["url", "timeout"]);
const abortController = new AbortController();
if (timeout) {
setTimeout(() => abortController.abort(), timeout);
}
try {
const res = yield fetch(url, Object.assign(Object.assign({}, req), { signal: abortController.signal }));
const status = res.status;
const body = yield res.text();
return { status, body };
}
catch (err) {
// Don't just check `err.name == "AbortError"`, as that could be any AbortController and aborted for any reason. Only `abortController` signifies tiemout.
if (abortController.signal.aborted) {
throw new TimeoutError();
}
throw err;
}
});
}
if (NODE_IMPORT_ERR) {
throw NODE_IMPORT_ERR;
}
const { Buffer, https } = NODE_IMPORTS;
return ({ url, method, headers, timeout, body }) => new Promise((resolve, reject) => {
const req = https.request(url, {
method,
headers,
timeout,
});
req
.on("response", (res) => {
const chunks = Array();
res
.on("data", (chunk) => chunks.push(chunk))
.on("end", () => resolve({
status: res.statusCode,
body: Buffer.concat(chunks).toString("utf-8"),
}))
.on("error", reject);
})
.on("timeout", () => {
// A Promise can only be fulfilled once, so we don't need to flag this; any further "error" events with `reject` calls will do nothing.
req.destroy();
reject(new TimeoutError());
})
.on("error", reject)
.end(body);
});
};
class DNSimple {
constructor({ accessToken, baseUrl = DNSimple.DEFAULT_BASE_URL, fetcher = getFetcherForPlatform(), timeout = DNSimple.DEFAULT_TIMEOUT, userAgent = "", } = {}) {
this.accounts = new accounts_1.Accounts(this);
this.billing = new billing_1.Billing(this);
this.certificates = new certificates_1.Certificates(this);
this.contacts = new contacts_1.Contacts(this);
this.domains = new domains_1.Domains(this);
this.identity = new identity_1.Identity(this);
this.oauth = new oauth_1.OAuth(this);
this.registrar = new registrar_1.Registrar(this);
this.services = new services_1.Services(this);
this.templates = new templates_1.Templates(this);
this.tlds = new tlds_1.Tlds(this);
this.vanityNameServers = new vanity_name_servers_1.VanityNameServers(this);
this.webhooks = new webhooks_1.Webhooks(this);
this.zones = new zones_1.Zones(this);
this.accessToken = accessToken;
this.baseUrl = baseUrl;
this.fetcher = fetcher;
this.timeout = timeout;
this.userAgent = userAgent;
}
request(method, path, body, params) {
return __awaiter(this, void 0, void 0, function* () {
const timeout = this.timeout;
const headers = {
Authorization: `Bearer ${this.accessToken}`,
Accept: "application/json",
"Content-Type": "application/json",
"User-Agent": `${this.userAgent} ${DNSimple.DEFAULT_USER_AGENT}`.trim(),
};
const { status, body: data } = yield this.fetcher({
url: this.baseUrl + versionedPath(path, params),
method,
headers,
timeout,
body: body == null ? undefined : JSON.stringify(body),
});
if (status === 401) {
throw new AuthenticationError(JSON.parse(data));
}
if (status === 404) {
throw new NotFoundError(JSON.parse(data));
}
if (status === 405) {
throw new MethodNotAllowedError();
}
if (status === 429) {
throw new TooManyRequestsError();
}
if (status >= 400 && status < 500) {
throw new ClientError(status, JSON.parse(data));
}
if (status === 204) {
return {};
}
if (status >= 200 && status < 300) {
return !data ? {} : JSON.parse(data);
}
if (status >= 500) {
throw new ServerError(status, JSON.parse(data));
}
throw new Error(`Unsupported status code: ${status}`);
});
}
}
exports.DNSimple = DNSimple;
DNSimple.VERSION = pkg.version;
DNSimple.DEFAULT_TIMEOUT = 120000;
DNSimple.DEFAULT_BASE_URL = "https://api.dnsimple.com";
DNSimple.DEFAULT_USER_AGENT = `dnsimple-node/${DNSimple.VERSION}`;
;