A professional, production-ready Node.js wrapper for the TCPShield REST API.
- Full endpoint coverage based on the TCPShield OpenAPI specification
- ESM and CommonJS support
- TypeScript declarations included
- Built-in timeout and error handling
- Custom fetch injection for legacy Node.js versions
npm install @perrygamerpt/tcpshield-api-wrapperimport { TcpShieldClient } from '@perrygamerpt/tcpshield-api-wrapper';
const client = new TcpShieldClient(process.env.TCPSHIELD_API_KEY);
const networks = await client.listNetworks();
console.log(networks);const { TcpShieldClient } = require('@perrygamerpt/tcpshield-api-wrapper');
const client = new TcpShieldClient(process.env.TCPSHIELD_API_KEY);
client.listNetworks().then(console.log).catch(console.error);import { TcpShieldClient, TcpShieldApiError } from '@perrygamerpt/tcpshield-api-wrapper';
const client = new TcpShieldClient(process.env.TCPSHIELD_API_KEY as string);
try {
const response = await client.getUserSummary();
console.log(response);
} catch (error) {
if (error instanceof TcpShieldApiError) {
console.error(error.status, error.data);
}
}The wrapper sends your API key in the X-API-Key header.
const client = new TcpShieldClient('your-api-key');import { TcpShieldClient } from '@perrygamerpt/tcpshield-api-wrapper';
import { fetch as undiciFetch } from 'undici';
const client = new TcpShieldClient(process.env.TCPSHIELD_API_KEY, {
baseUrl: 'https://api.tcpshield.com/',
timeout: 15000,
fetch: undiciFetch,
headers: {
'X-Correlation-ID': 'my-request-id'
}
});import { TcpShieldClient } from '@perrygamerpt/tcpshield-api-wrapper';
process.env.TCPSHIELD_API_KEY = 'your-api-key';
process.env.TCPSHIELD_API_URL = 'https://api.tcpshield.com/';
const client = TcpShieldClient.fromEnv();When the API returns a non-success status code, the wrapper throws TcpShieldApiError.
import { TcpShieldApiError } from '@perrygamerpt/tcpshield-api-wrapper';
try {
await client.getNetwork(999999);
} catch (error) {
if (error instanceof TcpShieldApiError) {
console.error('Status:', error.status);
console.error('Method:', error.method);
console.error('URL:', error.url);
console.error('Payload:', error.data);
}
}const network = await client.createNetwork({ name: 'Production Network' });
await client.createDomain(network.id, {
name: 'mc.example.com',
backend_set_id: 123,
bac: true
});await client.updateNetwork(123, {
connections_per_second_threshold: 75,
client_ban_seconds: 30,
client_allow_seconds: 10,
mitigation_message: 'You are being rate limited. Please try again shortly.'
});const [bounceRate, topDomains, uniqueUsers] = await Promise.all([
client.getAnalyticsBounceRate(123),
client.getAnalyticsTopDomains(123),
client.getAnalyticsUniqueUsers(123)
]);
console.log({ bounceRate, topDomains, uniqueUsers });const createdTunnel = await client.createSentryTunnel({
name: 'EU Edge Tunnel',
endpoint_peer: '198.51.100.42:51820',
bind_port: 25565,
location: 'ANY'
});
const tunnelId = createdTunnel?.id ?? createdTunnel?.data?.id;
if (tunnelId) {
await client.updateSentryTunnel(tunnelId, {
name: 'EU Edge Tunnel - Updated',
endpoint_public_key: 'public_key_here',
endpoint_peer: '198.51.100.42:51820',
bind_port: 25565
});
}All methods return a Promise with the parsed response payload.
listNetworks()createNetwork(data)getNetwork(networkId)updateNetwork(networkId, data)deleteNetwork(networkId)
listDomains(networkId)createDomain(networkId, data)getDomain(networkId, domainId)updateDomain(networkId, domainId, data)deleteDomain(networkId, domainId)preverifyDomain(networkId, data)verifyDomain(networkId, domainId)
listBackendSets(networkId)createBackendSet(networkId, data)getBackendSet(networkId, setId)updateBackendSet(networkId, setId, data)deleteBackendSet(networkId, setId)
listIpFirewallEntries(networkId)createIpFirewallEntry(networkId, data)deleteIpFirewallEntry(networkId, firewallEntryId)listAsnFirewallEntries(networkId)createAsnFirewallEntry(networkId, data)deleteAsnFirewallEntry(networkId, firewallEntryId)listCountryFirewallEntries(networkId)createCountryFirewallEntry(networkId, data)deleteCountryFirewallEntry(networkId, firewallEntryId)
listBedrockTunnels(networkId)createBedrockTunnel(networkId, data)listBedrockTunnelLocations(networkId)getBedrockTunnel(networkId, tunnelId)updateBedrockTunnel(networkId, tunnelId, data)deleteBedrockTunnel(networkId, tunnelId)
getAnalyticsBounceRate(networkId)getAnalyticsTopDomains(networkId)getAnalyticsUniqueUsers(networkId)getAnalyticsRetention(networkId)getAnalyticsMitigatedCount(networkId)getAnalyticsMcVersionBreakdown(networkId)
getUserSummary()updateUserEmail(data)getUserApiKey()regenerateUserApiKey()updateUserGeneralInfo(data)updateUserPassword(data)
listSentryTunnels()createSentryTunnel(data)listSentryTunnelLocations()getSentryTunnelBindPort()getSentryTunnelSetupScript(tunnelId)getSentryTunnelAnalytics(tunnelId)getSentryTunnel(tunnelId)updateSentryTunnel(tunnelId, data)deleteSentryTunnel(tunnelId)
listTunnelFilters()createTunnelFirewallRule(tunnelId, data)listTunnelFirewallRules(tunnelId)getTunnelFirewallFilter(filterId)updateTunnelFirewallFilter(filterId, data)deleteTunnelFirewallFilter(filterId)
Use the generic request method when TCPShield adds a new endpoint before this package is updated.
const raw = await client.request('/networks', { method: 'GET' });- Never hardcode API keys in source code
- Use environment variables or secrets managers
- Rotate API keys regularly
- Restrict key usage to required scopes only
MIT