├── .eslintrc.yml ├── .gitignore ├── .prettierrc.yaml ├── LICENSE ├── README.md ├── index.js ├── lib ├── Client.js ├── Getter.js ├── Resource.js ├── method.js ├── proxy.js └── resources │ ├── ArgoTunnels.js │ ├── DNSRecords.js │ ├── EnterpriseZoneWorkersKV.js │ ├── EnterpriseZoneWorkersKVNamespaces.js │ ├── EnterpriseZoneWorkersRoutes.js │ ├── EnterpriseZoneWorkersScripts.js │ ├── IPs.js │ ├── PageRules.js │ ├── Stream.js │ ├── User.js │ ├── UserTokens.js │ ├── ZoneCustomHostNames.js │ ├── ZoneSettings.js │ ├── ZoneWorkers.js │ ├── ZoneWorkersRoutes.js │ ├── ZoneWorkersScript.js │ └── Zones.js ├── package-lock.json ├── package.json └── test ├── Client.js ├── Resource.js ├── method.js └── proxy.js /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | extends: 2 | - es/2015/server 3 | - plugin:prettier/recommended 4 | - plugin:eslint-comments/recommended 5 | - plugin:node/recommended 6 | - plugin:security/recommended 7 | - plugin:promise/recommended 8 | plugins: 9 | - eslint-comments 10 | - node 11 | - security 12 | - promise 13 | - notice 14 | rules: 15 | prefer-reflect: off 16 | no-underscore-dangle: 17 | - error 18 | - allowAfterThis: true 19 | prefer-rest-params: off 20 | node/exports-style: 21 | - error 22 | - module.exports 23 | notice/notice: 24 | - error 25 | - template: "/*\n * Copyright (C) 2014-present Cloudflare, Inc.\n\n * This software may be modified and distributed under the terms\n * of the MIT license. See the LICENSE file for details.\n */" 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | coverage/ 3 | .nyc_output/ 4 | .travis.yml 5 | -------------------------------------------------------------------------------- /.prettierrc.yaml: -------------------------------------------------------------------------------- 1 | printWidth: 80 2 | tabWidth: 2 3 | useTabs: false 4 | semi: true 5 | singleQuote: true 6 | trailingComma: es5 7 | bracketSpacing: false 8 | parser: babylon -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 Cloudflare, Inc. 2 | Portions of lib/method.js adapted from stripe-node, Copyright (C) 2013 Stripe, Inc. (https://stripe.com) 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cloudflare Node.js bindings 2 | 3 | > [!WARNING] 4 | > 5 | > `v3.x` of this library is a ground-up rewrite of the SDK, using code generation from our OpenAPI spec. 6 | > 7 | > This package should be in a usable state for many projects, but expect frequent minor breaking 8 | > changes as we rename methods and types until GA. If this isn't suitable for you project, we recommend 9 | > pinning to the `2.x` releases for now. 10 | > 11 | > We will be archiving the current repository (`cloudflare/node-cloudflare`) in favour 12 | > of the newer repository ([`cloudflare/cloudflare-typescript`](https://github.com/cloudflare/cloudflare-typescript)) to ensure consistency with our other 13 | > libraries. The repository will still be accessible if you wish to use it, however, you will not be 14 | > able to raise new issues or propose changes. Those should instead be directed to the newer repository. 15 | 16 | --- 17 | 18 | [![Stability Stable][badge-stability]][badge-stability-url] 19 | [![NPM version][badge-npm]][badge-npm-url] 20 | [![Travis CI][badge-travis]][badge-travis-url] 21 | [![Coveralls][badge-coveralls]][badge-coveralls-url] 22 | [![NPM downloads][badge-npm-downloads]][badge-npm-downloads] 23 | [![Libraries.io Dependencies][badge-libraries]][badge-libraries-url] 24 | 25 | [Cloudflare v4 API][cf-api] bindings for Node.js, providing a sourdough 26 | "BREAD" (Browse, Read, Edit, Add, and Delete) interface. 27 | 28 | [cf-api]: https://api.cloudflare.com/ 29 | [badge-stability]: https://img.shields.io/badge/stability-stable-green.svg?style=flat-square 30 | [badge-stability-url]: https://github.com/dominictarr/stability/blob/4d649a5b3af8444720929a50254dfbb071ce27e7/levels.json#L8-L9 31 | [badge-npm]: https://img.shields.io/npm/v/cloudflare.svg?style=flat-square 32 | [badge-npm-downloads]: https://img.shields.io/npm/dm/cloudflare.svg?style=flat-square 33 | [badge-npm-url]: https://www.npmjs.com/package/cloudflare 34 | [badge-travis]: https://img.shields.io/travis/cloudflare/node-cloudflare/master.svg?style=flat-square 35 | [badge-travis-url]: https://travis-ci.org/cloudflare/node-cloudflare 36 | [badge-coveralls]: https://img.shields.io/coveralls/github/cloudflare/node-cloudflare/master.svg?style=flat-square 37 | [badge-coveralls-url]: https://coveralls.io/github/cloudflare/node-cloudflare 38 | [badge-libraries]: https://img.shields.io/librariesio/github/cloudflare/node-cloudflare.svg?style=flat-square 39 | [badge-libraries-url]: https://libraries.io/npm/cloudflare 40 | 41 | With these bindings, you'll get the following features: 42 | 43 | * A Promise-based API. With modern versions of Node.js, this can be 44 | leveraged for async/await and generator support. 45 | * Automatic handling of Gzip/Deflate compression. 46 | 47 | Node.js v4 and greater are supported. 48 | 49 | ## Configuration 50 | 51 | ### API Keys 52 | 53 | Set your account email address and API key. The API key can be found on 54 | the [My Profile -> API Tokens][api-tokens] page in the Cloudflare dashboard. 55 | 56 | [api-tokens]: https://dash.cloudflare.com/profile/api-tokens 57 | 58 | ```javascript 59 | var cf = require('cloudflare')({ 60 | email: 'you@example.com', 61 | key: 'your Cloudflare API key' 62 | }); 63 | ``` 64 | 65 | ### API Tokens (BETA) 66 | 67 | Create your token on the [My Profile -> API Tokens][api-tokens] page in the Cloudflare dashboard. 68 | 69 | [api-tokens]: https://dash.cloudflare.com/profile/api-tokens 70 | 71 | ```javascript 72 | var cf = require('cloudflare')({ 73 | token: 'your Cloudflare API token' 74 | }); 75 | ``` 76 | 77 | ## API Overview 78 | 79 | Every resource is accessed via your `cf` instance: 80 | 81 | ```javascript 82 | // cf.{ RESOURCE_NAME }.{ METHOD_NAME } 83 | ``` 84 | 85 | Every resource method returns a promise, which can be chained or used 86 | with async/await. 87 | 88 | ```javascript 89 | cf.zones.read('023e105f4ecef8ad9ca31a8372d0c353').then(function (resp) { 90 | return resp.result.status; 91 | }); 92 | 93 | 94 | // where supported 95 | async function getZoneStatus(id) { 96 | var resp = await cf.zones.read('023e105f4ecef8ad9ca31a8372d0c353'); 97 | return resp.result.status; 98 | } 99 | ``` 100 | 101 | ### Documentation 102 | 103 | * [Generated JSDoc](https://cloudflare.github.io/node-cloudflare) 104 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Client = require('./lib/Client'); 14 | const proxy = require('./lib/proxy'); 15 | 16 | /* eslint-disable global-require */ 17 | const resources = { 18 | argoTunnels: require('./lib/resources/ArgoTunnels'), 19 | dnsRecords: require('./lib/resources/DNSRecords'), 20 | enterpriseZoneWorkersScripts: require('./lib/resources/EnterpriseZoneWorkersScripts'), 21 | enterpriseZoneWorkersRoutes: require('./lib/resources/EnterpriseZoneWorkersRoutes'), 22 | enterpriseZoneWorkersKVNamespaces: require('./lib/resources/EnterpriseZoneWorkersKVNamespaces'), 23 | enterpriseZoneWorkersKV: require('./lib/resources/EnterpriseZoneWorkersKV'), 24 | ips: require('./lib/resources/IPs'), 25 | pageRules: require('./lib/resources/PageRules'), 26 | zones: require('./lib/resources/Zones'), 27 | zoneSettings: require('./lib/resources/ZoneSettings'), 28 | zoneCustomHostNames: require('./lib/resources/ZoneCustomHostNames'), 29 | zoneWorkers: require('./lib/resources/ZoneWorkers'), 30 | zoneWorkersScript: require('./lib/resources/ZoneWorkersScript'), 31 | zoneWorkersRoutes: require('./lib/resources/ZoneWorkersRoutes'), 32 | user: require('./lib/resources/User'), 33 | userTokens: require('./lib/resources/UserTokens'), 34 | stream: require('./lib/resources/Stream'), 35 | }; 36 | /* eslint-enable global-require */ 37 | 38 | /** 39 | * withEnvProxy configures an HTTPS proxy if required to reach the Cloudflare API. 40 | * 41 | * @private 42 | * @param {Object} opts - The current Cloudflare options 43 | */ 44 | const withEnvProxy = function withEnvProxy(opts) { 45 | /* eslint-disable no-process-env */ 46 | const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy; 47 | const noProxy = process.env.NO_PROXY || process.env.no_proxy; 48 | /* eslint-enable no-process-env */ 49 | 50 | if (httpsProxy) { 51 | const agent = proxy.proxyAgent( 52 | httpsProxy, 53 | noProxy, 54 | 'https://api.cloudflare.com' 55 | ); 56 | 57 | if (agent) { 58 | opts.agent = agent; 59 | } 60 | } 61 | }; 62 | 63 | /** 64 | * Constructs and returns a new Cloudflare API client with the specified authentication. 65 | * 66 | * @class Cloudflare 67 | * @param {Object} auth - The API authentication for an account 68 | * @param {string} auth.email - The account email address 69 | * @param {string} auth.key - The account API key 70 | * @param {string} auth.token - The account API token 71 | * 72 | * @property {DNSRecords} dnsRecords - DNS Records instance 73 | * @property {IPs} ips - IPs instance 74 | * @property {PageRules} pageRules - Page Rules instance 75 | * @property {Zones} zones - Zones instance 76 | * @property {ZoneSettings} zoneSettings - Zone Settings instance 77 | * @property {ZoneCustomHostNames} zoneCustomHostNames - Zone Custom Host Names instance 78 | * @property {User} user - User instance 79 | */ 80 | const Cloudflare = auto( 81 | prototypal({ 82 | constructor: function constructor(auth) { 83 | const opts = { 84 | email: auth && auth.email, 85 | key: auth && auth.key, 86 | token: auth && auth.token, 87 | }; 88 | 89 | withEnvProxy(opts); 90 | 91 | const client = new Client(opts); 92 | 93 | Object.defineProperty(this, '_client', { 94 | value: client, 95 | writable: false, 96 | enumerable: false, 97 | configurable: false, 98 | }); 99 | 100 | Object.keys(resources).forEach(function(resource) { 101 | Object.defineProperty(this, resource, { 102 | value: resources[resource](this._client), // eslint-disable-line security/detect-object-injection 103 | writable: true, 104 | enumerable: false, 105 | configurable: true, 106 | }); 107 | }, this); 108 | }, 109 | }) 110 | ); 111 | 112 | module.exports = Cloudflare; 113 | -------------------------------------------------------------------------------- /lib/Client.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const pkg = require('../package.json'); 12 | const Getter = require('./Getter'); 13 | 14 | const USER_AGENT = JSON.stringify({ 15 | bindings_version: pkg.version, // eslint-disable-line camelcase 16 | lang: 'node', 17 | lang_version: process.version, // eslint-disable-line camelcase 18 | platform: process.platform, 19 | arch: process.arch, 20 | publisher: 'cloudflare', 21 | }); 22 | 23 | const isPlainObject = function isPlainObject(x) { 24 | const prototype = Object.getPrototypeOf(x); 25 | const toString = Object.prototype.toString; 26 | 27 | return ( 28 | toString.call(x) === '[object Object]' && 29 | (prototype === null || prototype === Object.getPrototypeOf({})) 30 | ); 31 | }; 32 | 33 | const isUserServiceKey = function isUserServiceKey(x) { 34 | return x && x.substring(0, 5) === 'v1.0-'; 35 | }; 36 | 37 | module.exports = prototypal({ 38 | constructor: function constructor(options) { 39 | this.email = options.email; 40 | this.key = options.key; 41 | this.token = options.token; 42 | this.getter = new Getter(options); 43 | }, 44 | request(requestMethod, requestPath, data, opts) { 45 | const uri = `https://api.cloudflare.com/client/v4/${requestPath}`; 46 | const key = opts.auth.key || this.key; 47 | const token = opts.auth.token || this.token; 48 | const email = opts.auth.email || this.email; 49 | 50 | const options = { 51 | json: opts.json !== false, 52 | timeout: opts.timeout || 1e4, 53 | retries: opts.retries, 54 | method: requestMethod, 55 | headers: { 56 | 'user-agent': `cloudflare/${pkg.version} node/${process.versions.node}`, 57 | 'Content-Type': opts.contentType || 'application/json', 58 | Accept: 'application/json', 59 | 'X-Cloudflare-Client-User-Agent': USER_AGENT, 60 | }, 61 | }; 62 | 63 | if (isUserServiceKey(key)) { 64 | options.headers['X-Auth-User-Service-Key'] = key; 65 | } else if (key) { 66 | options.headers['X-Auth-Key'] = key; 67 | options.headers['X-Auth-Email'] = email; 68 | } else if (token) { 69 | options.headers.Authorization = `Bearer ${token}`; 70 | } 71 | 72 | if (requestMethod === 'GET') { 73 | options.query = data; 74 | } else { 75 | options.body = data; 76 | } 77 | 78 | if ( 79 | options.body && 80 | (isPlainObject(options.body) || Array.isArray(options.body)) 81 | ) { 82 | options.body = JSON.stringify(options.body); 83 | } 84 | 85 | return this.getter.got(uri, options).then(res => res.body); 86 | }, 87 | }); 88 | -------------------------------------------------------------------------------- /lib/Getter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const assign = require('object-assign'); 12 | const got = require('got'); 13 | 14 | module.exports = prototypal({ 15 | constructor: function constructor(options) { 16 | this._agent = options.agent; 17 | }, 18 | got(uri, options) { 19 | options = assign({}, options); 20 | options.agent = this._agent; 21 | 22 | return got(uri, options); 23 | }, 24 | }); 25 | -------------------------------------------------------------------------------- /lib/Resource.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const method = require('./method'); 12 | 13 | const BASIC_METHODS = { 14 | browse: method({ 15 | method: 'GET', 16 | }), 17 | read: method({ 18 | method: 'GET', 19 | path: ':id', 20 | }), 21 | edit: method({ 22 | method: 'PATCH', 23 | path: ':id', 24 | }), 25 | add: method({ 26 | method: 'POST', 27 | }), 28 | del: method({ 29 | method: 'DELETE', 30 | path: ':id', 31 | }), 32 | }; 33 | 34 | /** 35 | * Resource generates basic methods defined on subclasses. It is not intended to 36 | * be constructed directly. 37 | * 38 | * @class Resource 39 | * @private 40 | */ 41 | module.exports = prototypal( 42 | /** @lends Resource.prototype */ 43 | { 44 | constructor: function constructor(client) { 45 | Object.defineProperty(this, '_client', { 46 | value: client, 47 | writable: false, 48 | enumerable: false, 49 | configurable: false, 50 | }); 51 | 52 | if (Array.isArray(this.includeBasic)) { 53 | this.includeBasic.forEach(function(basicMethod) { 54 | Object.defineProperty(this, basicMethod, { 55 | value: BASIC_METHODS[basicMethod], // eslint-disable-line security/detect-object-injection 56 | writable: true, 57 | enumerable: false, 58 | configurable: true, 59 | }); 60 | }, this); 61 | } 62 | }, 63 | /** 64 | * @param {string} methodPath - The path from the {@link method} that should be 65 | * joined with the resource's path. 66 | */ 67 | createFullPath(methodPath) { 68 | return (methodPath && [this.path, methodPath].join('/')) || this.path; 69 | }, 70 | path: '', 71 | hasBrokenPatch: false, 72 | } 73 | ); 74 | -------------------------------------------------------------------------------- /lib/method.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const URLPattern = require('url-pattern'); 11 | 12 | const options = ['key', 'email', 'token']; 13 | 14 | const isPlainObject = function isPlainObject(x) { 15 | const prototype = Object.getPrototypeOf(x); 16 | const toString = Object.prototype.toString; 17 | 18 | return ( 19 | toString.call(x) === '[object Object]' && 20 | (prototype === null || prototype === Object.getPrototypeOf({})) 21 | ); 22 | }; 23 | 24 | const isOptionsHash = function isOptionsHash(obj) { 25 | const hasProp = function(acc, option) { 26 | if (acc) { 27 | return acc; 28 | } 29 | 30 | return Object.prototype.hasOwnProperty.call(obj, option); 31 | }; 32 | 33 | return isPlainObject(obj) && options.reduce(hasProp, false); 34 | }; 35 | 36 | const getDataFromArgs = function getDataFromArgs(args) { 37 | if (args.length > 0) { 38 | if (!isOptionsHash(args[0])) { 39 | return args.shift(); 40 | } 41 | } 42 | 43 | return {}; 44 | }; 45 | 46 | const getOptionsFromArgs = function getOptionsFromArgs(args) { 47 | const opts = { 48 | auth: {}, 49 | headers: {}, 50 | }; 51 | 52 | if (args.length > 0) { 53 | const arg = args[args.length - 1]; 54 | 55 | if (isOptionsHash(arg)) { 56 | const params = args.pop(); 57 | 58 | if (params.key) { 59 | opts.auth.key = params.key; 60 | } 61 | 62 | if (params.email) { 63 | opts.auth.email = params.email; 64 | } 65 | } 66 | } 67 | 68 | return opts; 69 | }; 70 | 71 | const identity = function identity(x) { 72 | return x; 73 | }; 74 | 75 | module.exports = function(spec) { 76 | const requestMethod = (spec.method || 'GET').toUpperCase(); 77 | const encode = spec.encode || identity; 78 | const json = spec.json !== false; 79 | const contentType = spec.contentType || 'application/json'; 80 | 81 | return function() { 82 | const fullPath = this.createFullPath(spec.path); 83 | const urlPattern = new URLPattern(fullPath); 84 | const urlParams = urlPattern.names; 85 | let err; 86 | const args = Array.prototype.slice.call(arguments); 87 | const urlData = {}; 88 | 89 | for (let i = 0, length = urlParams.length; i < length; i++) { 90 | const arg = args[0]; 91 | 92 | const param = urlParams[i]; // eslint-disable-line security/detect-object-injection 93 | 94 | if (!arg) { 95 | /* eslint-disable security/detect-object-injection */ 96 | err = new Error( 97 | `Cloudflare: Argument "${ 98 | urlParams[i] 99 | }" required, but got: ${arg} (on API request to ${requestMethod} ${fullPath})` 100 | ); 101 | /* eslint-enable security/detect-object-injection */ 102 | 103 | return Promise.reject(err); 104 | } 105 | 106 | urlData[param] = args.shift(); // eslint-disable-line security/detect-object-injection 107 | } 108 | 109 | const data = encode(getDataFromArgs(args)); 110 | const opts = getOptionsFromArgs(args); 111 | 112 | opts.json = json; 113 | opts.contentType = contentType; 114 | 115 | if (args.length !== 0) { 116 | err = new Error( 117 | `Cloudflare: Unknown arguments (${args}). Did you mean to pass an options object? (on API request to ${requestMethod} ${fullPath})` 118 | ); 119 | 120 | return Promise.reject(err); 121 | } 122 | 123 | const requestPath = urlPattern.stringify(urlData); 124 | 125 | if (requestMethod !== 'PATCH' || !this.hasBrokenPatch) { 126 | return this._client.request(requestMethod, requestPath, data, opts); 127 | } 128 | 129 | const patched = Object.keys(data); 130 | 131 | const sendPatch = function sendPatch() { 132 | const patch = patched.pop(); 133 | const datum = {}; 134 | 135 | datum[patch] = data[patch]; // eslint-disable-line security/detect-object-injection 136 | 137 | // noinspection JSPotentiallyInvalidUsageOfThis 138 | return this._client 139 | .request(requestMethod, requestPath, datum, opts) 140 | .then(response => { 141 | if (patched.length > 0) { 142 | return sendPatch.call(this); 143 | } 144 | 145 | return response; 146 | }); 147 | }; 148 | 149 | return sendPatch.call(this); 150 | }; 151 | }; 152 | -------------------------------------------------------------------------------- /lib/proxy.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const shouldProxy = require('should-proxy'); 11 | const HttpsProxyAgent = require('https-proxy-agent'); 12 | 13 | /** 14 | * proxyAgent returns an HTTPS agent to use to access the base URL. 15 | * 16 | * @private 17 | * @param {string} httpsProxy - HTTPS Proxy URL 18 | * @param {string} noProxy - URLs that should be excluded from proxying 19 | * @param {string} base - The client base URL 20 | * @returns {https.Agent|null} - The HTTPS agent, if required to access the base URL. 21 | */ 22 | const proxyAgent = function proxyAgent(httpsProxy, noProxy, base) { 23 | if (!httpsProxy) { 24 | return null; 25 | } 26 | noProxy = noProxy || ''; 27 | 28 | const ok = shouldProxy(base, { 29 | no_proxy: noProxy, // eslint-disable-line camelcase 30 | }); 31 | 32 | if (!ok) { 33 | return null; 34 | } 35 | 36 | return new HttpsProxyAgent(httpsProxy); 37 | }; 38 | 39 | module.exports.proxyAgent = proxyAgent; 40 | -------------------------------------------------------------------------------- /lib/resources/ArgoTunnels.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | const method = require('../method'); 15 | 16 | /** 17 | * Argo Tunnels represents the /accounts/:accountId/tunnels API endpoint. 18 | * 19 | * @class ArgoTunnels 20 | * @hideconstructor 21 | * @extends Resource 22 | */ 23 | module.exports = auto( 24 | prototypal({ 25 | extends: Resource, 26 | path: 'accounts/:accountId/tunnels', 27 | 28 | includeBasic: ['browse', 'read', 'add', 'del'], 29 | 30 | /** 31 | * clean removes stale connection resources from an Argo Tunnel 32 | * 33 | * @function clean 34 | * @memberof ArgoTunnels 35 | * @instance 36 | * @async 37 | * @param {string} accountId - The account ID 38 | * @param {string} id - The tunnel ID being modified 39 | * @returns {Promise} The response object. 40 | */ 41 | clean: method({ 42 | method: 'DELETE', 43 | path: ':id/connections', 44 | }), 45 | 46 | /** 47 | * browse allows for listing all Argo Tunnels for an account 48 | * 49 | * @function browse 50 | * @memberof ArgoTunnels 51 | * @instance 52 | * @async 53 | * @param {string} accountId - The account ID 54 | * @returns {Promise} The Argo Tunnels response object. 55 | */ 56 | /** 57 | * read allows for retrieving the specified Argo Tunnel 58 | * 59 | * @function read 60 | * @memberof ArgoTunnels 61 | * @instance 62 | * @async 63 | * @param {string} accountId - The account ID 64 | * @param {string} id - The Argo Tunnel ID 65 | * @returns {Promise} The Argo Tunnel object. 66 | */ 67 | /** 68 | * add allows for creating a new Argo Tunnel for an account. 69 | * 70 | * @function add 71 | * @memberof ArgoTunnels 72 | * @instance 73 | * @async 74 | * @param {string} accountId - The account ID 75 | * @param {Object} tunnel - The new Argo Tunnel object 76 | * @returns {Promise} The created Argo Tunnel object. 77 | */ 78 | /** 79 | * del allows for deleting the specified Tunnel 80 | * 81 | * @function del 82 | * @memberof ArgoTunnels 83 | * @instance 84 | * @async 85 | * @param {string} accountId - The account ID 86 | * @param {string} id - The Argo Tunnel ID 87 | * @returns {Promise} The deleted Argo Tunnel object. 88 | */ 89 | }) 90 | ); 91 | -------------------------------------------------------------------------------- /lib/resources/DNSRecords.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | const method = require('../method'); 15 | 16 | /** 17 | * DNSRecords represents the /zones/:zoneID/dns_records API endpoint. 18 | * 19 | * @class DNSRecords 20 | * @hideconstructor 21 | * @extends Resource 22 | */ 23 | module.exports = auto( 24 | prototypal({ 25 | extends: Resource, 26 | path: 'zones/:zoneId/dns_records', 27 | 28 | includeBasic: ['browse', 'read', 'add', 'del'], 29 | 30 | /** 31 | * edit allows for modification of the specified DNS Record 32 | * 33 | * @function edit 34 | * @memberof DNSRecords 35 | * @instance 36 | * @async 37 | * @param {string} zone_id - The zone ID 38 | * @param {string} id - The DNS record ID being modified 39 | * @param {Object} record - The modified dns record object 40 | * @returns {Promise} The DNS record object. 41 | */ 42 | edit: method({ 43 | method: 'PUT', 44 | path: ':id', 45 | }), 46 | 47 | /** 48 | * export retrieves all of a zone's DNS Records in BIND configuration format. 49 | * 50 | * @function export 51 | * @memberof DNSRecords 52 | * @instance 53 | * @async 54 | * @param {string} zone_id - The zone ID 55 | * @returns {Promise} The DNS browser response object. 56 | */ 57 | export: method({ 58 | method: 'GET', 59 | path: 'export', 60 | json: false, 61 | }), 62 | 63 | /** 64 | * browse allows for listing all DNS Records for a zone 65 | * 66 | * @function browse 67 | * @memberof DNSRecords 68 | * @instance 69 | * @async 70 | * @param {string} zone_id - The zone ID 71 | * @returns {Promise} The DNS browser response object. 72 | */ 73 | /** 74 | * read allows for retrieving the specified DNS Record 75 | * 76 | * @function read 77 | * @memberof DNSRecords 78 | * @instance 79 | * @async 80 | * @param {string} zone_id - The zone ID 81 | * @param {string} id - The DNS record ID 82 | * @returns {Promise} The DNS record object. 83 | */ 84 | /** 85 | * add allows for creating a new DNS record for a zone. 86 | * 87 | * @function add 88 | * @memberof DNSRecords 89 | * @instance 90 | * @async 91 | * @param {string} zone_id - The zone ID 92 | * @param {Object} record - The new DNS record object 93 | * @returns {Promise} The created DNS record object. 94 | */ 95 | /** 96 | * del allows for deleting the specified DNS Record 97 | * 98 | * @function del 99 | * @memberof DNSRecords 100 | * @instance 101 | * @async 102 | * @param {string} zone_id - The zone ID 103 | * @param {string} id - The DNS record ID to delete 104 | * @returns {Promise} The deleted DNS record object. 105 | */ 106 | }) 107 | ); 108 | -------------------------------------------------------------------------------- /lib/resources/EnterpriseZoneWorkersKV.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | const method = require('../method'); 15 | 16 | /** 17 | * EnterpriseZoneWorkersKV represents the accounts/:accountId/storage/kv/namespaces API endpoint. 18 | * 19 | * @class EnterpriseZoneWorkersKV 20 | * @hideconstructor 21 | * @extends Resource 22 | */ 23 | module.exports = auto( 24 | prototypal({ 25 | extends: Resource, 26 | path: 'accounts/:accountId/storage/kv/namespaces/:namespaceId', 27 | 28 | /** 29 | * browse allows for listing all the keys of a namespace 30 | * 31 | * @function browse 32 | * @memberof EnterpriseZoneWorkersKV 33 | * @instance 34 | * @async 35 | * @param {string} account_id - The account ID 36 | * @param {string} namespace_id - The namespace ID 37 | * @returns {Promise} The KV response object. 38 | */ 39 | browse: method({ 40 | method: 'GET', 41 | path: 'keys', 42 | }), 43 | /** 44 | * add allows for creating a key-value pair in a namespace 45 | * 46 | * @function add 47 | * @memberof EnterpriseZoneWorkersKV 48 | * @instance 49 | * @async 50 | * @param {string} account_id - The account ID 51 | * @param {string} namespace_id - The namespace ID 52 | * @param {string} id - The key to store into 53 | * @param {string} value - The value to store 54 | * @returns {Promise} The KV response object 55 | */ 56 | add: method({ 57 | method: 'PUT', 58 | path: 'values/:id', 59 | }), 60 | /** 61 | * read allows for reading the contents of key in a namespace 62 | * 63 | * @function read 64 | * @memberof EnterpriseZoneWorkersKV 65 | * @instance 66 | * @async 67 | * @param {string} account_id - The account ID 68 | * @param {string} namespace_id - The namespace ID 69 | * @param {string} id - The key to read from 70 | * @returns {Promise} The KV response object 71 | */ 72 | read: method({ 73 | method: 'GET', 74 | path: 'values/:id', 75 | json: false, 76 | contentType: 'text/plain', 77 | }), 78 | /** 79 | * del allows for deleting a key and its contents in a namespace 80 | * 81 | * @function del 82 | * @memberof EnterpriseZoneWorkersKV 83 | * @instance 84 | * @async 85 | * @param {string} account_id - The account ID 86 | * @param {string} namespace_id - The namespace ID 87 | * @param {string} id - The key to delete 88 | * @returns {Promise} The KV response object 89 | */ 90 | del: method({ 91 | method: 'DELETE', 92 | path: 'values/:id', 93 | }), 94 | /** 95 | * addMulti allows for creating multiple key-value pairs in a namespace 96 | * 97 | * @function addMulti 98 | * @memberof EnterpriseZoneWorkersKV 99 | * @instance 100 | * @async 101 | * @param {string} account_id - The account ID 102 | * @param {string} namespace_id - The namespace ID 103 | * @param {Array} data - An array containing key-vaue pair Objects to add 104 | * @returns {Promise} The KV response object 105 | */ 106 | addMulti: method({ 107 | method: 'PUT', 108 | path: 'bulk', 109 | }), 110 | /** 111 | * delMulti allows for deleting multiple key-value pairs in a namespace 112 | * 113 | * @function delMulti 114 | * @memberof EnterpriseZoneWorkersKV 115 | * @instance 116 | * @async 117 | * @param {string} account_id - The account ID 118 | * @param {string} namespace_id - The namespace ID 119 | * @param {Array} data - The array with keys to delete 120 | * @returns {Promise} The KV response object 121 | */ 122 | delMulti: method({ 123 | method: 'DELETE', 124 | path: 'bulk', 125 | }), 126 | }) 127 | ); 128 | -------------------------------------------------------------------------------- /lib/resources/EnterpriseZoneWorkersKVNamespaces.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | const method = require('../method'); 15 | 16 | /** 17 | * EnterpriseZoneWorkersKVNamespaces represents the accounts/:accountId/storage/kv/namespaces API endpoint. 18 | * 19 | * @class EnterpriseZoneWorkersKVNamespaces 20 | * @hideconstructor 21 | * @extends Resource 22 | */ 23 | module.exports = auto( 24 | prototypal({ 25 | extends: Resource, 26 | path: 'accounts/:accountId/storage/kv/namespaces', 27 | 28 | includeBasic: ['browse', 'add', 'del'], 29 | 30 | /** 31 | * browse allows for listing all of a zone's workers namespaces 32 | * 33 | * @function browse 34 | * @memberof EnterpriseZoneWorkersKVNamespaces 35 | * @instance 36 | * @async 37 | * @param {string} account_id - The account ID 38 | * @returns {Promise} The namespace response object. 39 | */ 40 | /** 41 | * add allows for creating a workers namespace 42 | * 43 | * @function add 44 | * @memberof EnterpriseZoneWorkersKVNamespaces 45 | * @instance 46 | * @async 47 | * @param {string} account_id - The account ID 48 | * @param {Object} config - The namespace object 49 | * @returns {Promise} The namespace response object. 50 | */ 51 | /** 52 | * del allows for deleting a workers namespace 53 | * 54 | * @function del 55 | * @memberof EnterpriseZoneWorkersKVNamespaces 56 | * @instance 57 | * @async 58 | * @param {string} account_id - The account ID 59 | * @param {string} id - The namespace id 60 | * @returns {Promise} The namespace response object. 61 | */ 62 | /** 63 | * edit allows for renaming a workers namespace 64 | * 65 | * @function edit 66 | * @memberof EnterpriseZoneWorkersKVNamespaces 67 | * @instance 68 | * @async 69 | * @param {string} account_id - The account ID 70 | * @param {string} id - The namespace id 71 | * @param {Object} config - The namespace object 72 | * @returns {Promise} The namespace response object. 73 | */ 74 | edit: method({ 75 | method: 'PUT', 76 | path: ':id', 77 | }), 78 | }) 79 | ); 80 | -------------------------------------------------------------------------------- /lib/resources/EnterpriseZoneWorkersRoutes.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | const method = require('../method'); 15 | 16 | /** 17 | * EnterpriseZoneWorkersRoutes represents the zones/:zoneId/workers/routes API endpoint. 18 | * 19 | * @class EnterpriseZoneWorkersRoutes 20 | * @hideconstructor 21 | * @extends Resource 22 | */ 23 | module.exports = auto( 24 | prototypal({ 25 | extends: Resource, 26 | path: 'zones/:zoneId/workers/routes', 27 | 28 | includeBasic: ['browse', 'read', 'add', 'del'], 29 | 30 | /** 31 | * browse allows for listing all of a zone's workers routes 32 | * 33 | * @function browse 34 | * @memberof EnterpriseZoneWorkersRoutes 35 | * @instance 36 | * @async 37 | * @param {string} zone_id - The zone ID 38 | * @returns {Promise} The route browse response object. 39 | */ 40 | /** 41 | * read allows for retrieving a specific zone's workers route 42 | * 43 | * @function read 44 | * @memberof EnterpriseZoneWorkersRoutes 45 | * @instance 46 | * @async 47 | * @param {string} zone_id - The zone ID 48 | * @param {string} id - The route ID 49 | * @returns {Promise} The route response object. 50 | */ 51 | /** 52 | * edit allows for modifying a specific zone's workers 53 | * 54 | * @function edit 55 | * @memberof EnterpriseZoneWorkersRoutes 56 | * @instance 57 | * @async 58 | * @param {string} zone_id - The zone ID 59 | * @param {string} id - The route ID 60 | * @param {Object} config - The modified route object 61 | * @returns {Promise} The custom hostname response object. 62 | */ 63 | edit: method({ 64 | method: 'PUT', 65 | path: ':id', 66 | }), 67 | /** 68 | * add allows for creating a workers route 69 | * 70 | * @function add 71 | * @memberof EnterpriseZoneWorkersRoutes 72 | * @instance 73 | * @async 74 | * @param {string} zone_id - The zone ID 75 | * @param {Object} config - The new route object 76 | * @returns {Promise} The custom route response object. 77 | */ 78 | /** 79 | * del allows for removing a workers routes 80 | * 81 | * @function del 82 | * @memberof EnterpriseZoneWorkersRoutes 83 | * @instance 84 | * @async 85 | * @param {string} zone_id - The zone ID 86 | * @param {string} id - The route ID to delete 87 | * @returns {Promise} The custom route response object. 88 | */ 89 | }) 90 | ); 91 | -------------------------------------------------------------------------------- /lib/resources/EnterpriseZoneWorkersScripts.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | const method = require('../method'); 15 | 16 | /** 17 | * EnterpriseZoneWorkersScripts represents the accounts/:accountId/workers/scripts API endpoint. 18 | * 19 | * @class EnterpriseZoneWorkersScripts 20 | * @hideconstructor 21 | * @extends Resource 22 | */ 23 | module.exports = auto( 24 | prototypal({ 25 | extends: Resource, 26 | path: 'accounts/:accountId/workers/scripts', 27 | 28 | includeBasic: ['browse', 'del'], 29 | 30 | /** 31 | * read retrieves a single workers script 32 | * 33 | * @function read 34 | * @memberof EnterpriseZoneWorkersScripts 35 | * @instance 36 | * @async 37 | * @param {string} account_id - The enterprise account ID 38 | * @param {string} name - The script name 39 | * @returns {Promise} The workers script response object. 40 | */ 41 | read: method({ 42 | method: 'GET', 43 | path: ':name', 44 | json: false, 45 | }), 46 | 47 | /** 48 | * edit uploads a new version of a workers script 49 | * 50 | * @function edit 51 | * @memberof EnterpriseZoneWorkersScripts 52 | * @instance 53 | * @async 54 | * @param {string} account_id - The enterprise account ID 55 | * @param {string} name - The script name 56 | * @param {string} script - The script 57 | * @returns {Promise} The response object 58 | */ 59 | edit: method({ 60 | method: 'PUT', 61 | path: ':name', 62 | contentType: 'application/javascript', 63 | }), 64 | 65 | /** 66 | * browse allows for listing all the workers scripts 67 | * 68 | * @function browse 69 | * @memberof EnterpriseZoneWorkersScripts 70 | * @instance 71 | * @async 72 | * @param {string} account_id - The enterprise account ID 73 | * @param {string} name - The script name 74 | * @returns {Promise} The zone workers script response object. 75 | */ 76 | /** 77 | * del allows for deleting the specified workers script 78 | * 79 | * @function del 80 | * @memberof EnterpriseZoneWorkersScripts 81 | * @instance 82 | * @async 83 | * @param {string} account_id - The enterprise account ID 84 | * @param {string} name - The script name 85 | * @returns {Promise} The deleted zone workers script response object. 86 | */ 87 | }) 88 | ); 89 | -------------------------------------------------------------------------------- /lib/resources/IPs.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | 15 | /** 16 | * IPs represents the /ips API endpoint. 17 | * 18 | * @class IPs 19 | * @hideconstructor 20 | * @extends Resource 21 | */ 22 | module.exports = auto( 23 | prototypal({ 24 | extends: Resource, 25 | path: 'ips', 26 | 27 | includeBasic: ['browse'], 28 | 29 | /** 30 | * browse returns a Promise of the current Cloudflare IPv4 and IPv6 addresses. 31 | * 32 | * @function browse 33 | * @memberof IPs 34 | * @instance 35 | * @async 36 | * @returns {Promise} The IPv4 and IPv6 addresses 37 | * @example 38 | * // logs the fetched IP addresses 39 | * cf.ips.browse(console.log) 40 | */ 41 | }) 42 | ); 43 | -------------------------------------------------------------------------------- /lib/resources/PageRules.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | 15 | /** 16 | * PageRules represents the /zones/:zoneID/pagerules API endpoint. 17 | * 18 | * @class PageRules 19 | * @hideconstructor 20 | * @extends Resource 21 | */ 22 | module.exports = auto( 23 | prototypal({ 24 | extends: Resource, 25 | path: 'zones/:zoneId/pagerules', 26 | 27 | includeBasic: ['browse', 'read', 'edit', 'add', 'del'], 28 | 29 | /** 30 | * browse allows for listing all the page rules 31 | * 32 | * @function browse 33 | * @memberof PageRules 34 | * @instance 35 | * @async 36 | * @returns {Promise} The page rules browse response object. 37 | */ 38 | /** 39 | * read allows for retrieving a specific page rule 40 | * 41 | * @function read 42 | * @memberof PageRules 43 | * @instance 44 | * @async 45 | * @param {string} id - The page rule ID 46 | * @returns {Promise} The page rule response object. 47 | */ 48 | /** 49 | * edit allows for modifying a specific zone 50 | * 51 | * @function edit 52 | * @memberof PageRules 53 | * @instance 54 | * @async 55 | * @param {string} id - The page rule ID 56 | * @param {Object} page_rule - The modified page rule object 57 | * @returns {Promise} The page rule response object. 58 | */ 59 | /** 60 | * add allows for creating a new zone 61 | * 62 | * @function add 63 | * @memberof PageRules 64 | * @instance 65 | * @async 66 | * @param {Object} zone - The new page rule object 67 | * @returns {Promise} The page rule response object. 68 | */ 69 | /** 70 | * del allows for removing a new zone 71 | * 72 | * @function del 73 | * @memberof PageRules 74 | * @instance 75 | * @async 76 | * @param {string} id - The page rule ID to delete 77 | * @returns {Promise} The page rule response object. 78 | */ 79 | }) 80 | ); 81 | -------------------------------------------------------------------------------- /lib/resources/Stream.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | const method = require('../method'); 15 | 16 | /** 17 | * Stream represents the /accout/:id/stream API endpoint. 18 | * 19 | * @class Stream 20 | * @hideconstructor 21 | * @extends Resource 22 | */ 23 | module.exports = auto( 24 | prototypal({ 25 | extends: Resource, 26 | path: 'accounts/:accountId/stream', 27 | hasBrokenPatch: true, 28 | 29 | includeBasic: ['browse', 'read', 'edit', 'add', 'del'], 30 | 31 | /** 32 | * ListVideos retrieves all of a account's videos. 33 | * 34 | * @function listVideos 35 | * @memberof Stream 36 | * @instance 37 | * @async 38 | * @param {string} accountId - The account ID 39 | * @returns {Promise} The response object 40 | */ 41 | listVideos: method({ 42 | method: 'GET', 43 | }), 44 | 45 | /** 46 | * VideoDetails retrieves details of a account's single video. 47 | * 48 | * @function videoDetails 49 | * @memberof Stream 50 | * @instance 51 | * @async 52 | * @param {string} accountId - The account ID 53 | * @param {string} id - The video ID 54 | * @returns {Promise} The response object 55 | */ 56 | videoDetails: method({ 57 | method: 'GET', 58 | path: ':id', 59 | }), 60 | 61 | /** 62 | * UploadVideoFromUrl uploads a video from specific URL 63 | * 64 | * @function uploadVideoFromUrl 65 | * @instance 66 | * @async 67 | * @param {string} accountId - The account ID 68 | * @param {Object} video - The upload video info 69 | * @returns {Promise} The response object 70 | */ 71 | uploadVideoFromUrl: method({ 72 | method: 'POST', 73 | path: 'copy', 74 | }), 75 | 76 | /** 77 | * DeleteVideo deletes a account's single video. 78 | * 79 | * @function deleteVideo 80 | * @memberof Stream 81 | * @instance 82 | * @async 83 | * @param {string} accountId - The account ID 84 | * @param {string} id - The video ID 85 | * @returns {Promise} The response object 86 | */ 87 | deleteVideo: method({ 88 | method: 'DELETE', 89 | path: ':id', 90 | }), 91 | }) 92 | ); 93 | -------------------------------------------------------------------------------- /lib/resources/User.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | const method = require('../method'); 15 | 16 | /** 17 | * User represents the /user API endpoint. 18 | * 19 | * @class User 20 | * @hideconstructor 21 | * @extends Resource 22 | */ 23 | module.exports = auto( 24 | prototypal({ 25 | extends: Resource, 26 | path: 'user', 27 | 28 | /** 29 | * read returns the current user object 30 | * 31 | * @function read 32 | * @memberof User 33 | * @instance 34 | * @async 35 | * @returns {Promise} The user object 36 | */ 37 | read: method({ 38 | method: 'GET', 39 | }), 40 | 41 | /** 42 | * edit allows for modification of the current user 43 | * 44 | * @function edit 45 | * @memberof User 46 | * @instance 47 | * @async 48 | * @param {Object} user - The modified user object 49 | * @returns {Promise} The user object 50 | */ 51 | edit: method({ 52 | method: 'PATCH', 53 | }), 54 | }) 55 | ); 56 | -------------------------------------------------------------------------------- /lib/resources/UserTokens.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | const method = require('../method'); 15 | 16 | /** 17 | * UserTokens represents the /user/tokens API endpoint. 18 | * 19 | * @class UserTokens 20 | * @hideconstructor 21 | * @extends Resource 22 | */ 23 | module.exports = auto( 24 | prototypal({ 25 | extends: Resource, 26 | path: 'user/tokens', 27 | 28 | includeBasic: ['browse', 'read', 'edit', 'add', 'del'], 29 | /** 30 | * roll rotates the token secret 31 | * 32 | * @function roll 33 | * @memberof UserTokens 34 | * @instance 35 | * @async 36 | * @param {string} id - The User Token ID 37 | * @returns {Promise} The User Token response object. 38 | */ 39 | roll: method({ 40 | method: 'PUT', 41 | path: ':id/value', 42 | }), 43 | /** 44 | * verify the token secret 45 | * 46 | * @function verify 47 | * @memberof UserTokens 48 | * @instance 49 | * @async 50 | * @returns {Promise} The User Token response object. 51 | */ 52 | verify: method({ 53 | method: 'GET', 54 | path: 'verify', 55 | }), 56 | /** 57 | * browsePermissionGroups browse all available permission groups 58 | * 59 | * @function browsePermissionGroups 60 | * @memberof UserTokens 61 | * @instance 62 | * @async 63 | * @returns {Promise} The response object. 64 | */ 65 | browsePermissionGroups: method({ 66 | method: 'GET', 67 | path: 'permission_groups', 68 | }), 69 | /** 70 | * browse allows for listing user tokens 71 | * 72 | * @function browse 73 | * @memberof UserTokens 74 | * @instance 75 | * @async 76 | * @returns {Promise} The User Token response object. 77 | */ 78 | /** 79 | * read allows for retrieving a user token's details 80 | * 81 | * @function read 82 | * @memberof UserTokens 83 | * @instance 84 | * @async 85 | * @param {string} id - The User Token ID 86 | * @returns {Promise} The User Token object. 87 | */ 88 | /** 89 | * add allows for creating a user token. 90 | * 91 | * @function add 92 | * @memberof UserTokens 93 | * @instance 94 | * @async 95 | * @param {Object} token - The new user token object 96 | * @returns {Promise} The created user token object. 97 | */ 98 | /** 99 | * del allows for deleting a user token. 100 | * 101 | * @function del 102 | * @memberof UserTokens 103 | * @instance 104 | * @async 105 | * @param {string} id - The user token ID to delete 106 | * @returns {Promise} The deleted user token object. 107 | */ 108 | }) 109 | ); 110 | -------------------------------------------------------------------------------- /lib/resources/ZoneCustomHostNames.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | 15 | /** 16 | * ZoneCustomHostNames represents the /zones/:zoneID/custom_hostnames API endpoint. 17 | * 18 | * @class ZoneCustomHostNames 19 | * @hideconstructor 20 | * @extends Resource 21 | */ 22 | module.exports = auto( 23 | prototypal({ 24 | extends: Resource, 25 | path: 'zones/:zoneId/custom_hostnames', 26 | 27 | includeBasic: ['browse', 'read', 'edit', 'add', 'del'], 28 | 29 | /** 30 | * browse allows for listing all of a zone's custom hostanames 31 | * 32 | * @function browse 33 | * @memberof ZoneCustomHostNames 34 | * @instance 35 | * @async 36 | * @param {string} zone_id - The zone ID 37 | * @returns {Promise} The custom hostname browse response object. 38 | */ 39 | /** 40 | * read allows for retrieving a specific custom hostname 41 | * 42 | * @function read 43 | * @memberof ZoneCustomHostNames 44 | * @instance 45 | * @async 46 | * @param {string} zone_id - The zone ID 47 | * @param {string} id - The custom hostname ID 48 | * @returns {Promise} The custom hostname response object. 49 | */ 50 | /** 51 | * edit allows for modifying a specific zone 52 | * 53 | * @function edit 54 | * @memberof ZoneCustomHostNames 55 | * @instance 56 | * @async 57 | * @param {string} zone_id - The zone ID 58 | * @param {string} id - The custom hostname ID 59 | * @param {Object} config - The modified custom hostname object 60 | * @returns {Promise} The custom hostname response object. 61 | */ 62 | /** 63 | * add allows for creating a new zone 64 | * 65 | * @function add 66 | * @memberof ZoneCustomHostNames 67 | * @instance 68 | * @async 69 | * @param {string} zone_id - The zone ID 70 | * @param {Object} config - The new custom hostname object 71 | * @returns {Promise} The custom hostname response object. 72 | */ 73 | /** 74 | * del allows for removing a new zone 75 | * 76 | * @function del 77 | * @memberof ZoneCustomHostNames 78 | * @instance 79 | * @async 80 | * @param {string} zone_id - The zone ID 81 | * @param {string} id - The custom hostname ID to delete 82 | * @returns {Promise} The custom hostname response object. 83 | */ 84 | }) 85 | ); 86 | -------------------------------------------------------------------------------- /lib/resources/ZoneSettings.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | const method = require('../method'); 15 | 16 | /** 17 | * ZoneSettings represents the /zones/:zoneID/settings API endpoint. 18 | * 19 | * @class ZoneSettings 20 | * @hideconstructor 21 | * @extends Resource 22 | */ 23 | module.exports = auto( 24 | prototypal({ 25 | extends: Resource, 26 | path: 'zones/:zoneId/settings', 27 | 28 | includeBasic: ['browse', 'read', 'edit'], 29 | 30 | /** 31 | * editAll allows for editing of all the zone settings at once 32 | * 33 | * @function editAll 34 | * @memberof ZoneSettings 35 | * @instance 36 | * @async 37 | * @param {string} id - The zone ID 38 | * @param {Object} settings - The modified zone settings 39 | * @returns {Promise} The response object 40 | */ 41 | editAll: method({ 42 | method: 'PATCH', 43 | }), 44 | 45 | /** 46 | * browse allows for listing all the zone settings 47 | * 48 | * @function browse 49 | * @memberof ZoneSettings 50 | * @instance 51 | * @async 52 | * @param {string} id - The zone ID 53 | * @returns {Promise} The zone settings response object. 54 | */ 55 | /** 56 | * read retrieves a single zone setting 57 | * 58 | * @function read 59 | * @memberof ZoneSettings 60 | * @instance 61 | * @async 62 | * @param {string} id - The zone ID 63 | * @param {string} setting = The setting name 64 | * @returns {Promise} The zone settings response object. 65 | */ 66 | /** 67 | * edit modifies a single zone setting 68 | * 69 | * @function edit 70 | * @memberof ZoneSettings 71 | * @instance 72 | * @async 73 | * @param {string} id - The zone ID 74 | * @param {string} setting = The setting name 75 | * @param {string|Object} value - The new zone setting 76 | * @returns {Promise} The zone settings response object. 77 | */ 78 | }) 79 | ); 80 | -------------------------------------------------------------------------------- /lib/resources/ZoneWorkers.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | const method = require('../method'); 15 | 16 | /** 17 | * ZoneWorkers represents the /zones/:zoneId/workers API endpoint. 18 | * 19 | * @class ZoneWorkers 20 | * @hideconstructor 21 | * @extends Resource 22 | */ 23 | module.exports = auto( 24 | prototypal({ 25 | extends: Resource, 26 | path: 'zones/:zoneId/workers', 27 | 28 | /** 29 | * validate allows for validating a workers script 30 | * 31 | * @function validate 32 | * @memberof ZoneWorkers 33 | * @instance 34 | * @async 35 | * @param {string} zoneId - The zone ID 36 | * @param {string} script - The worker script 37 | * @returns {Promise} The validate response object. 38 | */ 39 | validate: method({ 40 | method: 'PUT', 41 | path: 'validate', 42 | contentType: 'application/javascript', 43 | }), 44 | }) 45 | ); 46 | -------------------------------------------------------------------------------- /lib/resources/ZoneWorkersRoutes.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | const method = require('../method'); 15 | 16 | /** 17 | * ZoneWorkersRoutes represents the zones/:zoneId/workers/filters API endpoint. 18 | * 19 | * @class ZoneWorkersRoutes 20 | * @hideconstructor 21 | * @extends Resource 22 | */ 23 | module.exports = auto( 24 | prototypal({ 25 | extends: Resource, 26 | path: 'zones/:zoneId/workers/routes', 27 | 28 | includeBasic: ['browse', 'read', 'add', 'del'], 29 | 30 | /** 31 | * edit allows for modifying a specific zone's workers route 32 | * 33 | * @function edit 34 | * @memberof ZoneWorkersRoutes 35 | * @instance 36 | * @async 37 | * @param {string} zone_id - The zone ID 38 | * @param {string} id - The route ID 39 | * @param {Object} config - The modified route object 40 | * @returns {Promise} The custom hostname response object. 41 | */ 42 | edit: method({ 43 | method: 'PUT', 44 | path: ':id', 45 | }), 46 | 47 | /** 48 | * browse allows for listing all of a zone's workers routes 49 | * 50 | * @function browse 51 | * @memberof ZoneWorkersRoutes 52 | * @instance 53 | * @async 54 | * @param {string} zone_id - The zone ID 55 | * @returns {Promise} The route browse response object. 56 | */ 57 | /** 58 | * read allows for retrieving a specific zone's workers route 59 | * 60 | * @function read 61 | * @memberof ZoneWorkersRoutes 62 | * @instance 63 | * @async 64 | * @param {string} zone_id - The zone ID 65 | * @param {string} id - The route ID 66 | * @returns {Promise} The route response object. 67 | */ 68 | /** 69 | * add allows for creating a workers route 70 | * 71 | * @function add 72 | * @memberof ZoneWorkersRoutes 73 | * @instance 74 | * @async 75 | * @param {string} zone_id - The zone ID 76 | * @param {Object} config - The new route object 77 | * @returns {Promise} The custom route response object. 78 | */ 79 | /** 80 | * del allows for removing a workers route 81 | * 82 | * @function del 83 | * @memberof ZoneWorkersRoutes 84 | * @instance 85 | * @async 86 | * @param {string} zone_id - The zone ID 87 | * @param {string} id - The route ID to delete 88 | * @returns {Promise} The custom route response object. 89 | */ 90 | }) 91 | ); 92 | -------------------------------------------------------------------------------- /lib/resources/ZoneWorkersScript.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | const method = require('../method'); 15 | 16 | /** 17 | * ZoneWorkersScript represents the /zones/:zoneID/workers/script API endpoint. 18 | * 19 | * @class ZoneWorkersScript 20 | * @hideconstructor 21 | * @extends Resource 22 | */ 23 | module.exports = auto( 24 | prototypal({ 25 | extends: Resource, 26 | path: 'zones/:zoneId/workers/script', 27 | 28 | /** 29 | * read retrieves a the current workers script 30 | * 31 | * @function read 32 | * @memberof ZoneWorkersScript 33 | * @instance 34 | * @async 35 | * @param {string} zone_id - The enterprise account ID 36 | * @returns {Promise} The workers script response object. 37 | */ 38 | read: method({ 39 | method: 'GET', 40 | json: false, 41 | }), 42 | 43 | /** 44 | * read retrieves a the current workers script 45 | * 46 | * @function read 47 | * @memberof ZoneWorkersScript 48 | * @instance 49 | * @async 50 | * @param {string} zone_id - The enterprise account ID 51 | * @param {string} script - The script 52 | * @returns {Promise} The workers script response object. 53 | */ 54 | edit: method({ 55 | method: 'PUT', 56 | contentType: 'application/javascript', 57 | }), 58 | 59 | /** 60 | * del allows for deleting the workers script 61 | * 62 | * @function del 63 | * @memberof ZoneWorkersScript 64 | * @instance 65 | * @async 66 | * @returns {Promise} The deleted zone workers script response object. 67 | */ 68 | del: method({ 69 | method: 'DELETE', 70 | }), 71 | }) 72 | ); 73 | -------------------------------------------------------------------------------- /lib/resources/Zones.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const prototypal = require('es-class'); 11 | const auto = require('autocreate'); 12 | 13 | const Resource = require('../Resource'); 14 | const method = require('../method'); 15 | 16 | /** 17 | * Zones represents the /zones API endpoint. 18 | * 19 | * @class Zones 20 | * @hideconstructor 21 | * @extends Resource 22 | */ 23 | module.exports = auto( 24 | prototypal({ 25 | extends: Resource, 26 | path: 'zones', 27 | hasBrokenPatch: true, 28 | 29 | includeBasic: ['browse', 'read', 'edit', 'add', 'del'], 30 | 31 | /** 32 | * activationCheck initiates another zone activation check 33 | * 34 | * @function activationCheck 35 | * @memberof Zones 36 | * @instance 37 | * @async 38 | * @param {string} id - The zone ID 39 | * @returns {Promise} The response object 40 | */ 41 | activationCheck: method({ 42 | method: 'PUT', 43 | path: ':id/activation_check', 44 | }), 45 | 46 | /** 47 | * purgeCache purges files from Cloudflare's cache 48 | * 49 | * @function purgeCache 50 | * @memberof Zones 51 | * @instance 52 | * @async 53 | * @param {string} id - The zone ID 54 | * @param {Object} [params] - Parameters to restrict purges 55 | * @param {string[]|Object[]} [params.files] - Files to purge from the Cloudflare cache 56 | * @param {string[]} [params.tags] - Purge files served with these Cache-Tag headers 57 | * @param {string[]} [params.hosts] - Purge files that match these hosts 58 | * @returns {Promise} The response object 59 | */ 60 | purgeCache: method({ 61 | method: 'POST', 62 | path: ':id/purge_cache', 63 | }), 64 | 65 | /** 66 | * browse allows for listing all the zones 67 | * 68 | * @function browse 69 | * @memberof Zones 70 | * @instance 71 | * @async 72 | * @returns {Promise} The zone browse response object. 73 | */ 74 | /** 75 | * read allows for retrieving a specific zone 76 | * 77 | * @function read 78 | * @memberof Zones 79 | * @instance 80 | * @async 81 | * @param {string} id - The zone ID 82 | * @returns {Promise} The zone response object. 83 | */ 84 | /** 85 | * edit allows for modifying a specific zone 86 | * 87 | * @function edit 88 | * @memberof Zones 89 | * @instance 90 | * @async 91 | * @param {string} id - The zone ID 92 | * @param {Object} zone - The modified zone object 93 | * @returns {Promise} The zone response object. 94 | */ 95 | /** 96 | * add allows for creating a new zone 97 | * 98 | * @function add 99 | * @memberof Zones 100 | * @instance 101 | * @async 102 | * @param {Object} zone - The new zone object 103 | * @returns {Promise} The zone response object. 104 | */ 105 | /** 106 | * del allows for removing a new zone 107 | * 108 | * @function del 109 | * @memberof Zones 110 | * @instance 111 | * @async 112 | * @param {string} id - The zone ID to delete 113 | * @returns {Promise} The zone response object. 114 | */ 115 | }) 116 | ); 117 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloudflare", 3 | "version": "2.9.1", 4 | "description": "CloudFlare API client", 5 | "author": "Terin Stock ", 6 | "bugs": { 7 | "url": "https://github.com/cloudflare/node-cloudflare/issues" 8 | }, 9 | "dependencies": { 10 | "autocreate": "^1.1.0", 11 | "es-class": "^2.1.1", 12 | "got": "^6.3.0", 13 | "https-proxy-agent": "^5.0.0", 14 | "object-assign": "^4.1.0", 15 | "should-proxy": "^1.0.4", 16 | "url-pattern": "^1.0.3" 17 | }, 18 | "devDependencies": { 19 | "coveralls": "^2.13.1", 20 | "eslint": "^4.15.0", 21 | "eslint-config-es": "^0.8.12", 22 | "eslint-config-prettier": "^2.9.0", 23 | "eslint-plugin-eslint-comments": "^2.0.1", 24 | "eslint-plugin-mocha": "^4.11.0", 25 | "eslint-plugin-node": "^5.2.1", 26 | "eslint-plugin-notice": "^0.5.6", 27 | "eslint-plugin-prettier": "^2.4.0", 28 | "eslint-plugin-promise": "^3.6.0", 29 | "eslint-plugin-security": "^1.4.0", 30 | "intelli-espower-loader": "^1.0.1", 31 | "mocha": "^3.4.2", 32 | "nyc": "^10.3.2", 33 | "power-assert": "^1.4.4", 34 | "prettier": "^1.9.2", 35 | "testdouble": "^3.1.1" 36 | }, 37 | "homepage": "https://github.com/cloudflare/node-cloudflare", 38 | "keywords": [ 39 | "cloudflare", 40 | "api" 41 | ], 42 | "license": "MIT", 43 | "main": "index.js", 44 | "repository": { 45 | "type": "git", 46 | "url": "git+https://github.com/cloudflare/node-cloudflare.git" 47 | }, 48 | "scripts": { 49 | "lint": "eslint '{index,{lib,test}/**/*}.js'", 50 | "test": "nyc --reporter=lcov --reporter=text-summary mocha --require intelli-espower-loader --recursive test", 51 | "coverage": "cat ./coverage/lcov.info | coveralls" 52 | }, 53 | "files": [ 54 | "index.js", 55 | "lib" 56 | ], 57 | "xo": { 58 | "space": true, 59 | "rules": { 60 | "unicorn/filename-case": 0 61 | } 62 | }, 63 | "publishConfig": { 64 | "tag": "next" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /test/Client.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const assert = require('power-assert'); 11 | const td = require('testdouble'); 12 | const mocha = require('mocha'); 13 | 14 | const describe = mocha.describe; 15 | const it = mocha.it; 16 | const beforeEach = mocha.beforeEach; 17 | const afterEach = mocha.afterEach; 18 | 19 | describe('HTTP Client', () => { 20 | let FakeGetter; 21 | let Client; 22 | 23 | beforeEach(done => { 24 | FakeGetter = td.replace('../lib/Getter'); 25 | Client = require('../lib/Client'); // eslint-disable-line global-require 26 | 27 | done(); 28 | }); 29 | 30 | afterEach(done => { 31 | td.reset(); 32 | done(); 33 | }); 34 | 35 | it('should convert data into query parameters in GET requests', () => { 36 | const getter = new FakeGetter(); 37 | const email = 'fake@domain.email'; 38 | const key = 'DEADBEEF'; 39 | const body = { 40 | hello: 'world', 41 | }; 42 | 43 | const options = { 44 | json: true, 45 | method: 'GET', 46 | headers: { 47 | 'X-Auth-Key': key, 48 | 'X-Auth-Email': email, 49 | 'Content-Type': 'application/json', 50 | Accept: 'application/json', 51 | }, 52 | query: { 53 | name: 'world', 54 | }, 55 | }; 56 | 57 | td.when(getter.got(), {ignoreExtraArgs: true}).thenReject(); 58 | td 59 | .when( 60 | getter.got( 61 | 'https://api.cloudflare.com/client/v4/example/42', 62 | td.matchers.contains(options) 63 | ) 64 | ) 65 | .thenResolve({body}); 66 | 67 | const subject = new Client({ 68 | email, 69 | key, 70 | }); 71 | 72 | const res = subject.request( 73 | 'GET', 74 | 'example/42', 75 | { 76 | name: 'world', 77 | }, 78 | { 79 | auth: {}, 80 | headers: {}, 81 | } 82 | ); 83 | 84 | return res.then(resp => assert.deepEqual(resp, body)); 85 | }); 86 | 87 | it('should pass data as body for non-GET requests', () => { 88 | const getter = new FakeGetter(); 89 | const body = { 90 | hello: 'world', 91 | }; 92 | const options = { 93 | json: true, 94 | timeout: 42, 95 | retries: 1337, 96 | method: 'TEST', 97 | body: JSON.stringify({ 98 | name: 'world', 99 | }), 100 | }; 101 | 102 | td.when(getter.got(), {ignoreExtraArgs: true}).thenReject(); 103 | td 104 | .when( 105 | getter.got( 106 | 'https://api.cloudflare.com/client/v4/example/42', 107 | td.matchers.contains(options) 108 | ) 109 | ) 110 | .thenResolve({body}); 111 | 112 | const subject = new Client({}); 113 | 114 | const res = subject.request( 115 | 'TEST', 116 | 'example/42', 117 | { 118 | name: 'world', 119 | }, 120 | { 121 | timeout: 42, 122 | retries: 1337, 123 | auth: {}, 124 | headers: {}, 125 | } 126 | ); 127 | 128 | return res.then(resp => assert.deepEqual(resp, body)); 129 | }); 130 | 131 | it('should support User Service Auth keys', () => { 132 | const getter = new FakeGetter(); 133 | const email = 'fake@domain.email'; 134 | const key = 'v1.0-DEADBEEF'; 135 | const body = { 136 | hello: 'world', 137 | }; 138 | 139 | const options = { 140 | json: true, 141 | method: 'GET', 142 | headers: { 143 | 'X-Auth-User-Service-Key': key, 144 | 'Content-Type': 'application/json', 145 | Accept: 'application/json', 146 | }, 147 | query: { 148 | name: 'world', 149 | }, 150 | }; 151 | 152 | td.when(getter.got(), {ignoreExtraArgs: true}).thenReject(); 153 | td 154 | .when( 155 | getter.got( 156 | 'https://api.cloudflare.com/client/v4/example/42', 157 | td.matchers.contains(options) 158 | ) 159 | ) 160 | .thenResolve({body}); 161 | 162 | const subject = new Client({ 163 | email, 164 | key, 165 | }); 166 | 167 | const res = subject.request( 168 | 'GET', 169 | 'example/42', 170 | { 171 | name: 'world', 172 | }, 173 | { 174 | auth: {}, 175 | headers: {}, 176 | } 177 | ); 178 | 179 | return res.then(resp => assert.deepEqual(resp, body)); 180 | }); 181 | 182 | it('should support API Tokens', () => { 183 | const getter = new FakeGetter(); 184 | const token = 'vr29SNZEpswxdp'; 185 | const body = { 186 | hello: 'world', 187 | }; 188 | 189 | const options = { 190 | json: true, 191 | method: 'GET', 192 | headers: { 193 | Authorization: `Bearer ${token}`, 194 | 'Content-Type': 'application/json', 195 | Accept: 'application/json', 196 | }, 197 | query: { 198 | name: 'world', 199 | }, 200 | }; 201 | 202 | td.when(getter.got(), {ignoreExtraArgs: true}).thenReject(); 203 | td 204 | .when( 205 | getter.got( 206 | 'https://api.cloudflare.com/client/v4/example/42', 207 | td.matchers.contains(options) 208 | ) 209 | ) 210 | .thenResolve({body}); 211 | 212 | const subject = new Client({ 213 | token, 214 | }); 215 | 216 | const res = subject.request( 217 | 'GET', 218 | 'example/42', 219 | { 220 | name: 'world', 221 | }, 222 | { 223 | auth: {}, 224 | headers: {}, 225 | } 226 | ); 227 | 228 | return res.then(resp => assert.deepEqual(resp, body)); 229 | }); 230 | 231 | it('should override authentication', () => { 232 | const getter = new FakeGetter(); 233 | const body = { 234 | hello: 'world', 235 | }; 236 | const options = { 237 | json: true, 238 | method: 'TEST', 239 | body: JSON.stringify({ 240 | name: 'world', 241 | }), 242 | headers: { 243 | 'X-Auth-Key': 'DEADBEEF', 244 | 'X-Auth-Email': 'fake@domain.email', 245 | }, 246 | }; 247 | 248 | td.when(getter.got(), {ignoreExtraArgs: true}).thenReject(); 249 | td 250 | .when( 251 | getter.got( 252 | 'https://api.cloudflare.com/client/v4/example/42', 253 | td.matchers.contains(options) 254 | ) 255 | ) 256 | .thenResolve({body}); 257 | 258 | const subject = new Client({ 259 | email: 'other@domain.email', 260 | key: '5CA1AB1E', 261 | }); 262 | 263 | const res = subject.request( 264 | 'TEST', 265 | 'example/42', 266 | { 267 | name: 'world', 268 | }, 269 | { 270 | auth: { 271 | email: 'fake@domain.email', 272 | key: 'DEADBEEF', 273 | }, 274 | headers: {}, 275 | } 276 | ); 277 | 278 | return res.then(resp => assert.deepEqual(resp, body)); 279 | }); 280 | }); 281 | -------------------------------------------------------------------------------- /test/Resource.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const assert = require('power-assert'); 11 | const mocha = require('mocha'); 12 | const prototypal = require('es-class'); 13 | const td = require('testdouble'); 14 | 15 | const describe = mocha.describe; 16 | const it = mocha.it; 17 | const beforeEach = mocha.beforeEach; 18 | const afterEach = mocha.afterEach; 19 | 20 | const Resource = require('../lib/Resource'); 21 | const Client = require('../lib/Client'); 22 | 23 | describe('Resource', () => { 24 | let FakeClient; 25 | 26 | beforeEach(done => { 27 | FakeClient = td.constructor(Client); 28 | 29 | done(); 30 | }); 31 | 32 | afterEach(done => { 33 | td.reset(); 34 | done(); 35 | }); 36 | 37 | it('creates an instance of a Resource', done => { 38 | const client = new FakeClient(); 39 | const subject = new Resource(client); 40 | 41 | assert(subject instanceof Resource); 42 | assert.strictEqual(subject._client, client); // eslint-disable-line no-underscore-dangle 43 | 44 | done(); 45 | }); 46 | 47 | describe('createFullPath', () => { 48 | it('returns root when unconfigured', done => { 49 | const client = new FakeClient(); 50 | const subject = new Resource(client); 51 | 52 | const path = subject.createFullPath(); 53 | 54 | assert.equal(path, ''); 55 | 56 | done(); 57 | }); 58 | 59 | it('joins method path with resource path', done => { 60 | const client = new FakeClient(); 61 | const subject = new Resource(client); 62 | 63 | subject.path = 'example'; 64 | 65 | const path = subject.createFullPath('foo'); 66 | 67 | assert.equal(path, 'example/foo'); 68 | 69 | done(); 70 | }); 71 | }); 72 | 73 | describe('subclass', () => { 74 | it('creates and instance of Resource and Klass', done => { 75 | const Klass = prototypal({ 76 | extends: Resource, 77 | }); 78 | const client = new FakeClient(); 79 | const subject = new Klass(client); 80 | 81 | assert(subject instanceof Resource); 82 | assert(subject instanceof Klass); 83 | assert.strictEqual(subject._client, client); // eslint-disable-line no-underscore-dangle 84 | 85 | done(); 86 | }); 87 | 88 | it('joins method path with resource path', done => { 89 | const Klass = prototypal({ 90 | extends: Resource, 91 | path: 'example', 92 | }); 93 | const client = new FakeClient(); 94 | const subject = new Klass(client); 95 | 96 | const path = subject.createFullPath('foo'); 97 | 98 | assert.equal(path, 'example/foo'); 99 | 100 | done(); 101 | }); 102 | 103 | it('includes basic methods', done => { 104 | const Klass = prototypal({ 105 | extends: Resource, 106 | includeBasic: ['browse', 'del'], 107 | }); 108 | const client = new FakeClient(); 109 | const subject = new Klass(client); 110 | 111 | assert(Object.hasOwnProperty.call(subject, 'browse')); 112 | assert(typeof subject.browse === 'function'); 113 | assert(Object.hasOwnProperty.call(subject, 'del')); 114 | assert(typeof subject.del === 'function'); 115 | 116 | done(); 117 | }); 118 | }); 119 | }); 120 | -------------------------------------------------------------------------------- /test/method.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const assert = require('power-assert'); 11 | const td = require('testdouble'); 12 | const mocha = require('mocha'); 13 | 14 | const describe = mocha.describe; 15 | const it = mocha.it; 16 | const beforeEach = mocha.beforeEach; 17 | const afterEach = mocha.afterEach; 18 | 19 | const Resource = require('../lib/Resource'); 20 | const Client = require('../lib/Client'); 21 | const method = require('../lib/method'); 22 | 23 | describe('method', () => { 24 | let FakeResource; 25 | let FakeClient; 26 | 27 | beforeEach(done => { 28 | FakeClient = td.constructor(Client); 29 | FakeResource = td.constructor(Resource); 30 | 31 | done(); 32 | }); 33 | afterEach(done => { 34 | td.reset(); 35 | done(); 36 | }); 37 | 38 | it('should make basic request', () => { 39 | const body = { 40 | hello: 'world', 41 | }; 42 | 43 | const client = new FakeClient(); 44 | const resource = new FakeResource(); 45 | 46 | resource._client = client; // eslint-disable-line no-underscore-dangle 47 | 48 | td.when(resource.createFullPath(undefined)).thenReturn('/'); 49 | td.when(client.request(), {ignoreExtraArgs: true}).thenReject(); 50 | td 51 | .when( 52 | client.request( 53 | 'GET', 54 | '/', 55 | {}, 56 | { 57 | auth: {}, 58 | headers: {}, 59 | json: true, 60 | contentType: 'application/json', 61 | } 62 | ) 63 | ) 64 | .thenResolve(body); 65 | 66 | const subject = method({}).bind(resource); 67 | 68 | return subject().then(resp => assert.deepEqual(resp, body)); 69 | }); 70 | 71 | it('should interpolate URL parameters', () => { 72 | const body = { 73 | hello: 'world', 74 | }; 75 | 76 | const client = new FakeClient(); 77 | const resource = new FakeResource(); 78 | 79 | resource._client = client; // eslint-disable-line no-underscore-dangle 80 | 81 | td.when(resource.createFullPath(':id')).thenReturn('example/:id'); 82 | td.when(client.request(), {ignoreExtraArgs: true}).thenReject(); 83 | td 84 | .when( 85 | client.request( 86 | 'POST', 87 | 'example/42', 88 | {}, 89 | { 90 | auth: {}, 91 | headers: {}, 92 | json: true, 93 | contentType: 'application/json', 94 | } 95 | ) 96 | ) 97 | .thenResolve(body); 98 | 99 | const subject = method({ 100 | method: 'POST', 101 | path: ':id', 102 | }).bind(resource); 103 | 104 | return subject(42).then(resp => assert.deepEqual(resp, body)); 105 | }); 106 | 107 | it('should reject when URL parameters are not provided', () => { 108 | const client = new FakeClient(); 109 | const resource = new FakeResource(); 110 | 111 | resource._client = client; // eslint-disable-line no-underscore-dangle 112 | 113 | td.when(resource.createFullPath(':id')).thenReturn('example/:id'); 114 | td.when(client.request(), {ignoreExtraArgs: true}).thenReject(); 115 | 116 | const subject = method({ 117 | method: 'POST', 118 | path: ':id', 119 | }).bind(resource); 120 | 121 | return subject().catch(err => 122 | assert(err.message.match(/^Cloudflare: Argument/)) 123 | ); 124 | }); 125 | 126 | it('should extract data from arguments', () => { 127 | const body = { 128 | hello: 'world', 129 | }; 130 | const client = new FakeClient(); 131 | const resource = new FakeResource(); 132 | 133 | resource._client = client; // eslint-disable-line no-underscore-dangle 134 | 135 | td.when(resource.createFullPath(':id')).thenReturn('example/:id'); 136 | td.when(client.request(), {ignoreExtraArgs: true}).thenReject(); 137 | td 138 | .when( 139 | client.request( 140 | 'POST', 141 | 'example/42', 142 | { 143 | name: 'world', 144 | }, 145 | { 146 | auth: {}, 147 | headers: {}, 148 | json: true, 149 | contentType: 'application/json', 150 | } 151 | ) 152 | ) 153 | .thenResolve(body); 154 | 155 | const subject = method({ 156 | method: 'POST', 157 | path: ':id', 158 | }).bind(resource); 159 | 160 | return subject(42, { 161 | name: 'world', 162 | }).then(resp => assert.deepEqual(resp, body)); 163 | }); 164 | 165 | it('should extract options with no body', () => { 166 | const body = { 167 | hello: 'world', 168 | }; 169 | 170 | const client = new FakeClient(); 171 | const resource = new FakeResource(); 172 | 173 | resource._client = client; // eslint-disable-line no-underscore-dangle 174 | 175 | td.when(resource.createFullPath(undefined)).thenReturn('/'); 176 | td.when(client.request(), {ignoreExtraArgs: true}).thenReject(); 177 | td 178 | .when( 179 | client.request( 180 | 'GET', 181 | '/', 182 | {}, 183 | { 184 | auth: { 185 | key: 'SCA1EAB1E', 186 | email: 'other@domain.email', 187 | }, 188 | headers: {}, 189 | json: true, 190 | contentType: 'application/json', 191 | } 192 | ) 193 | ) 194 | .thenResolve(body); 195 | 196 | const subject = method({}).bind(resource); 197 | 198 | return subject({ 199 | key: 'SCA1EAB1E', 200 | email: 'other@domain.email', 201 | }).then(resp => assert.deepEqual(resp, body)); 202 | }); 203 | 204 | it('should extract options with body', () => { 205 | const body = { 206 | hello: 'world', 207 | }; 208 | 209 | const client = new FakeClient(); 210 | const resource = new FakeResource(); 211 | 212 | resource._client = client; // eslint-disable-line no-underscore-dangle 213 | 214 | td.when(resource.createFullPath(':id')).thenReturn('example/:id'); 215 | td.when(client.request(), {ignoreExtraArgs: true}).thenReject(); 216 | td 217 | .when( 218 | client.request( 219 | 'POST', 220 | 'example/42', 221 | { 222 | name: 'world', 223 | }, 224 | { 225 | auth: { 226 | key: 'SCA1EAB1E', 227 | email: 'other@domain.email', 228 | }, 229 | headers: {}, 230 | json: true, 231 | contentType: 'application/json', 232 | } 233 | ) 234 | ) 235 | .thenResolve(body); 236 | 237 | const subject = method({ 238 | method: 'POST', 239 | path: ':id', 240 | }).bind(resource); 241 | 242 | return subject( 243 | 42, 244 | { 245 | name: 'world', 246 | }, 247 | { 248 | key: 'SCA1EAB1E', 249 | email: 'other@domain.email', 250 | } 251 | ).then(resp => assert.deepEqual(resp, body)); 252 | }); 253 | 254 | it('should set json when specified', () => { 255 | const body = { 256 | hello: 'world', 257 | }; 258 | 259 | const client = new FakeClient(); 260 | const resource = new FakeResource(); 261 | 262 | resource._client = client; // eslint-disable-line no-underscore-dangle 263 | 264 | td.when(resource.createFullPath(undefined)).thenReturn('/'); 265 | td.when(client.request(), {ignoreExtraArgs: true}).thenReject(); 266 | td 267 | .when( 268 | client.request( 269 | 'GET', 270 | '/', 271 | {}, 272 | { 273 | auth: {}, 274 | headers: {}, 275 | json: false, 276 | contentType: 'application/json', 277 | } 278 | ) 279 | ) 280 | .thenResolve(body); 281 | 282 | const subject = method({ 283 | json: false, 284 | }).bind(resource); 285 | 286 | return subject().then(resp => assert.deepEqual(resp, body)); 287 | }); 288 | 289 | it('should set content-type when specified', () => { 290 | const body = { 291 | hello: 'world', 292 | }; 293 | 294 | const client = new FakeClient(); 295 | const resource = new FakeResource(); 296 | 297 | resource._client = client; // eslint-disable-line no-underscore-dangle 298 | 299 | td.when(resource.createFullPath(undefined)).thenReturn('/'); 300 | td.when(client.request(), {ignoreExtraArgs: true}).thenReject(); 301 | td 302 | .when( 303 | client.request( 304 | 'GET', 305 | '/', 306 | {}, 307 | { 308 | auth: {}, 309 | headers: {}, 310 | json: true, 311 | contentType: 'application/javascript', 312 | } 313 | ) 314 | ) 315 | .thenResolve(body); 316 | 317 | const subject = method({ 318 | contentType: 'application/javascript', 319 | }).bind(resource); 320 | 321 | return subject().then(resp => assert.deepEqual(resp, body)); 322 | }); 323 | }); 324 | -------------------------------------------------------------------------------- /test/proxy.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014-present Cloudflare, Inc. 3 | 4 | * This software may be modified and distributed under the terms 5 | * of the MIT license. See the LICENSE file for details. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const assert = require('power-assert'); 11 | const mocha = require('mocha'); 12 | 13 | const proxy = require('../lib/proxy'); 14 | 15 | const describe = mocha.describe; 16 | const it = mocha.it; 17 | 18 | describe('proxy agents', () => { 19 | it('should not return an agent when parameters are not set', done => { 20 | const tests = [ 21 | ['', '', 'example.com'], 22 | [null, null, 'http://example.com/'], 23 | ]; 24 | 25 | tests.forEach(test => { 26 | const agent = proxy.proxyAgent(test[0], test[1], test[2]); 27 | 28 | assert.ok(!agent, 'agent was unexpected'); 29 | }); 30 | 31 | done(); 32 | }); 33 | 34 | it('should not return an agent when noProxy matches base', done => { 35 | const tests = [ 36 | ['http://10.0.0.1:1234', 'example.com', 'http://example.com'], 37 | ['http://10.0.0.1:1234', '.example.com', 'http://example.com'], 38 | ['http://10.0.0.1:1234', 'foobar.com,.example.com', 'http://example.com'], 39 | ]; 40 | 41 | tests.forEach(test => { 42 | const agent = proxy.proxyAgent(test[0], test[1], test[2]); 43 | 44 | assert.ok(!agent, 'agent was unexpected'); 45 | }); 46 | 47 | done(); 48 | }); 49 | 50 | it('should return an agent when noProxy is not set', done => { 51 | const tests = [ 52 | ['http://10.0.0.1:1234', null, 'http://example.com'], 53 | ['http://10.0.0.1:1234', '', 'http://example.com'], 54 | ]; 55 | 56 | tests.forEach(test => { 57 | const agent = proxy.proxyAgent(test[0], test[1], test[2]); 58 | 59 | assert.ok(agent, 'expected an agent'); 60 | }); 61 | 62 | done(); 63 | }); 64 | 65 | it("should return an agent when noProxy doesn't match", done => { 66 | const agent = proxy.proxyAgent( 67 | 'http://10.0.0.1:1234', 68 | '.example.com', 69 | 'https://example.org' 70 | ); 71 | 72 | assert.ok(agent, 'expected an agent'); 73 | 74 | done(); 75 | }); 76 | }); 77 | --------------------------------------------------------------------------------