Giter Club home page Giter Club logo

dnsimple-node's Introduction

DNSimple Node.js Client

A Node.js client for the DNSimple API v2 with TypeScript definitions.

Build Status js-semistandard-style npm version npm downloads

Requirements

The dnsimple-node package requires Node.js 18 or higher.

You must also have an activated DNSimple account to access the DNSimple API.

Installation

You can install this package directly from the GitHub repo with npm install dnsimple/dnsimple-node.

Alternatively, install the latest stable version from NPM with npm install dnsimple.

Usage

This library is a Node.js client you can use to interact with the DNSimple API v2. TypeScript definitions are provided for all API method parameters and responses.

Note that in all examples below, the accessToken must be an OAuth token as described in the DNSimple API Access Token documentation.

All client methods that call out to the DNSimple API are async and will return a Promise. The examples below demonstrate basic usage.

const { DNSimple } = require("dnsimple");
// Or use this if you're using TypeScript:
// import { DNSimple } from "dnsimple";

const client = new DNSimple({
  accessToken: process.env.TOKEN,
});

// Fetch your details
const response = await client.identity.whoami();
// All responses have a `data` property if there's response data.
const accountId = response.data.account.id;

// List your domains
const { data: domains1 } = await client.domains.listDomains(accountId);
const { data: domains3 } = await client.domains.listDomains(accountId, { page: 3 });

// Create a domain
const { data: createdDomain } = await client.domains.createDomain(accountId, { name: "example.com" });

// Get a domain
const { data: domain } = await client.domains.getDomain(accountId, "example.com");

To be run like this:

TOKEN=[TOKEN VALUE GOES HERE] node test.js

Take a look at https://github.com/dnsimple/hello-domains-node for an example app that authorizes via OAuth and displays your domain list.

Pagination

There are helper submethods available on API methods that are paginated to assist with fetching items across all pages.

For an API that returns a paginate property, you can use either the iterateAll or collectAll submethods:

  • iterateAll: return an asynchronous iterator of items that are returned from the API. When the last item on a page is iterated, the next page will be fetched. This continues until there are no more pages.

  • collectAll: fetch all pages and collect all the items in order into an array.

Examples:

// iterateAll
for await (const certificate of client.certificates.listCertificates.iterateAll(1010, "bingo.pizza")) {
  console.log(certificate);
}
// collectAll
const certificates: Array<Certificate> = await client.certificates.listCertificates.collectAll(1010, "bingo.pizza");
console.log(certificates.length);

Sandbox Environment

We highly recommend testing against our sandbox environment before using our production environment. This will allow you to avoid real purchases, live charges on your credit card, and reduce the chance of your running up against rate limits.

The client supports both the production and sandbox environment. To switch to sandbox pass the sandbox API host using the baseUrl property when you construct the client:

const { DNSimple } = require("dnsimple");
const client = new DNSimple({
  baseUrl: "https://api.sandbox.dnsimple.com",
  accessToken: process.env.TOKEN,
});

You will need to ensure that you are using an access token created in the sandbox environment. Production tokens will not work in the sandbox environment.

Setting a custom User-Agent header

You customize the User-Agent header for the calls made to the DNSimple API:

const { DNSimple } = require("dnsimple");
const client = new DNSimple({
  userAgent: "my-app",
  accessToken: process.env.TOKEN,
});

The value you provide will be appended to the default User-Agent the client uses. For example, if you use my-app, the final header value will be dnsimple-node/x.x.x my-app (note that it will vary depending on the client version).

License

Copyright © 2016–2023 DNSimple Corporation. This is Free Software distributed under the MIT license.

dnsimple-node's People

Contributors

aeden avatar ags4no avatar dallasread avatar dependabot-preview[bot] avatar dependabot[bot] avatar doowb avatar duduribeiro avatar dxtimer avatar ecomba avatar ggalmazor avatar jacegu avatar jodosha avatar jonchurch avatar nestorsalceda avatar olemchls avatar san983 avatar sbastn avatar sigv avatar weppos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dnsimple-node's Issues

Requests are unauthenticated

Following example in docs does not work (requests do not authenticate). Looks like the code is setting the Bearer header, but current docs say to set X-DNSimple-Token. Seems like a pretty big bug, so side question- is this repo currently used / maintained?

Show the response error message on failure

        if (res.statusCode == 400) {
          reject.call(this, {description: 'Bad request'});
        } else if (res.statusCode == 401) {
          reject.call(this, {description: 'Authentication error'});
        } else if (res.statusCode == 404) {
          reject.call(this, {description: 'Not found'});
        } else if (res.statusCode == 405) {
          reject.call(this, {description: 'Method not allowed'});
        } else if (res.statusCode == 429) {
          reject.call(this, {description: 'Too many requests'});
        } else if (res.statusCode == 204) {
          resolve.call(this, {});
        } else if (res.statusCode >= 200 && res.statusCode < 300) {

On failure, we currently set a generic error message. However, 4xx error code contains a payload that explains the reason of the failure.

We should parse the JSON content and extract the message.
See https://github.com/dnsimple/dnsimple-ruby/blob/master/lib/dnsimple/client.rb#L127-L140 https://github.com/dnsimple/dnsimple-go/blob/master/dnsimple/dnsimple.go#L298-L312

.d.ts support

Hey any plans for adding index.d.ts for typescript users?

client.zones.updateZoneRecord throws error for URI unsafe DNS record content

I'm currently using this client to automatically register & update DNS records with MailGun records automatically -

I've been very successful at creating records using the createZoneRecord function but when I've duplicated the code for updateZoneRecord I am getting this error

DNSimple updateSubdomain Error: TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters

I've confirmed that creating new domains with DNS records containing URI unsafe characters such as "/" which is the most prevalent works as expected but createZoneRecord for some reason does not

This is fairly problematic for RSA keys generated as _domainkey records (for DKIM)

Do I have to URI encode the values inside the DNS record "content" properties? If so, why is it necessary to do this for updateZoneRecord but not createZoneRecord (my guess is that this is potentially a bug, but I'm not sure)

Can create one zone record, then subsequent ones fail

I am having a problem using this library to create an A record and a TXT record. I have tried many combos of the code I am providing, but the all produce the same outcome. Basically, one zone record gets create, but the second record gets 'Authentication failed' message. Because the first record gets create and is successful, I assume it is not a token problem? I am scratching my head what could be happening. Here is the code

exports.txtRecord = (name, location, optional) => {
  return {
    name: name,
    type: 'TXT',
    content: `l=${location}`,
    ttl: 600,
    priority: 10,
  }
}

exports.aRecord = (name, ip) => {
  return {
    name: name,
    type: 'A',
    content: `${ip}`,
    ttl: 600,
    priority: 10,
  }
}

exports.create = (config, services, name, location, optional, done) => {
  let txtRecord = exports.txtRecord(name, location, optional)
  let aRecord = exports.aRecord(name, config.FLAPTO_RESOLVER)

  exports.createRecord(config, services, aRecord, (err, aResult) => {
    console.log(err, aRecord, aResult)
    if (err) return done(err)

    exports.createRecord(name, services, txtRecord, (err, txtResult) => {
      console.log(err, txtRecord, txtResult)
      if (err) return done(err)
      return done(null, {aResult, txtResult})
    })
  })
}

exports.createRecord = (config, services, record, done) => {
  services.client.identity.whoami().then(function(response) {
    return services.client.zones.createZoneRecord(config.account, config.rootDomain, record)
  }).then(function(response) {
    console.log(response);
    done(null, response.data)
  }, function(error) {
    console.log(error);
    done(error)
  });
}

The console output I get is

null { name: 'cjtnfgcqz0000ikky9c2e455d.anon',
  type: 'A',
  content: '50.65.72.243',
  ttl: 600,
  priority: 10 } { id: 15507248,
  zone_id: 'flap.to',
  parent_id: null,
  name: 'cjtnfgcqz0000ikky9c2e455d.anon',
  content: '50.65.72.243',
  ttl: 600,
  priority: null,
  type: 'A',
  regions: [ 'global' ],
  system_record: false,
  created_at: '2019-03-24T21:21:32Z',
  updated_at: '2019-03-24T21:21:32Z' }
{ message: 'Authentication failed',
  description: 'Authentication error' }
{ message: 'Authentication failed',
  description: 'Authentication error' } { name: 'cjtnfgcqz0000ikky9c2e455d.anon',
  type: 'TXT',
  content: 'l=53.51933096,-113.31845597',
  ttl: 600,
  priority: 10 } undefined

So I can see the A record gets created with success, but the TXT record does not. If I swap the order the TXT record will get created, but the A record will not.

So there seems to be something I am not understanding about using this client library. I got frustrated and tried using the 'request' library direct, and I got the same behaviour. Would I be able to get some help on this please?

Authentication fails on sandbox for some reason?

The request,

curl  -H 'Authorization: Bearer <token>' \
      -H 'Accept: application/json' \
      -X GET \
      https://api.dnsimple.com/v2/1010/registrar/domains/example.com/check

JS

const { q } = req.query;
return client.registrar.checkDomain(process.env.DNSIMPLE_ACCOUNT_ID, q);

Returning message

Error: {"message":"Authentication failed","description":"Authentication error"}

The response does not provide enough information.

  • Is it because I'm on free trial?

I cannot use the api. blocked from the authorization.

@aeden


Edit - seems like it fails on https://api.sandbox.dnsimple.com, but works on https://api.dnsimple.com.

This seams like an internal issue. Is the docs outdated or is this a temporal issue?

(Tested with the same code, only altering the baseurl.)

Default Node.js HTTP Timeout changes in v13

Hey there! Wanted to file an issue as a heads up that in Node.js v13 there has been a change that alters the default timeout option.

It has been changed from 2 minutes to 0 (which for the HTTP module itself means there will not be a timeout by default).

Your code is using that default timeout, and so when running under Node.js v13 the value will be 0 instead of 120000:

Dnsimple.DEFAULT_TIMEOUT = require('http').createServer().timeout;

I opened a PR to hardcode the value to what it is under all previous Node.js versions (the value has not previously changed since it's introduction in Node.js v0.9.12)

Consistent User-Agent header

The Node API client doesn't handle the User-Agent header the same way other clients do. In the Node client you can fully override the header where in the other clients it's a composition of the custom User-Agent and the default User-Agent.

See the affected code here.

Send Content-Type header

All non-GET requests must send the header:

Content-Type: application/json

In the future the API will reject requests that don't send a proper Content-Type header.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.