cloudflare/cloudflare-typescript

Public

mirrored from https://github.com/cloudflare/cloudflare-typescriptAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v3.2.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

README.md

341lines · modecode

1# Cloudflare Typescript API Library
2
3[![NPM version](https://img.shields.io/npm/v/cloudflare.svg)](https://npmjs.org/package/cloudflare)
4
5This library provides convenient access to the Cloudflare REST API from server-side TypeScript or JavaScript.
6
7The REST API documentation can be found [on developers.cloudflare.com](https://developers.cloudflare.com/api). The full API of this library can be found in [api.md](api.md).
8
9## Installation
10
11```sh
12npm install cloudflare
13```
14
15## Usage
16
17The full API of this library can be found in [api.md](api.md).
18
19<!-- prettier-ignore -->
20```js
21import Cloudflare from 'cloudflare';
22
23const cloudflare = new Cloudflare({
24 apiEmail: process.env['CLOUDFLARE_EMAIL'], // This is the default and can be omitted
25 apiKey: process.env['CLOUDFLARE_API_KEY'], // This is the default and can be omitted
26});
27
28async function main() {
29 const zone = await cloudflare.zones.create({
30 account: { id: '023e105f4ecef8ad9ca31a8372d0c353' },
31 name: 'example.com',
32 type: 'full',
33 });
34
35 console.log(zone.id);
36}
37
38main();
39```
40
41### Request & Response types
42
43This library includes TypeScript definitions for all request params and response fields. You may import and use them like so:
44
45<!-- prettier-ignore -->
46```ts
47import Cloudflare from 'cloudflare';
48
49const cloudflare = new Cloudflare({
50 apiEmail: process.env['CLOUDFLARE_EMAIL'], // This is the default and can be omitted
51 apiKey: process.env['CLOUDFLARE_API_KEY'], // This is the default and can be omitted
52});
53
54async function main() {
55 const params: Cloudflare.ZoneCreateParams = {
56 account: { id: '023e105f4ecef8ad9ca31a8372d0c353' },
57 name: 'example.com',
58 type: 'full',
59 };
60 const zone: Cloudflare.Zone = await cloudflare.zones.create(params);
61}
62
63main();
64```
65
66Documentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors.
67
68## Handling errors
69
70When the library is unable to connect to the API,
71or if the API returns a non-success status code (i.e., 4xx or 5xx response),
72a subclass of `APIError` will be thrown:
73
74<!-- prettier-ignore -->
75```ts
76async function main() {
77 const zone = await cloudflare.zones
78 .get({ zone_id: '023e105f4ecef8ad9ca31a8372d0c353' })
79 .catch(async (err) => {
80 if (err instanceof Cloudflare.APIError) {
81 console.log(err.status); // 400
82 console.log(err.name); // BadRequestError
83 console.log(err.headers); // {server: 'nginx', ...}
84 } else {
85 throw err;
86 }
87 });
88}
89
90main();
91```
92
93Error codes are as followed:
94
95| Status Code | Error Type |
96| ----------- | -------------------------- |
97| 400 | `BadRequestError` |
98| 401 | `AuthenticationError` |
99| 403 | `PermissionDeniedError` |
100| 404 | `NotFoundError` |
101| 422 | `UnprocessableEntityError` |
102| 429 | `RateLimitError` |
103| >=500 | `InternalServerError` |
104| N/A | `APIConnectionError` |
105
106### Retries
107
108Certain errors will be automatically retried 2 times by default, with a short exponential backoff.
109Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict,
110429 Rate Limit, and >=500 Internal errors will all be retried by default.
111
112You can use the `maxRetries` option to configure or disable this:
113
114<!-- prettier-ignore -->
115```js
116// Configure the default for all requests:
117const cloudflare = new Cloudflare({
118 maxRetries: 0, // default is 2
119});
120
121// Or, configure per-request:
122await cloudflare.zones.get({ zone_id: '023e105f4ecef8ad9ca31a8372d0c353' }, {
123 maxRetries: 5,
124});
125```
126
127### Timeouts
128
129Requests time out after 1 minute by default. You can configure this with a `timeout` option:
130
131<!-- prettier-ignore -->
132```ts
133// Configure the default for all requests:
134const cloudflare = new Cloudflare({
135 timeout: 20 * 1000, // 20 seconds (default is 1 minute)
136});
137
138// Override per-request:
139await cloudflare.zones.edit({ zone_id: '023e105f4ecef8ad9ca31a8372d0c353' }, {
140 timeout: 5 * 1000,
141});
142```
143
144On timeout, an `APIConnectionTimeoutError` is thrown.
145
146Note that requests which time out will be [retried twice by default](#retries).
147
148## Auto-pagination
149
150List methods in the Cloudflare API are paginated.
151You can use `for await … of` syntax to iterate through items across all pages:
152
153```ts
154async function fetchAllAccounts(params) {
155 const allAccounts = [];
156 // Automatically fetches more pages as needed.
157 for await (const accountListResponse of cloudflare.accounts.list()) {
158 allAccounts.push(accountListResponse);
159 }
160 return allAccounts;
161}
162```
163
164Alternatively, you can make request a single page at a time:
165
166```ts
167let page = await cloudflare.accounts.list();
168for (const accountListResponse of page.result) {
169 console.log(accountListResponse);
170}
171
172// Convenience methods are provided for manually paginating:
173while (page.hasNextPage()) {
174 page = page.getNextPage();
175 // ...
176}
177```
178
179## Advanced Usage
180
181### Accessing raw Response data (e.g., headers)
182
183The "raw" `Response` returned by `fetch()` can be accessed through the `.asResponse()` method on the `APIPromise` type that all methods return.
184
185You can also use the `.withResponse()` method to get the raw `Response` along with the parsed data.
186
187<!-- prettier-ignore -->
188```ts
189const cloudflare = new Cloudflare();
190
191const response = await cloudflare.zones
192 .create({ account: { id: '023e105f4ecef8ad9ca31a8372d0c353' }, name: 'example.com', type: 'full' })
193 .asResponse();
194console.log(response.headers.get('X-My-Header'));
195console.log(response.statusText); // access the underlying Response object
196
197const { data: zone, response: raw } = await cloudflare.zones
198 .create({ account: { id: '023e105f4ecef8ad9ca31a8372d0c353' }, name: 'example.com', type: 'full' })
199 .withResponse();
200console.log(raw.headers.get('X-My-Header'));
201console.log(zone.id);
202```
203
204### Making custom/undocumented requests
205
206This library is typed for convenient access to the documented API. If you need to access undocumented
207endpoints, params, or response properties, the library can still be used.
208
209#### Undocumented endpoints
210
211To make requests to undocumented endpoints, you can use `client.get`, `client.post`, and other HTTP verbs.
212Options on the client, such as retries, will be respected when making these requests.
213
214```ts
215await client.post('/some/path', {
216 body: { some_prop: 'foo' },
217 query: { some_query_arg: 'bar' },
218});
219```
220
221#### Undocumented request params
222
223To make requests using undocumented parameters, you may use `// @ts-expect-error` on the undocumented
224parameter. This library doesn't validate at runtime that the request matches the type, so any extra values you
225send will be sent as-is.
226
227```ts
228client.foo.create({
229 foo: 'my_param',
230 bar: 12,
231 // @ts-expect-error baz is not yet public
232 baz: 'undocumented option',
233});
234```
235
236For requests with the `GET` verb, any extra params will be in the query, all other requests will send the
237extra param in the body.
238
239If you want to explicitly send an extra argument, you can do so with the `query`, `body`, and `headers` request
240options.
241
242#### Undocumented response properties
243
244To access undocumented response properties, you may access the response object with `// @ts-expect-error` on
245the response object, or cast the response object to the requisite type. Like the request params, we do not
246validate or strip extra properties from the response from the API.
247
248### Customizing the fetch client
249
250By default, this library uses `node-fetch` in Node, and expects a global `fetch` function in other environments.
251
252If you would prefer to use a global, web-standards-compliant `fetch` function even in a Node environment,
253(for example, if you are running Node with `--experimental-fetch` or using NextJS which polyfills with `undici`),
254add the following import before your first import `from "Cloudflare"`:
255
256```ts
257// Tell TypeScript and the package to use the global web fetch instead of node-fetch.
258// Note, despite the name, this does not add any polyfills, but expects them to be provided if needed.
259import 'cloudflare/shims/web';
260import Cloudflare from 'cloudflare';
261```
262
263To do the inverse, add `import "cloudflare/shims/node"` (which does import polyfills).
264This can also be useful if you are getting the wrong TypeScript types for `Response` ([more details](https://github.com/cloudflare/cloudflare-typescript/tree/main/src/_shims#readme)).
265
266### Logging and middleware
267
268You may also provide a custom `fetch` function when instantiating the client,
269which can be used to inspect or alter the `Request` or `Response` before/after each request:
270
271```ts
272import { fetch } from 'undici'; // as one example
273import Cloudflare from 'cloudflare';
274
275const client = new Cloudflare({
276 fetch: async (url: RequestInfo, init?: RequestInit): Promise<Response> => {
277 console.log('About to make a request', url, init);
278 const response = await fetch(url, init);
279 console.log('Got response', response);
280 return response;
281 },
282});
283```
284
285Note that if given a `DEBUG=true` environment variable, this library will log all requests and responses automatically.
286This is intended for debugging purposes only and may change in the future without notice.
287
288### Configuring an HTTP(S) Agent (e.g., for proxies)
289
290By default, this library uses a stable agent for all http/https requests to reuse TCP connections, eliminating many TCP & TLS handshakes and shaving around 100ms off most requests.
291
292If you would like to disable or customize this behavior, for example to use the API behind a proxy, you can pass an `httpAgent` which is used for all requests (be they http or https), for example:
293
294<!-- prettier-ignore -->
295```ts
296import http from 'http';
297import { HttpsProxyAgent } from 'https-proxy-agent';
298
299// Configure the default for all requests:
300const cloudflare = new Cloudflare({
301 httpAgent: new HttpsProxyAgent(process.env.PROXY_URL),
302});
303
304// Override per-request:
305await cloudflare.zones.delete(
306 { zone_id: '023e105f4ecef8ad9ca31a8372d0c353' },
307 {
308 httpAgent: new http.Agent({ keepAlive: false }),
309 },
310);
311```
312
313## Semantic versioning
314
315This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:
316
3171. Changes that only affect static types, without breaking runtime behavior.
3182. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals)_.
3193. Changes that we do not expect to impact the vast majority of users in practice.
320
321We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.
322
323We are keen for your feedback; please open an [issue](https://www.github.com/cloudflare/cloudflare-typescript/issues) with questions, bugs, or suggestions.
324
325## Requirements
326
327TypeScript >= 4.5 is supported.
328
329The following runtimes are supported:
330
331- Node.js 18 LTS or later ([non-EOL](https://endoflife.date/nodejs)) versions.
332- Deno v1.28.0 or higher, using `import Cloudflare from "npm:cloudflare"`.
333- Bun 1.0 or later.
334- Cloudflare Workers.
335- Vercel Edge Runtime.
336- Jest 28 or greater with the `"node"` environment (`"jsdom"` is not supported at this time).
337- Nitro v2.6 or greater.
338
339Note that React Native is not supported at this time.
340
341If you are interested in other runtime environments, please open or upvote an issue on GitHub.