1 | /* eslint-disable max-classes-per-file */
|
2 | const axios = require('./httpclient');
|
3 | const config = require('./config');
|
4 | const Conditions = require('./conditions');
|
5 | const Headers = require('./headers');
|
6 | const AccountAPI = require('./api-account.js');
|
7 | const AuthAPI = require('./api-auth.js');
|
8 | const PurgeAPI = require('./api-purge.js');
|
9 | const DomainAPI = require('./api-domain.js');
|
10 | const HealthcheckAPI = require('./api-healthcheck');
|
11 |
|
12 | class RateLimitError extends Error {
|
13 |
|
14 | }
|
15 |
|
16 | class Fastly {
|
17 | /**
|
18 | * @typedef {Function} CreateFunction
|
19 | * A function that creates a resource of a specific type. If a resource of that
|
20 | * name already exists, it will reject the returned promise with an error.
|
21 | * @param {string} version - The service config version to operate on. Needs to be checked out.
|
22 | * @param {object} data - The data object describing the resource to be created.
|
23 | * @param {string} data.name - The name of the resource to be created.
|
24 | * @returns {Promise} The response object representing the completion or failure.
|
25 | * @throws {FastlyError}
|
26 | */
|
27 |
|
28 | /**
|
29 | * @typedef {Function} UpdateFunction
|
30 | * A function that updates an already existing resource of a specific type.
|
31 | * If no resource of that name exists, it will reject the returned promise with an error.
|
32 | * @param {string} version - The service config version to operate on. Needs to be checked out.
|
33 | * @param {string} name - The name of the resource to be updated. The old name in case of renaming
|
34 | * something.
|
35 | * @param {object} data - The data object describing the resource to be updated.
|
36 | * @param {string} data.name - The new name of the resource to be updated.
|
37 | * @returns {Promise} The response object representing the completion or failure.
|
38 | * @throws {FastlyError}
|
39 | */
|
40 |
|
41 | /**
|
42 | * @typedef {Function} ReadFunction
|
43 | * A function that retrieves a representation of a resource of a specific type.
|
44 | * If no resource of that name exists, it will reject the returned promise with an error.
|
45 | * @param {string} version - The service config version to operate on. Needs to be checked out.
|
46 | * @param {string} name - The name of the resource to be retrieved.
|
47 | * @returns {Promise} The response object representing the completion or failure.
|
48 | * @throws {FastlyError}
|
49 | */
|
50 |
|
51 | /**
|
52 | * @typedef {Function} ListFunction
|
53 | * A function that retrieves a list of resources of a specific type.
|
54 | * @param {string} version - The service config version to operate on. Needs to be checked out.
|
55 | * @returns {Promise} The response object representing the completion or failure.
|
56 | * @throws {FastlyError}
|
57 | */
|
58 |
|
59 | /**
|
60 | * Create a new function that lists all log configurations for a given service
|
61 | * and version. The function can be parametrized with the name of the logging
|
62 | * service.
|
63 | *
|
64 | * @param {string} service - The id of the logging service. Supported services are:
|
65 | * s3, s3canary, azureblob, cloudfiles, digitalocean, ftp, bigquery, gcs, honeycomb,
|
66 | * logshuttle, logentries, loggly, heroku, https, openstack, papertrail, scalyr, splunk,
|
67 | * sumologic, syslog.
|
68 | * @returns {ListFunction} A logging function.
|
69 | */
|
70 | readLogsFn(service) {
|
71 | return async (version) => this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/logging/${service}`);
|
72 | }
|
73 |
|
74 | /**
|
75 | * Create a new function that returns a named log configuration for a given service
|
76 | * and version. The function can be parametrized with the name of the logging
|
77 | * service.
|
78 | *
|
79 | * @param {string} service - The id of the logging service. Supported services are:
|
80 | * s3, s3canary, azureblob, cloudfiles, digitalocean, ftp, bigquery, gcs, honeycomb,
|
81 | * logshuttle, logentries, loggly, heroku, https, openstack, papertrail, scalyr, splunk,
|
82 | * sumologic, syslog.
|
83 | * @returns {ReadFunction} A logging function.
|
84 | */
|
85 | readLogFn(service) {
|
86 | return async (version, name) => this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/logging/${service}/${name}`);
|
87 | }
|
88 |
|
89 | /**
|
90 | * Create a new function that creates a named log configuration for a given service
|
91 | * and version. The function can be parametrized with the name of the logging
|
92 | * service.
|
93 | *
|
94 | * @param {string} service - The id of the logging service. Supported services are:
|
95 | * s3, s3canary, azureblob, cloudfiles, digitalocean, ftp, bigquery, gcs, honeycomb,
|
96 | * logshuttle, logentries, loggly, heroku, https, openstack, papertrail, scalyr, splunk,
|
97 | * sumologic, syslog.
|
98 | * @returns {CreateFunction} A logging function.
|
99 | */
|
100 | createLogFn(service) {
|
101 | return async (version, data) => this.request.post(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/logging/${service}`, data);
|
102 | }
|
103 |
|
104 | /**
|
105 | * Create a new function that updates a named log configuration for a given service
|
106 | * and version. The function can be parametrized with the name of the logging
|
107 | * service.
|
108 | *
|
109 | * @param {string} service - The id of the logging service. Supported services are:
|
110 | * s3, s3canary, azureblob, cloudfiles, digitalocean, ftp, bigquery, gcs, honeycomb,
|
111 | * logshuttle, logentries, loggly, heroku, https, openstack, papertrail, scalyr, splunk,
|
112 | * sumologic, syslog.
|
113 | * @returns {UpdateFunction} A logging function.
|
114 | */
|
115 | updateLogFn(service) {
|
116 | return async (version, name, data) => this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/logging/${service}/${name}`, data);
|
117 | }
|
118 |
|
119 | /**
|
120 | * Creates an update-or-create or "safe create" function that will either create
|
121 | * (if it does not exist) or update (if it does) a named resource. The function
|
122 | * will attempt to check if the resource exists first (if a reader function has been
|
123 | * provided), alternatively, it will just blindly create and fall back with an
|
124 | * update.
|
125 | *
|
126 | * @param {CreateFunction} createFn - A function that creates a resource.
|
127 | * @param {UpdateFunction} updateFn - A function that updates a resource.
|
128 | * @param {ReadFunction} readFn - An optional function that checks for the existence
|
129 | * of a resource.
|
130 | * @returns {UpdateFunction} An update function that does not fail on conflict.
|
131 | */
|
132 | upsertFn(createFn, updateFn, readFn) {
|
133 | if (readFn) {
|
134 | // careful
|
135 | return (version, name, data) => readFn.apply(this, [version, name])
|
136 | .then(() => updateFn.apply(this, [version, name, data]))
|
137 | .catch(() => createFn.apply(this, [version, data]));
|
138 | }
|
139 | // stubborn
|
140 | return (version, name, data) => createFn.apply(this, [version, data])
|
141 | .catch(() => updateFn.apply(this, [version, name, data]));
|
142 | }
|
143 |
|
144 | /* eslint-disable camelcase */
|
145 | /**
|
146 | * The constructor method for creating a fastly-promises instance.
|
147 | *
|
148 | * @param {string} token - The Fastly API token.
|
149 | * @param {string} service_id - The Fastly service ID.
|
150 | * @param {number} timeout - HTTP timeout for requests to the Fastly API, default: 15 seconds.
|
151 | */
|
152 | constructor(token, service_id, timeout = 15000) {
|
153 | this.service_id = service_id;
|
154 | this.request = axios.create({
|
155 | baseURL: config.mainEntryPoint,
|
156 | timeout,
|
157 | headers: { 'Fastly-Key': token },
|
158 | });
|
159 |
|
160 | this.requestmonitor = this.request.monitor;
|
161 |
|
162 | this.versions = {
|
163 | current: undefined,
|
164 | active: undefined,
|
165 | latest: undefined,
|
166 | };
|
167 |
|
168 | this.readS3Logs = this.readLogsFn('s3');
|
169 | this.readS3canaryLogs = this.readLogsFn('s3canary');
|
170 | this.readAzureblobLogs = this.readLogsFn('azureblob');
|
171 | this.readCloudfilesLogs = this.readLogsFn('cloudfiles');
|
172 | this.readDigitaloceanLogs = this.readLogsFn('digitalocean');
|
173 | this.readFtpLogs = this.readLogsFn('ftp');
|
174 | this.readBigqueryLogs = this.readLogsFn('bigquery');
|
175 | this.readGcsLogs = this.readLogsFn('gcs');
|
176 | this.readHoneycombLogs = this.readLogsFn('honeycomb');
|
177 | this.readLogshuttleLogs = this.readLogsFn('logshuttle');
|
178 | this.readLogentriesLogs = this.readLogsFn('logentries');
|
179 | this.readLogglyLogs = this.readLogsFn('loggly');
|
180 | this.readHerokuLogs = this.readLogsFn('heroku');
|
181 | this.readOpenstackLogs = this.readLogsFn('openstack');
|
182 | this.readPapertrailLogs = this.readLogsFn('papertrail');
|
183 | this.readScalyrLogs = this.readLogsFn('scalyr');
|
184 | this.readSplunkLogs = this.readLogsFn('splunk');
|
185 | this.readSumologicLogs = this.readLogsFn('sumologic');
|
186 | this.readSyslogLogs = this.readLogsFn('syslog');
|
187 | this.readHttpsLogs = this.readLogsFn('https');
|
188 |
|
189 | this.readS3 = this.readLogFn('s3');
|
190 | this.readS3canary = this.readLogFn('s3canary');
|
191 | this.readAzureblob = this.readLogFn('azureblob');
|
192 | this.readCloudfiles = this.readLogFn('cloudfiles');
|
193 | this.readDigitalocean = this.readLogFn('digitalocean');
|
194 | this.readFtp = this.readLogFn('ftp');
|
195 | this.readBigquery = this.readLogFn('bigquery');
|
196 | this.readGcs = this.readLogFn('gcs');
|
197 | this.readHoneycomb = this.readLogFn('honeycomb');
|
198 | this.readLogshuttle = this.readLogFn('logshuttle');
|
199 | this.readLogentries = this.readLogFn('logentries');
|
200 | this.readLoggly = this.readLogFn('loggly');
|
201 | this.readHeroku = this.readLogFn('heroku');
|
202 | this.readOpenstack = this.readLogFn('openstack');
|
203 | this.readPapertrail = this.readLogFn('papertrail');
|
204 | this.readScalyr = this.readLogFn('scalyr');
|
205 | this.readSplunk = this.readLogFn('splunk');
|
206 | this.readSumologic = this.readLogFn('sumologic');
|
207 | this.readSyslog = this.readLogFn('syslog');
|
208 | this.readHttps = this.readLogFn('https');
|
209 |
|
210 | this.createS3 = this.createLogFn('s3');
|
211 | this.createS3canary = this.createLogFn('s3canary');
|
212 | this.createAzureblob = this.createLogFn('azureblob');
|
213 | this.createCloudfiles = this.createLogFn('cloudfiles');
|
214 | this.createDigitalocean = this.createLogFn('digitalocean');
|
215 | this.createFtp = this.createLogFn('ftp');
|
216 | this.createBigquery = this.createLogFn('bigquery');
|
217 | this.createGcs = this.createLogFn('gcs');
|
218 | this.createHoneycomb = this.createLogFn('honeycomb');
|
219 | this.createLogshuttle = this.createLogFn('logshuttle');
|
220 | this.createLogentries = this.createLogFn('logentries');
|
221 | this.createLoggly = this.createLogFn('loggly');
|
222 | this.createHeroku = this.createLogFn('heroku');
|
223 | this.createOpenstack = this.createLogFn('openstack');
|
224 | this.createPapertrail = this.createLogFn('papertrail');
|
225 | this.createScalyr = this.createLogFn('scalyr');
|
226 | this.createSplunk = this.createLogFn('splunk');
|
227 | this.createSumologic = this.createLogFn('sumologic');
|
228 | this.createSyslog = this.createLogFn('syslog');
|
229 | this.createHttps = this.createLogFn('https');
|
230 |
|
231 | this.updateS3 = this.updateLogFn('s3');
|
232 | this.updateS3canary = this.updateLogFn('s3canary');
|
233 | this.updateAzureblob = this.updateLogFn('azureblob');
|
234 | this.updateCloudfiles = this.updateLogFn('cloudfiles');
|
235 | this.updateDigitalocean = this.updateLogFn('digitalocean');
|
236 | this.updateFtp = this.updateLogFn('ftp');
|
237 | this.updateBigquery = this.updateLogFn('bigquery');
|
238 | this.updateGcs = this.updateLogFn('gcs');
|
239 | this.updateHoneycomb = this.updateLogFn('honeycomb');
|
240 | this.updateLogshuttle = this.updateLogFn('logshuttle');
|
241 | this.updateLogentries = this.updateLogFn('logentries');
|
242 | this.updateLoggly = this.updateLogFn('loggly');
|
243 | this.updateHeroku = this.updateLogFn('heroku');
|
244 | this.updateOpenstack = this.updateLogFn('openstack');
|
245 | this.updatePapertrail = this.updateLogFn('papertrail');
|
246 | this.updateScalyr = this.updateLogFn('scalyr');
|
247 | this.updateSplunk = this.updateLogFn('splunk');
|
248 | this.updateSumologic = this.updateLogFn('sumologic');
|
249 | this.updateSyslog = this.updateLogFn('syslog');
|
250 | this.updateHttps = this.updateLogFn('https');
|
251 |
|
252 | this.writeS3 = this
|
253 | .upsertFn(this.createS3, this.updateS3, this.readS3);
|
254 | this.writeS3canary = this
|
255 | .upsertFn(this.createS3canary, this.updateS3canary, this.readS3canary);
|
256 | this.writeAzureblob = this
|
257 | .upsertFn(this.createAzureblob, this.updateAzureblob, this.readAzureblob);
|
258 | this.writeCloudfiles = this
|
259 | .upsertFn(this.createCloudfiles, this.updateCloudfiles, this.readCloudfiles);
|
260 | this.writeDigitalocean = this
|
261 | .upsertFn(this.createDigitalocean, this.updateDigitalocean, this.readDigitalocean);
|
262 | this.writeFtp = this
|
263 | .upsertFn(this.createFtp, this.updateFtp, this.readFtp);
|
264 | this.writeBigquery = this
|
265 | .upsertFn(this.createBigquery, this.updateBigquery, this.readBigquery);
|
266 | this.writeGcs = this
|
267 | .upsertFn(this.createGcs, this.updateGcs, this.readGcs);
|
268 | this.writeHoneycomb = this
|
269 | .upsertFn(this.createHoneycomb, this.updateHoneycomb, this.readHoneycomb);
|
270 | this.writeLogshuttle = this
|
271 | .upsertFn(this.createLogshuttle, this.updateLogshuttle, this.readLogshuttle);
|
272 | this.writeLogentries = this
|
273 | .upsertFn(this.createLogentries, this.updateLogentries, this.readLogentries);
|
274 | this.writeLoggly = this
|
275 | .upsertFn(this.createLoggly, this.updateLoggly, this.readLoggly);
|
276 | this.writeHeroku = this
|
277 | .upsertFn(this.createHeroku, this.updateHeroku, this.readHeroku);
|
278 | this.writeOpenstack = this
|
279 | .upsertFn(this.createOpenstack, this.updateOpenstack, this.readOpenstack);
|
280 | this.writePapertrail = this
|
281 | .upsertFn(this.createPapertrail, this.updatePapertrail, this.readPapertrail);
|
282 | this.writeScalyr = this
|
283 | .upsertFn(this.createScalyr, this.updateScalyr, this.readScalyr);
|
284 | this.writeSplunk = this
|
285 | .upsertFn(this.createSplunk, this.updateSplunk, this.readSplunk);
|
286 | this.writeSumologic = this
|
287 | .upsertFn(this.createSumologic, this.updateSumologic, this.readSumologic);
|
288 | this.writeSyslog = this
|
289 | .upsertFn(this.createSyslog, this.updateSyslog, this.readSyslog);
|
290 | this.writeHttps = this
|
291 | .upsertFn(this.createHttps, this.updateHttps, this.readHttps);
|
292 |
|
293 | this.writeVCL = this.upsertFn(this.createVCL, this.updateVCL);
|
294 | this.writeSnippet = this.upsertFn(this.createSnippet, this.updateSnippet, this.readSnippet);
|
295 | this.writeBackend = this.upsertFn(this.createBackend, this.updateBackend);
|
296 |
|
297 | this.writeCondition = this.upsertFn(
|
298 | this.createCondition,
|
299 | this.updateCondition,
|
300 | this.readCondition,
|
301 | );
|
302 |
|
303 | this.writeHeader = this.upsertFn(
|
304 | this.createHeader,
|
305 | this.updateHeader,
|
306 | this.readHeader,
|
307 | );
|
308 |
|
309 | this.conditions = new Conditions(this);
|
310 | this.headers = new Headers(this);
|
311 |
|
312 | // bind the methods of the API classes.
|
313 | [AccountAPI, AuthAPI, PurgeAPI, DomainAPI, HealthcheckAPI].forEach((API) => {
|
314 | const api = new API(this);
|
315 | Object.getOwnPropertyNames(API.prototype).forEach((name) => {
|
316 | const prop = api[name];
|
317 | if (typeof prop === 'function' && !name.startsWith('_') && name !== 'constructor') {
|
318 | this[name] = prop.bind(api);
|
319 | }
|
320 | });
|
321 | });
|
322 |
|
323 | this.writeHealthcheck = this.upsertFn(
|
324 | this.createHealthcheck,
|
325 | this.updateHealthcheck,
|
326 | this.readHealtcheck,
|
327 | );
|
328 | }
|
329 |
|
330 | /**
|
331 | * @typedef {object} FastlyError
|
332 | * The FastlyError class describes the most common errors that can occur
|
333 | * when working with the Fastly API. Using `error.status`, the underlying
|
334 | * HTTP status code can be retrieved. Known error status codes include:
|
335 | * - 400: attempting to activate invalid VCL
|
336 | * - 401: invalid credentials
|
337 | * - 404: resource not found
|
338 | * - 409: confict when trying to POST a resource that already exists
|
339 | * - 422: attempting to modify a service config that is not checked out
|
340 | * - 429: rate limit exceeded, try again later
|
341 | * @property {number} status The HTTP status code from the server response, e.g. 200.
|
342 | * @property {object} data The parsed body of the HTTP response.
|
343 | * @property {string} code A short error message.
|
344 | * @property {string} message A more detailed error message.
|
345 | */
|
346 |
|
347 | /**
|
348 | * @typedef {object} Response
|
349 | * @property {number} status The HTTP status code from the server response, e.g. 200.
|
350 | * @property {string} statusText The HTTP status text, e.g. 'OK'.
|
351 | * @property {object} headers The HTTP headers of the reponse.
|
352 | * @property {object} config The original request configuration used for the HTTP client.
|
353 | * @property {object} request The HTTP request.
|
354 | * @property {object} data The parsed body of the HTTP response.
|
355 | */
|
356 |
|
357 | /**
|
358 | * Get a list of all Fastly datacenters.
|
359 | *
|
360 | * @see https://docs.fastly.com/api/tools#datacenter_1c8d3b9dd035e301155b44eae05e0554
|
361 | * @example
|
362 | * instance.dataCenters()
|
363 | .then(res => {
|
364 | console.log(res.data);
|
365 | })
|
366 | .catch(err => {
|
367 | console.log(err.message);
|
368 | });
|
369 | * @returns {Promise} The response object representing the completion or failure.
|
370 | */
|
371 | dataCenters() {
|
372 | return this.request.get('/datacenters');
|
373 | }
|
374 |
|
375 | /**
|
376 | * Fastly's services IP ranges.
|
377 | *
|
378 | * @see https://docs.fastly.com/api/tools#public_ip_list_ef2e9900a1c9522b58f5abed92ec785e
|
379 | * @example
|
380 | * instance.publicIpList()
|
381 | .then(res => {
|
382 | console.log(res.data);
|
383 | })
|
384 | .catch(err => {
|
385 | console.log(err.message);
|
386 | });
|
387 | * @returns {Promise} The response object representing the completion or failure.
|
388 | */
|
389 | publicIpList() {
|
390 | return this.request.get('/public-ip-list');
|
391 | }
|
392 |
|
393 | /**
|
394 | * Retrieve headers and MD5 hash of the content for a particular URL from each Fastly edge server.
|
395 | *
|
396 | * @see https://docs.fastly.com/api/tools#content_4d2d4548b29c7661e17ebe7098872d6d
|
397 | * @example
|
398 | * instance.edgeCheck('api.example.com')
|
399 | .then(res => {
|
400 | console.log(res.data);
|
401 | })
|
402 | .catch(err => {
|
403 | console.log(err.message);
|
404 | });
|
405 | * @param {string} url - Full URL (host and path) to check on all nodes. If protocol is omitted,
|
406 | http will be assumed.
|
407 | * @returns {Promise} The response object representing the completion or failure.
|
408 | */
|
409 | edgeCheck(url = '') {
|
410 | return this.request.get(`/content/edge_check?url=${url}`);
|
411 | }
|
412 |
|
413 | /**
|
414 | * List all services.
|
415 | *
|
416 | * @see https://docs.fastly.com/api/config#service_74d98f7e5d018256e44d1cf820388ef8
|
417 | * @example
|
418 | * instance.readServices()
|
419 | .then(res => {
|
420 | console.log(res.data);
|
421 | })
|
422 | .catch(err => {
|
423 | console.log(err.message);
|
424 | });
|
425 | * @returns {Promise} The response object representing the completion or failure.
|
426 | */
|
427 | readServices() {
|
428 | return this.request.get('/service');
|
429 | }
|
430 |
|
431 | /**
|
432 | * Reads the services and returns a data object that contains a map where the service id is
|
433 | * the key.
|
434 | *
|
435 | * @returns {Promise} The response object representing the completion or failure.
|
436 | */
|
437 | async readServicesById() {
|
438 | const ret = await this.request.get('/service');
|
439 | ret.data = ret.data.reduce((dat, service) => Object.assign(dat, { [service.id]: service }), {});
|
440 | return ret;
|
441 | }
|
442 |
|
443 | /**
|
444 | * Get a specific service by id.
|
445 | *
|
446 | * @see https://docs.fastly.com/api/config#service_a884a9abd5af9723f6fcbb1ed13ae4cc
|
447 | * @param {string} [serviceId] - The service id.
|
448 | * @returns {Promise} The response object representing the completion or failure.
|
449 | */
|
450 | async readService(serviceId = this.service_id) {
|
451 | return this.request.get(`/service/${serviceId}`);
|
452 | }
|
453 |
|
454 | /**
|
455 | * List the versions for a particular service.
|
456 | *
|
457 | * @see https://docs.fastly.com/api/config#version_dfde9093f4eb0aa2497bbfd1d9415987
|
458 | * @example
|
459 | * instance.readVersions()
|
460 | .then(res => {
|
461 | const active = res.data.filter(version => version.active);
|
462 | console.log(active);
|
463 | })
|
464 | .catch(err => {
|
465 | console.log(err.message);
|
466 | });
|
467 | * @returns {Promise} The response object representing the completion or failure.
|
468 | */
|
469 | readVersions() {
|
470 | return this.request.get(`/service/${this.service_id}/version`);
|
471 | }
|
472 |
|
473 | /**
|
474 | * @typedef {object} Versions
|
475 | *
|
476 | * Describes the most relevant versions of the service.
|
477 | *
|
478 | * @property {number} latest - The latest version of the service.
|
479 | * @property {number} active - The currently active version number.
|
480 | * @property {number} current - The latest editable version number.
|
481 | */
|
482 | /**
|
483 | * Gets the version footprint for the service.
|
484 | *
|
485 | * @returns {Versions} The latest, current, and active versions of the service.
|
486 | */
|
487 | async getVersions() {
|
488 | if (this.versions.latest) {
|
489 | return this.versions;
|
490 | }
|
491 | const { data } = await this.readVersions();
|
492 | this.versions.initial = 1;
|
493 | this.versions.latest = data
|
494 | .map(({ number }) => number)
|
495 | .pop();
|
496 | this.versions.active = data
|
497 | .filter((version) => version.active)
|
498 | .map(({ number }) => number)
|
499 | .pop();
|
500 | this.versions.current = data
|
501 | .filter((version) => !version.locked)
|
502 | .map(({ number }) => number)
|
503 | .pop();
|
504 |
|
505 | return this.versions;
|
506 | }
|
507 |
|
508 | async getVersion(version, ...fallbackname) {
|
509 | if (version) {
|
510 | return version;
|
511 | }
|
512 | const versions = await this.getVersions();
|
513 | return fallbackname.map((attempt) => versions[attempt]).filter((e) => e)[0];
|
514 | }
|
515 |
|
516 | /**
|
517 | * Clone the current configuration into a new version.
|
518 | *
|
519 | * @param {string} version - The version to be cloned.
|
520 | * @see https://docs.fastly.com/api/config#version_7f4937d0663a27fbb765820d4c76c709
|
521 | * @example
|
522 | * instance.cloneVersion('45')
|
523 | .then(res => {
|
524 | console.log(res.data);
|
525 | })
|
526 | .catch(err => {
|
527 | console.log(err.message);
|
528 | });
|
529 | * @returns {Promise} The response object representing the completion or failure.
|
530 | */
|
531 | async cloneVersion(version) {
|
532 | const versions = await this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'active', 'current', 'latest', 'initial')}/clone`);
|
533 | this.versions.current = versions.data.number;
|
534 | this.versions.latest = versions.data.number;
|
535 | return versions;
|
536 | }
|
537 |
|
538 | /**
|
539 | * Activate the current version.
|
540 | *
|
541 | * @param {string} version - The version to be activated.
|
542 | * @see https://docs.fastly.com/api/config#version_0b79ae1ba6aee61d64cc4d43fed1e0d5
|
543 | * @example
|
544 | * instance.activateVersion('23')
|
545 | .then(res => {
|
546 | console.log(res.data);
|
547 | })
|
548 | .catch(err => {
|
549 | console.log(err.message);
|
550 | });
|
551 | * @returns {Promise} The response object representing the completion or failure.
|
552 | */
|
553 | async activateVersion(version) {
|
554 | const versions = await this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/activate`);
|
555 | this.versions.active = versions.data.number;
|
556 | this.versions.latest = versions.data.number;
|
557 | return versions;
|
558 | }
|
559 |
|
560 | // === start ===
|
561 |
|
562 | /**
|
563 | * List all dictionary items for a particular service and version.
|
564 | *
|
565 | * @see https://docs.fastly.com/api/config#dictionary_item_a48de28cd7e76c1ea58523f39bb7204b
|
566 | * @example
|
567 | * instance.readDictItems(1, 'my_dictionary')
|
568 | .then(res => {
|
569 | console.log(res.data);
|
570 | })
|
571 | .catch(err => {
|
572 | console.log(err.message);
|
573 | });
|
574 | * @param {string} version - The version of the dictionary.
|
575 | * @param {string} name - The name of the dictionary.
|
576 | * @returns {Promise} The response object representing the completion or failure.
|
577 | */
|
578 | async readDictItems(version, name) {
|
579 | return this.readDictionary(
|
580 | await this.getVersion(version, 'latest'),
|
581 | name,
|
582 | ).then(({ data }) => this.request.get(`/service/${this.service_id}/dictionary/${data.id}/items`));
|
583 | }
|
584 |
|
585 | /**
|
586 | * Get details of a single dictionary item.
|
587 | *
|
588 | * @see https://docs.fastly.com/api/config#dictionary_item_08f090cd03ed4602ae63f131087e2f29
|
589 | * @example
|
590 | * instance.readDictItem('12', 'extensions', 'some_key')
|
591 | .then(res => {
|
592 | console.log(res.data);
|
593 | })
|
594 | .catch(err => {
|
595 | console.log(err.message);
|
596 | });
|
597 | * @param {string} version - The current version of a service.
|
598 | * @param {string} name - Name of the dictionary.
|
599 | * @param {string} key - The key to retrieve values by.
|
600 | * @returns {Promise} The response object representing the completion or failure.
|
601 | */
|
602 | async readDictItem(version, name, key) {
|
603 | return this.readDictionary(
|
604 | await this.getVersion(version, 'latest'),
|
605 | name,
|
606 | ).then(({ data }) => {
|
607 | if (data.write_only) {
|
608 | return {
|
609 | status: 403, // not permitted to read from write-only dicts
|
610 | data: {
|
611 | dictionary_id: data.id,
|
612 | service_id: this.service_id,
|
613 | item_key: key,
|
614 | item_value: undefined,
|
615 | created_at: undefined,
|
616 | deleted_at: undefined,
|
617 | updated_at: undefined,
|
618 | },
|
619 | };
|
620 | }
|
621 | // always use uncached version here
|
622 | return this.request.get.fresh(`/service/${this.service_id}/dictionary/${data.id}/item/${encodeURIComponent(key)}`);
|
623 | });
|
624 | }
|
625 |
|
626 | /**
|
627 | * Create a new dictionary item for a particular service and version.
|
628 | *
|
629 | * @see https://docs.fastly.com/api/config#dictionary_item_6ec455c0ba1b21671789e1362bc7fe55
|
630 | * @param {number} version - The version number (current if omitted).
|
631 | * @param {object} name - The dictionary definition.
|
632 | * @param {string} key - The key.
|
633 | * @param {string} value - The value to write.
|
634 | * @returns {Promise} The reponse object.
|
635 | */
|
636 | async createDictItem(version, name, key, value) {
|
637 | return this.readDictionary(
|
638 | await this.getVersion(version, 'latest'),
|
639 | name,
|
640 | ).then(({ data }) => this.request.post(`/service/${this.service_id}/dictionary/${data.id}/item`, {
|
641 | item_key: key,
|
642 | item_value: value,
|
643 | }));
|
644 | }
|
645 |
|
646 | /**
|
647 | * @typedef {object} DictUpdate
|
648 | * Specifies a dictionary update operation. In most cases, `upsert` is the best way
|
649 | * to update values, as it will work for existing and non-existing items.
|
650 | * @property {string} op - The operation: `create`, `update`, `delete`, or `upsert`.
|
651 | * @property {string} item_key - The lookup key.
|
652 | * @property {string} item_value - The dictionary value.
|
653 | */
|
654 | /**
|
655 | * Updates multiple dictionary items in bulk.
|
656 | *
|
657 | * @param {number} version - The version numer (current if ommitted).
|
658 | * @param {string} name - Name of the dictionary.
|
659 | * @param {...DictUpdate} items - The dictionary update operations.
|
660 | * @returns {Promise} The response object.
|
661 | * @example
|
662 | * // single item
|
663 | * fastly.bulkUpdateDictItems(1, 'secret_dictionary',
|
664 | * { item_key: 'some_key', item_value: 'some_value', op: 'upsert' });
|
665 | *
|
666 | * // multiple items
|
667 | * fastly.bulkUpdateDictItems(1, 'secret_dictionary',
|
668 | * { item_key: 'some_key', item_value: 'some_value', op: 'update' },
|
669 | * { item_key: 'other_key', item_value: 'other_value', op: 'update' });
|
670 | */
|
671 | async bulkUpdateDictItems(version, name, ...items) {
|
672 | return this.readDictionary(
|
673 | await this.getVersion(version, 'latest'),
|
674 | name,
|
675 | ).then(({ data }) => this.request.patch(`/service/${this.service_id}/dictionary/${data.id}/items`, {
|
676 | items,
|
677 | }));
|
678 | }
|
679 |
|
680 | /**
|
681 | * Update a dictionary item value for a particular service and version.
|
682 | *
|
683 | * @see https://docs.fastly.com/api/config#dictionary_item_34c884a7cdce84dfcfd38dac7a0b5bb0
|
684 | * @example
|
685 | * instance.updateDictItem(1, 'extensions', 'html', 'text/html')
|
686 | .then(res => {
|
687 | console.log(res.data);
|
688 | })
|
689 | .catch(err => {
|
690 | console.log(err.message);
|
691 | });
|
692 | * @param {string} version - The current version of a service.
|
693 | * @param {string} name - The name of the dictionary.
|
694 | * @param {string} key - The key to update data under.
|
695 | * @param {string} value - The value to update the dictionary with.
|
696 | * @returns {Promise} The response object representing the completion or failure.
|
697 | */
|
698 | async updateDictItem(version, name, key, value) {
|
699 | return this.readDictionary(
|
700 | await this.getVersion(version, 'latest'),
|
701 | name,
|
702 | ).then(({ data }) => this.request.put(`/service/${this.service_id}/dictionary/${data.id}/item/${encodeURIComponent(key)}`, {
|
703 | item_value: value,
|
704 | }));
|
705 | }
|
706 |
|
707 | /**
|
708 | * Delete a dictionary item for a particular service and version.
|
709 | *
|
710 | * @see https://docs.fastly.com/api/config#dictionary_item_664347e743b8eafc9a93c729d9da0427
|
711 | * @example
|
712 | * instance.deleteDictItem('34', 'extensions', 'html')
|
713 | .then(res => {
|
714 | console.log(res.data);
|
715 | })
|
716 | .catch(err => {
|
717 | console.log(err.message);
|
718 | });
|
719 | * @param {string} version - The current version of a service.
|
720 | * @param {string} name - The name of the dictionary.
|
721 | * @param {string} key - The key to update data under.
|
722 | * @returns {Promise} The response object representing the completion or failure.
|
723 | */
|
724 | async deleteDictItem(version, name, key) {
|
725 | return this.readDictionary(
|
726 | await this.getVersion(version, 'latest'),
|
727 | name,
|
728 | ).then(({ data }) => this.request.delete(`/service/${this.service_id}/dictionary/${data.id}/item/${encodeURIComponent(key)}`));
|
729 | }
|
730 |
|
731 | /**
|
732 | * Safely create, update or delete a dictionary item in a named dictionary.
|
733 | *
|
734 | * @param {number} version - Service version to use for dictionary lookup.
|
735 | * @param {string} name - Name of the dictionary (not ID).
|
736 | * @param {string} key - Key to create, update or delete.
|
737 | * @param {string} value - Value to update. Empty strings will delete the dictionary entry.
|
738 | * @returns {Promise} The response object representing the completion or failure.
|
739 | */
|
740 | writeDictItem(version, name, key, value) {
|
741 | return this.readDictItem(version, name, key)
|
742 | .then(() => {
|
743 | // the dictionary item already exists
|
744 | if (value) {
|
745 | // update existing value
|
746 | return this.updateDictItem(version, name, key, value);
|
747 | }
|
748 | // value is undefined. Fastly does not support overwriting with empty
|
749 | // values, so we delete the value
|
750 | return this.deleteDictItem(version, name, key);
|
751 | })
|
752 | .catch(() => {
|
753 | // the dictionary item does not exist
|
754 | if (value) {
|
755 | return this.createDictItem(version, name, key, value);
|
756 | }
|
757 | // the item does not exist and there is no data to write, we just pretend it went ok
|
758 | return {
|
759 | status: 200,
|
760 | data: {
|
761 | status: 'ok',
|
762 | },
|
763 | };
|
764 | });
|
765 | }
|
766 |
|
767 | // === done ===
|
768 |
|
769 | /**
|
770 | * List all dictionaries for a particular service and version.
|
771 | *
|
772 | * @see https://docs.fastly.com/api/config#dictionary_6d2cc293b994eb8c16d93e92e91f3915
|
773 | * @example
|
774 | * instance.readDictionaries('12')
|
775 | .then(res => {
|
776 | console.log(res.data);
|
777 | })
|
778 | .catch(err => {
|
779 | console.log(err.message);
|
780 | });
|
781 | * @param {string} version - The current version of a service.
|
782 | * @returns {Promise} The response object representing the completion or failure.
|
783 | */
|
784 | async readDictionaries(version) {
|
785 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/dictionary`);
|
786 | }
|
787 |
|
788 | /**
|
789 | * Get details of a single dictionary.
|
790 | *
|
791 | * @see https://docs.fastly.com/api/config#dictionary_0e16df083830ed3b6c30b73dcef64014
|
792 | * @example
|
793 | * instance.readDictionary('12', 'extensions')
|
794 | .then(res => {
|
795 | console.log(res.data);
|
796 | })
|
797 | .catch(err => {
|
798 | console.log(err.message);
|
799 | });
|
800 | * @param {string} version - The current version of a service.
|
801 | * @param {string} name - Name of the dictionary.
|
802 | * @returns {Promise} The response object representing the completion or failure.
|
803 | */
|
804 | async readDictionary(version, name) {
|
805 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/dictionary/${name}`);
|
806 | }
|
807 |
|
808 | /**
|
809 | * Create a new dictionary for a particular service and version.
|
810 | *
|
811 | * @see https://docs.fastly.com/api/config#dictionary_7d48b87bf82433162a3b209292722125
|
812 | * @param {number} version - The version number (current if omitted).
|
813 | * @param {object} data - The dictionary definition.
|
814 | * @returns {Promise} The reponse object.
|
815 | */
|
816 | async createDictionary(version, data) {
|
817 | return this.request.post(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/dictionary`, data);
|
818 | }
|
819 |
|
820 | /**
|
821 | * Update a dictionary for a particular service and version.
|
822 | *
|
823 | * @see https://docs.fastly.com/api/config#dictionary_8c9da370b1591d99e5389143a5589a32
|
824 | * @example
|
825 | * instance.updateDictionary('34', 'old-name', { name: 'new-name' })
|
826 | .then(res => {
|
827 | console.log(res.data);
|
828 | })
|
829 | .catch(err => {
|
830 | console.log(err.message);
|
831 | });
|
832 | * @param {string} version - The current version of a service.
|
833 | * @param {string} name - The name of the dictionary.
|
834 | * @param {object} data - The data to be sent as the request body.
|
835 | * @returns {Promise} The response object representing the completion or failure.
|
836 | */
|
837 | async updateDictionary(version, name, data) {
|
838 | return this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/dictionary/${encodeURIComponent(name)}`, data);
|
839 | }
|
840 |
|
841 | async writeDictionary(version, name, data) {
|
842 | try {
|
843 | const existing = await this.readDictionary(version, name);
|
844 | // keep the write-only status
|
845 | const mydata = {
|
846 | name: data.name,
|
847 | write_only: existing.data.write_only,
|
848 | };
|
849 | if (mydata.name && mydata.name !== existing.data.name) {
|
850 | return this.updateDictionary(version, name, mydata);
|
851 | }
|
852 | return existing;
|
853 | } catch (e) {
|
854 | return this.createDictionary(version, data);
|
855 | }
|
856 | }
|
857 |
|
858 | /**
|
859 | * Delete a dictionary for a particular service and version.
|
860 | *
|
861 | * @see https://docs.fastly.com/api/config#dictionary_8c9da370b1591d99e5389143a5589a32
|
862 | * @example
|
863 | * instance.deleteDictionary('34', 'extensions')
|
864 | .then(res => {
|
865 | console.log(res.data);
|
866 | })
|
867 | .catch(err => {
|
868 | console.log(err.message);
|
869 | });
|
870 | * @param {string} version - The current version of a service.
|
871 | * @param {string} name - The name of the dictionary.
|
872 | * @returns {Promise} The response object representing the completion or failure.
|
873 | */
|
874 | async deleteDictionary(version, name) {
|
875 | return this.request.delete(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/dictionary/${encodeURIComponent(name)}`);
|
876 | }
|
877 |
|
878 | /* ==CONDITIONS */
|
879 |
|
880 | /**
|
881 | * List all conditions for a particular service and version.
|
882 | *
|
883 | * @see https://docs.fastly.com/api/config#condition_b61196c572f473c89863a81cc5912861
|
884 | * @example
|
885 | * instance.readConditions('12')
|
886 | .then(res => {
|
887 | console.log(res.data);
|
888 | })
|
889 | .catch(err => {
|
890 | console.log(err.message);
|
891 | });
|
892 | * @param {string} version - The current version of a service.
|
893 | * @returns {Promise} The response object representing the completion or failure.
|
894 | */
|
895 | async readConditions(version) {
|
896 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/condition`);
|
897 | }
|
898 |
|
899 | /**
|
900 | * Get details of a single named condition.
|
901 | *
|
902 | * @see https://docs.fastly.com/api/config#condition_149a2f48485ceb335f70504e5269b77e
|
903 | * @example
|
904 | * instance.readCondition('12', 'returning')
|
905 | .then(res => {
|
906 | console.log(res.data);
|
907 | })
|
908 | .catch(err => {
|
909 | console.log(err.message);
|
910 | });
|
911 | * @param {string} version - The current version of a service.
|
912 | * @param {string} name - Name of the condition.
|
913 | * @returns {Promise} The response object representing the completion or failure.
|
914 | */
|
915 | async readCondition(version, name) {
|
916 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/condition/${name}`);
|
917 | }
|
918 |
|
919 | /**
|
920 | * Get details of a single named snippet.
|
921 | *
|
922 | * @see https://developer.fastly.com/reference/api/vcl-services/snippet/
|
923 | * @example
|
924 | * instance.readSnippet('12', 'returning')
|
925 | .then(res => {
|
926 | console.log(res.data);
|
927 | })
|
928 | .catch(err => {
|
929 | console.log(err.message);
|
930 | });
|
931 | * @param {string} version - The current version of a service.
|
932 | * @param {string} name - Name of the snippet.
|
933 | * @returns {Promise} The response object representing the completion or failure.
|
934 | */
|
935 | async readSnippet(version, name) {
|
936 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/snippet/${name}`);
|
937 | }
|
938 |
|
939 | /**
|
940 | * Create a new condition for a particular service and version.
|
941 | *
|
942 | * @see https://docs.fastly.com/api/config#condition_551199dbec2271195319b675d8659226
|
943 | * @param {number} version - The version number (current if omitted).
|
944 | * @param {object} data - The condition definition.
|
945 | * @returns {Promise} The reponse object.
|
946 | */
|
947 | async createCondition(version, data) {
|
948 | return this.request.post(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/condition`, data);
|
949 | }
|
950 |
|
951 | /**
|
952 | * Update a condition for a particular service and version.
|
953 | *
|
954 | * @see https://docs.fastly.com/api/config#condition_01a2c4e4b44943b541e001013b665deb
|
955 | * @example
|
956 | * instance.updateCondition('34', 'returning', { name: 'returning-visitor' })
|
957 | .then(res => {
|
958 | console.log(res.data);
|
959 | })
|
960 | .catch(err => {
|
961 | console.log(err.message);
|
962 | });
|
963 | * @param {string} version - The current version of a service.
|
964 | * @param {string} name - The name of the condition.
|
965 | * @param {object} data - The data to be sent as the request body.
|
966 | * @returns {Promise} The response object representing the completion or failure.
|
967 | */
|
968 | async updateCondition(version, name, data) {
|
969 | const mydata = { ...data };
|
970 | // cannot change type of condition
|
971 | delete mydata.type;
|
972 | return this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/condition/${encodeURIComponent(name)}`, data);
|
973 | }
|
974 |
|
975 | /**
|
976 | * Delete a condition for a particular service and version.
|
977 | *
|
978 | * @see https://docs.fastly.com/api/config#condition_2b902b7649c46b4541f00a920d06c94d
|
979 | * @example
|
980 | * instance.deleteCondition('34', 'extensions')
|
981 | .then(res => {
|
982 | console.log(res.data);
|
983 | })
|
984 | .catch(err => {
|
985 | console.log(err.message);
|
986 | });
|
987 | * @param {string} version - The current version of a service.
|
988 | * @param {string} name - The name of the condition.
|
989 | * @returns {Promise} The response object representing the completion or failure.
|
990 | */
|
991 | async deleteCondition(version, name) {
|
992 | return this.request.delete(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/condition/${encodeURIComponent(name)}`);
|
993 | }
|
994 |
|
995 | /* == HEADERS */
|
996 |
|
997 | /**
|
998 | * List all headers for a particular service and version.
|
999 | *
|
1000 | * @see https://docs.fastly.com/api/config#header_dd9da0592b2f1ff8ef0a4c1943f8abff
|
1001 | * @example
|
1002 | * instance.readHeaders('12')
|
1003 | .then(res => {
|
1004 | console.log(res.data);
|
1005 | })
|
1006 | .catch(err => {
|
1007 | console.log(err.message);
|
1008 | });
|
1009 | * @param {string} version - The current version of a service.
|
1010 | * @returns {Promise} The response object representing the completion or failure.
|
1011 | */
|
1012 | async readHeaders(version) {
|
1013 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/header`);
|
1014 | }
|
1015 |
|
1016 | /**
|
1017 | * Get details of a single named header.
|
1018 | *
|
1019 | * @see https://docs.fastly.com/api/config#header_86469e5eba4e5d6b1463e81f82a847e0
|
1020 | * @example
|
1021 | * instance.readHeader('12', 'returning')
|
1022 | .then(res => {
|
1023 | console.log(res.data);
|
1024 | })
|
1025 | .catch(err => {
|
1026 | console.log(err.message);
|
1027 | });
|
1028 | * @param {string} version - The current version of a service.
|
1029 | * @param {string} name - Name of the header.
|
1030 | * @returns {Promise} The response object representing the completion or failure.
|
1031 | */
|
1032 | async readHeader(version, name) {
|
1033 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/header/${name}`);
|
1034 | }
|
1035 |
|
1036 | /**
|
1037 | * Create a new header for a particular service and version.
|
1038 | *
|
1039 | * @see https://docs.fastly.com/api/config#header_151df4ce647a8e222e730b260287cb39
|
1040 | * @param {number} version - The version number (current if omitted).
|
1041 | * @param {object} data - The header definition.
|
1042 | * @returns {Promise} The reponse object.
|
1043 | */
|
1044 | async createHeader(version, data) {
|
1045 | return this.request.post(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/header`, data);
|
1046 | }
|
1047 |
|
1048 | /**
|
1049 | * Update a header for a particular service and version.
|
1050 | *
|
1051 | * @see https://docs.fastly.com/api/config#header_c4257a0fd0eb017ea47b1fbb318fd61c
|
1052 | * @example
|
1053 | * instance.updateHeader('34', 'returning', { name: 'returning-visitor' })
|
1054 | .then(res => {
|
1055 | console.log(res.data);
|
1056 | })
|
1057 | .catch(err => {
|
1058 | console.log(err.message);
|
1059 | });
|
1060 | * @param {string} version - The current version of a service.
|
1061 | * @param {string} name - The name of the header.
|
1062 | * @param {object} data - The data to be sent as the request body.
|
1063 | * @returns {Promise} The response object representing the completion or failure.
|
1064 | */
|
1065 | async updateHeader(version, name, data) {
|
1066 | return this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/header/${encodeURIComponent(name)}`, data);
|
1067 | }
|
1068 |
|
1069 | /**
|
1070 | * Delete a header for a particular service and version.
|
1071 | *
|
1072 | * @see https://docs.fastly.com/api/config#header_4bbb73fffda4d189bf5a19b474399a83
|
1073 | * @example
|
1074 | * instance.deleteHeader('34', 'extensions')
|
1075 | .then(res => {
|
1076 | console.log(res.data);
|
1077 | })
|
1078 | .catch(err => {
|
1079 | console.log(err.message);
|
1080 | });
|
1081 | * @param {string} version - The current version of a service.
|
1082 | * @param {string} name - The name of the header.
|
1083 | * @returns {Promise} The response object representing the completion or failure.
|
1084 | */
|
1085 | async deleteHeader(version, name) {
|
1086 | return this.request.delete(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/header/${encodeURIComponent(name)}`);
|
1087 | }
|
1088 |
|
1089 | /**
|
1090 | * List all backends for a particular service and version.
|
1091 | *
|
1092 | * @see https://docs.fastly.com/api/config#backend_fb0e875c9a7669f071cbf89ca32c7f69
|
1093 | * @example
|
1094 | * instance.readBackends('12')
|
1095 | .then(res => {
|
1096 | console.log(res.data);
|
1097 | })
|
1098 | .catch(err => {
|
1099 | console.log(err.message);
|
1100 | });
|
1101 | * @param {string} version - The current version of a service.
|
1102 | * @returns {Promise} The response object representing the completion or failure.
|
1103 | */
|
1104 | async readBackends(version) {
|
1105 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/backend`);
|
1106 | }
|
1107 |
|
1108 | /**
|
1109 | * Update the backend for a particular service and version.
|
1110 | *
|
1111 | * @see https://docs.fastly.com/api/config#backend_fb3b3529417c70f57458644f7aec652e
|
1112 | * @example
|
1113 | * instance.updateBackend('34', 'slow-server', { name: 'fast-server' })
|
1114 | .then(res => {
|
1115 | console.log(res.data);
|
1116 | })
|
1117 | .catch(err => {
|
1118 | console.log(err.message);
|
1119 | });
|
1120 | * @param {string} version - The current version of a service.
|
1121 | * @param {string} name - The name of the backend.
|
1122 | * @param {object} data - The data to be sent as the request body.
|
1123 | * @returns {Promise} The response object representing the completion or failure.
|
1124 | */
|
1125 | async updateBackend(version, name, data) {
|
1126 | return this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/backend/${encodeURIComponent(name)}`, data);
|
1127 | }
|
1128 |
|
1129 | /**
|
1130 | * Create a new backend for a particular service and version.
|
1131 | *
|
1132 | * @see https://docs.fastly.com/api/config#backend_85c170418ee71191dbb3b5046aeb6c2c
|
1133 | * @param {number} version - The version number (current if omitted).
|
1134 | * @param {object} data - The backend definition.
|
1135 | * @returns {Promise} The reponse object.
|
1136 | */
|
1137 | async createBackend(version, data) {
|
1138 | return this.request.post(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/backend`, data);
|
1139 | }
|
1140 | /**
|
1141 | * @typedef {object} Snippet
|
1142 | * @property {string} name The name of the snippet, as visible in the Fastly UI.
|
1143 | * @property {string} content The VCL body of the snippet.
|
1144 | */
|
1145 |
|
1146 | /**
|
1147 | * List all snippets for a particular service and version.
|
1148 | *
|
1149 | * @see https://docs.fastly.com/api/config#api-section-snippet
|
1150 | * @example
|
1151 | * instance.readSnippets('12')
|
1152 | .then(res => {
|
1153 | console.log(res.data);
|
1154 | })
|
1155 | .catch(err => {
|
1156 | console.log(err.message);
|
1157 | });
|
1158 | * @param {string} version - The current version of a service.
|
1159 | * @returns {Promise} The response object representing the completion or failure.
|
1160 | */
|
1161 | async readSnippets(version) {
|
1162 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/snippet`);
|
1163 | }
|
1164 |
|
1165 | /**
|
1166 | * Create a snippet for a particular service and version.
|
1167 | *
|
1168 | * @see https://docs.fastly.com/api/config#snippet_41e0e11c662d4d56adada215e707f30d
|
1169 | * @example
|
1170 | * instance.createSnippet('36', {
|
1171 | name: 'your_snippet',
|
1172 | priority: 10,
|
1173 | dynamic: 1,
|
1174 | content: 'table referer_blacklist {}',
|
1175 | type: 'init'
|
1176 | })
|
1177 | .then(res => {
|
1178 | console.log(res.data);
|
1179 | })
|
1180 | .catch(err => {
|
1181 | console.log(err.message);
|
1182 | });
|
1183 | * @param {string} version - The current version of a service.
|
1184 | * @param {Snippet} data - The data to be sent as the request body.
|
1185 | * @returns {Promise} The response object representing the completion or failure.
|
1186 | */
|
1187 | async createSnippet(version, data) {
|
1188 | return this.request.post(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/snippet`, data);
|
1189 | }
|
1190 |
|
1191 | /**
|
1192 | * Update a VCL snippet for a particular service and version.
|
1193 | *
|
1194 | * @param {string} version - The current version of a service.
|
1195 | * @param {string} name - The name of the snippet to update.
|
1196 | * @param {Snippet} data - The data to be sent as the request body.
|
1197 | * @returns {Promise} The response object representing the completion or failure.
|
1198 | */
|
1199 | async updateSnippet(version, name, data) {
|
1200 | const mydata = { ...data };
|
1201 | delete mydata.type;
|
1202 | return this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/snippet/${name}`, mydata);
|
1203 | }
|
1204 |
|
1205 | /**
|
1206 | * @typedef {object} VCL
|
1207 | * @property {string} name The name of the VCL, as visible in the Fastly UI.
|
1208 | * Note: setting the name to 'main' here won't make it the main VCL,
|
1209 | * unless you also call `setMainVCL`.
|
1210 | * @property {string} content The VCL body of the custom VCL.
|
1211 | */
|
1212 |
|
1213 | /**
|
1214 | * Create custom VCL for a particular service and version.
|
1215 | *
|
1216 | * @see https://docs.fastly.com/api/config#vcl_7ade6ab5926b903b6acf3335a85060cc
|
1217 | * @param {string} version - The current version of a service.
|
1218 | * @param {VCL} data - The data to be sent as the request body.
|
1219 | * @returns {Promise} The response object representing the completion or failure.
|
1220 | */
|
1221 | async createVCL(version, data) {
|
1222 | return this.request.post(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/vcl`, data);
|
1223 | }
|
1224 |
|
1225 | /**
|
1226 | * Update custom VCL for a particular service and version.
|
1227 | *
|
1228 | * @see https://docs.fastly.com/api/config#vcl_0971365908e17086751c5ef2a8053087
|
1229 | * @param {string} version - The current version of a service.
|
1230 | * @param {string} name - The name of the VCL to update.
|
1231 | * @param {VCL} data - The data to be sent as the request body.
|
1232 | * @returns {Promise} The response object representing the completion or failure.
|
1233 | */
|
1234 | async updateVCL(version, name, data) {
|
1235 | if (typeof name === 'object') {
|
1236 | /* eslint-disable no-param-reassign */
|
1237 | data = name;
|
1238 | name = data.name;
|
1239 | /* eslint-enable no-param-reassign */
|
1240 | }
|
1241 | return this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/vcl/${name}`, data);
|
1242 | }
|
1243 |
|
1244 | /**
|
1245 | * Define a custom VCL to be the main VCL for a particular service and version.
|
1246 | *
|
1247 | * @see https://docs.fastly.com/api/config#vcl_5576c38e7652f5a7261bfcad41c0faf1
|
1248 | * @param {string} version - The current version of a service.
|
1249 | * @param {string} name - The name of the VCL to declare main.
|
1250 | * @returns {Promise} The response object representing the completion or failure.
|
1251 | */
|
1252 | async setMainVCL(version, name) {
|
1253 | return this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/vcl/${name}/main`, {});
|
1254 | }
|
1255 |
|
1256 | /**
|
1257 | * Creates a new version, runs the function `operations` and then
|
1258 | * optionally activates the newly created version. This function
|
1259 | * is useful for making modifications to a service config.
|
1260 | *
|
1261 | * You can provide a `limit` of write operations, which is an estimate
|
1262 | * of the number of write operations that will be attempted. If the
|
1263 | * limit is higher than the number of actions allowed by Fastly's rate
|
1264 | * limits, the function will fail fast after cloning the service config.
|
1265 | *
|
1266 | * @example
|
1267 | * ```javascript
|
1268 | * await fastly.transact(async (newversion) => {
|
1269 | * await fastly.doSomething(newversion);
|
1270 | * });
|
1271 | * // new version has been activated
|
1272 | * ```
|
1273 | * @param {Function} operations - A function that performs changes on the service config.
|
1274 | * @param {boolean} activate - Set to false to prevent automatic activation.
|
1275 | * @param {number} limit - Number of write operations that will be performed in this action.
|
1276 | * @returns {object} The return value of the wrapped function.
|
1277 | */
|
1278 | async transact(operations, activate = true, limit = 0) {
|
1279 | const newversion = (await this.cloneVersion()).data.number;
|
1280 | if (limit > 0 && this.requestmonitor.remaining && this.requestmonitor.remaining < limit) {
|
1281 | throw new RateLimitError(`Insufficient number of requests (${this.requestmonitor.remaining}) remaining for number of scheduled operations (${limit})`);
|
1282 | }
|
1283 | const result = await operations.apply(this, [newversion]);
|
1284 | if (activate) {
|
1285 | await this.activateVersion(newversion);
|
1286 | }
|
1287 | return result;
|
1288 | }
|
1289 |
|
1290 | /**
|
1291 | * See `transact`, but this version does not activate the created version.
|
1292 | *
|
1293 | * @see #transact
|
1294 | * @param {Function} operations - The operations that should be applied to the
|
1295 | * cloned service config version.
|
1296 | * @returns {object} Whatever `operations` returns.
|
1297 | */
|
1298 | async dryrun(operations) {
|
1299 | return this.transact(operations, false);
|
1300 | }
|
1301 | }
|
1302 |
|
1303 | /**
|
1304 | * Function to create a new fastly-promises instance.
|
1305 | *
|
1306 | * @param {string} token - The Fastly API token.
|
1307 | * @param {string} service_id - The Fastly service ID.
|
1308 | * @returns {Fastly} The exported module.
|
1309 | */
|
1310 | module.exports = (token, service_id) => new Fastly(token, service_id);
|