porkbun-js
Version:
Porkbun API wrapper for Node.js
404 lines (397 loc) • 12.3 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
PorkbunAPI: () => PorkbunAPI
});
module.exports = __toCommonJS(src_exports);
// src/lib/client.ts
var import_axios = __toESM(require("axios"));
var PorkbunError = class extends Error {
/**
* @param {string} message - Error message
* @param {number} [status] - HTTP status code
* @param {string} [code] - Error code
*/
constructor(message, status, code) {
super(message);
this.status = status;
this.code = code;
this.name = "PorkbunError";
}
};
var PorkbunClient = class {
/**
* Creates a new PorkbunClient instance
* @param {PorkbunConfig} config - API configuration
*/
constructor(config) {
this.config = config;
this.client = import_axios.default.create({
baseURL: config.baseURL || "https://api.porkbun.com/api/json/v3",
headers: {
"Content-Type": "application/json"
}
});
this.setupInterceptors();
}
/** Axios instance for making HTTP requests */
client;
/**
* Returns the authentication payload for API requests
* @returns {Object} Authentication payload
* @protected
*/
getAuthPayload() {
return {
apikey: this.config.apiKey,
secretapikey: this.config.secretApiKey
};
}
/**
* Sets up response interceptors for error handling
* @private
*/
setupInterceptors() {
this.client.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 403) {
throw new PorkbunError(
"Authentication failed. Check your API keys or 2FA requirements.",
403
);
}
const message = error.response?.data?.message || error.message;
throw new PorkbunError(
`API Error: ${message}`,
error.response?.status
);
}
);
}
/**
* Validates TTL value
* @param {number} [ttl] - Time to live in seconds
* @throws {PorkbunError} If TTL is less than 600 seconds
* @protected
*/
validateTTL(ttl) {
if (ttl && ttl < 600) {
throw new PorkbunError("TTL must be at least 600 seconds");
}
}
/**
* Makes an authenticated POST request
* @template T - Expected response type
* @param {string} endpoint - API endpoint
* @param {Record<string, any>} [data] - Request payload
* @returns {Promise<T>} API response
* @protected
*/
async post(endpoint, data = {}) {
const response = await this.client.post(endpoint, {
...this.getAuthPayload(),
...data
});
return response.data;
}
};
// src/modules/domain.ts
var DomainModule = class extends PorkbunClient {
/**
* Lists all domains in your account
* @param {DomainListOptions} [options={}] - Optional parameters
* @param {number} [options.start] - Starting index for pagination
* @param {boolean} [options.includeLabels] - Include domain labels in response
* @returns {Promise<DomainListResponse>} List of domains
*
* @example
* ```typescript
* // List all domains
* const domains = await api.domain.listAll();
*
* // List domains with pagination and labels
* const domainsWithLabels = await api.domain.listAll({
* start: 10,
* includeLabels: true
* });
* ```
*/
async listAll(options = {}) {
return this.post("/domain/listAll", {
start: options.start?.toString() || "0",
includeLabels: options.includeLabels ? "yes" : "no"
});
}
/**
* Gets nameservers for a domain
* @param {string} domain - The domain name
* @returns {Promise<NameServersResponse>} Current nameservers
*
* @example
* ```typescript
* const nameservers = await api.domain.getNameServers('example.com');
* ```
*/
async getNameServers(domain) {
return this.post(`/domain/getNs/${domain}`);
}
/**
* Updates nameservers for a domain
* @param {string} domain - The domain name
* @param {string[]} nameservers - Array of nameserver hostnames
* @returns {Promise<APIResponse>} Update operation response
*
* @example
* ```typescript
* await api.domain.updateNameServers('example.com', [
* 'ns1.provider.com',
* 'ns2.provider.com'
* ]);
* ```
*/
async updateNameServers(domain, nameservers) {
return this.post(`/domain/updateNs/${domain}`, { ns: nameservers });
}
/**
* Adds URL forwarding for a domain
* @param {string} domain - The domain name
* @param {URLForwardingOptions} options - Forwarding configuration
* @param {('redirect'|'permanent'|'masked')} options.type - Type of forwarding
* @param {string} options.destination - Target URL
* @returns {Promise<APIResponse>} Creation response
*
* @example
* ```typescript
* await api.domain.addUrlForward('example.com', {
* type: 'redirect',
* destination: 'https://target.com'
* });
* ```
*/
async addUrlForward(domain, options) {
return this.post(`/domain/addUrlForward/${domain}`, options);
}
/**
* Gets URL forwarding settings for a domain
* @param {string} domain - The domain name
* @returns {Promise<URLForwardingResponse>} Current forwarding rules
*
* @example
* ```typescript
* const forwards = await api.domain.getUrlForwarding('example.com');
* ```
*/
async getUrlForwarding(domain) {
return this.post(`/domain/getUrlForwarding/${domain}`);
}
/**
* Deletes a URL forwarding rule
* @param {string} domain - The domain name
* @param {string} id - Forwarding rule ID
* @returns {Promise<APIResponse>} Delete operation response
*
* @example
* ```typescript
* await api.domain.deleteUrlForward('example.com', 'forward123');
* ```
*/
async deleteUrlForward(domain, id) {
return this.post(`/domain/deleteUrlForward/${domain}/${id}`);
}
/**
* Tests API connectivity
* @returns {Promise<APIResponse>} Ping response with status
*
* @example
* ```typescript
* await api.domain.ping();
* ```
*/
async ping() {
return this.post("/ping");
}
};
// src/modules/dns.ts
var DNSModule = class extends PorkbunClient {
/**
* Creates a new DNS record
* @param {string} domain - The domain name
* @param {DNSCreateOptions} options - DNS record configuration
* @param {DNSRecordType} options.type - Record type (A, AAAA, MX, etc.)
* @param {string} options.name - Subdomain or @ for root
* @param {string} options.content - Record value
* @param {number} [options.ttl] - Time to live in seconds
* @returns {Promise<DNSCreateResponse>} Creation response with record ID
*
* @example
* ```typescript
* await api.dns.create('example.com', {
* type: 'A',
* name: 'www',
* content: '192.0.2.1',
* ttl: 600
* });
* ```
*/
async create(domain, options) {
return this.post(`/dns/create/${domain}`, options);
}
/**
* Edits an existing DNS record
* @param {string} domain - The domain name
* @param {string} id - Record ID to edit
* @param {DNSEditOptions} options - Updated record configuration
* @returns {Promise<APIResponse>} Edit operation response
*
* @example
* ```typescript
* await api.dns.edit('example.com', 'record123', {
* content: '192.0.2.2'
* });
* ```
*/
async edit(domain, id, options) {
return this.post(`/dns/edit/${domain}/${id}`, options);
}
/**
* Edits DNS records matching name and type
* @param {string} domain - The domain name
* @param {DNSRecordType} type - Record type to edit
* @param {string} subdomain - Subdomain or @ for root
* @param {DNSEditOptions} options - Updated record configuration
* @returns {Promise<APIResponse>} Edit operation response
*
* @example
* ```typescript
* await api.dns.editByNameType('example.com', 'A', 'www', {
* content: '192.0.2.2'
* });
* ```
*/
async editByNameType(domain, type, subdomain, options) {
return this.post(`/dns/editByNameType/${domain}/${type}/${subdomain}`, options);
}
/**
* Deletes a DNS record
* @param {string} domain - The domain name
* @param {string} id - Record ID to delete
* @returns {Promise<APIResponse>} Delete operation response
*
* @example
* ```typescript
* await api.dns.delete('example.com', 'record123');
* ```
*/
async delete(domain, id) {
return this.post(`/dns/delete/${domain}/${id}`);
}
/**
* Deletes DNS records matching name and type
* @param {string} domain - The domain name
* @param {DNSRecordType} type - Record type to delete
* @param {string} subdomain - Subdomain or @ for root
* @returns {Promise<APIResponse>} Delete operation response
*
* @example
* ```typescript
* await api.dns.deleteByNameType('example.com', 'A', 'www');
* ```
*/
async deleteByNameType(domain, type, subdomain) {
return this.post(`/dns/deleteByNameType/${domain}/${type}/${subdomain}`);
}
/**
* Retrieves DNS records
* @param {string} domain - The domain name
* @param {string} [id] - Optional record ID for specific record
* @returns {Promise<DNSRecordsResponse>} DNS records
*
* @example
* ```typescript
* // Get all records
* const allRecords = await api.dns.retrieve('example.com');
*
* // Get specific record
* const record = await api.dns.retrieve('example.com', 'record123');
* ```
*/
async retrieve(domain, id) {
const endpoint = id ? `/dns/retrieve/${domain}/${id}` : `/dns/retrieve/${domain}`;
return this.post(endpoint);
}
/**
* Retrieves DNS records matching name and type
* @param {string} domain - The domain name
* @param {DNSRecordType} type - Record type to retrieve
* @param {string} subdomain - Subdomain or @ for root
* @returns {Promise<DNSRecordsResponse>} Matching DNS records
*
* @example
* ```typescript
* const records = await api.dns.retrieveByNameType('example.com', 'A', 'www');
* ```
*/
async retrieveByNameType(domain, type, subdomain) {
return this.post(`/dns/retrieveByNameType/${domain}/${type}/${subdomain}`);
}
};
// src/modules/ssl.ts
var SSLModule = class extends PorkbunClient {
/**
* Retrieves SSL certificate bundle for a domain
* @param {string} domain - The domain name
* @returns {Promise<SSLBundleResponse>} SSL certificate bundle
*
* @example
* ```typescript
* const bundle = await api.ssl.retrieve('example.com');
* ```
*/
async retrieve(domain) {
return this.post(`/ssl/retrieve/${domain}`);
}
};
// src/index.ts
var PorkbunAPI = class {
domain;
dns;
ssl;
constructor(config) {
this.domain = new DomainModule(config);
this.dns = new DNSModule(config);
this.ssl = new SSLModule(config);
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
PorkbunAPI
});