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);
|
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 |
|
324 | /**
|
325 | * @typedef {object} FastlyError
|
326 | * The FastlyError class describes the most common errors that can occur
|
327 | * when working with the Fastly API. Using `error.status`, the underlying
|
328 | * HTTP status code can be retrieved. Known error status codes include:
|
329 | * - 400: attempting to activate invalid VCL
|
330 | * - 401: invalid credentials
|
331 | * - 404: resource not found
|
332 | * - 409: confict when trying to POST a resource that already exists
|
333 | * - 422: attempting to modify a service config that is not checked out
|
334 | * - 429: rate limit exceeded, try again later
|
335 | * @property {number} status The HTTP status code from the server response, e.g. 200.
|
336 | * @property {object} data The parsed body of the HTTP response.
|
337 | * @property {string} code A short error message.
|
338 | * @property {string} message A more detailed error message.
|
339 | */
|
340 |
|
341 | /**
|
342 | * @typedef {object} Response
|
343 | * @property {number} status The HTTP status code from the server response, e.g. 200.
|
344 | * @property {string} statusText The HTTP status text, e.g. 'OK'.
|
345 | * @property {object} headers The HTTP headers of the reponse.
|
346 | * @property {object} config The original request configuration used for the HTTP client.
|
347 | * @property {object} request The HTTP request.
|
348 | * @property {object} data The parsed body of the HTTP response.
|
349 | */
|
350 |
|
351 | /**
|
352 | * Get a list of all Fastly datacenters.
|
353 | *
|
354 | * @see https://docs.fastly.com/api/tools#datacenter_1c8d3b9dd035e301155b44eae05e0554
|
355 | * @example
|
356 | * instance.dataCenters()
|
357 | .then(res => {
|
358 | console.log(res.data);
|
359 | })
|
360 | .catch(err => {
|
361 | console.log(err.message);
|
362 | });
|
363 | * @returns {Promise} The response object representing the completion or failure.
|
364 | */
|
365 | dataCenters() {
|
366 | return this.request.get('/datacenters');
|
367 | }
|
368 |
|
369 | /**
|
370 | * Fastly's services IP ranges.
|
371 | *
|
372 | * @see https://docs.fastly.com/api/tools#public_ip_list_ef2e9900a1c9522b58f5abed92ec785e
|
373 | * @example
|
374 | * instance.publicIpList()
|
375 | .then(res => {
|
376 | console.log(res.data);
|
377 | })
|
378 | .catch(err => {
|
379 | console.log(err.message);
|
380 | });
|
381 | * @returns {Promise} The response object representing the completion or failure.
|
382 | */
|
383 | publicIpList() {
|
384 | return this.request.get('/public-ip-list');
|
385 | }
|
386 |
|
387 | /**
|
388 | * Retrieve headers and MD5 hash of the content for a particular URL from each Fastly edge server.
|
389 | *
|
390 | * @see https://docs.fastly.com/api/tools#content_4d2d4548b29c7661e17ebe7098872d6d
|
391 | * @example
|
392 | * instance.edgeCheck('api.example.com')
|
393 | .then(res => {
|
394 | console.log(res.data);
|
395 | })
|
396 | .catch(err => {
|
397 | console.log(err.message);
|
398 | });
|
399 | * @param {string} url - Full URL (host and path) to check on all nodes. If protocol is omitted,
|
400 | http will be assumed.
|
401 | * @returns {Promise} The response object representing the completion or failure.
|
402 | */
|
403 | edgeCheck(url = '') {
|
404 | return this.request.get(`/content/edge_check?url=${url}`);
|
405 | }
|
406 |
|
407 | /**
|
408 | * List all services.
|
409 | *
|
410 | * @see https://docs.fastly.com/api/config#service_74d98f7e5d018256e44d1cf820388ef8
|
411 | * @example
|
412 | * instance.readServices()
|
413 | .then(res => {
|
414 | console.log(res.data);
|
415 | })
|
416 | .catch(err => {
|
417 | console.log(err.message);
|
418 | });
|
419 | * @returns {Promise} The response object representing the completion or failure.
|
420 | */
|
421 | readServices() {
|
422 | return this.request.get('/service');
|
423 | }
|
424 |
|
425 | /**
|
426 | * Reads the services and returns a data object that contains a map where the service id is
|
427 | * the key.
|
428 | *
|
429 | * @returns {Promise} The response object representing the completion or failure.
|
430 | */
|
431 | async readServicesById() {
|
432 | const ret = await this.request.get('/service');
|
433 | ret.data = ret.data.reduce((dat, service) => Object.assign(dat, { [service.id]: service }), {});
|
434 | return ret;
|
435 | }
|
436 |
|
437 | /**
|
438 | * Get a specific service by id.
|
439 | *
|
440 | * @see https://docs.fastly.com/api/config#service_a884a9abd5af9723f6fcbb1ed13ae4cc
|
441 | * @param {string} [serviceId] - The service id.
|
442 | * @returns {Promise} The response object representing the completion or failure.
|
443 | */
|
444 | async readService(serviceId = this.service_id) {
|
445 | return this.request.get(`/service/${serviceId}`);
|
446 | }
|
447 |
|
448 | /**
|
449 | * List the versions for a particular service.
|
450 | *
|
451 | * @see https://docs.fastly.com/api/config#version_dfde9093f4eb0aa2497bbfd1d9415987
|
452 | * @example
|
453 | * instance.readVersions()
|
454 | .then(res => {
|
455 | const active = res.data.filter(version => version.active);
|
456 | console.log(active);
|
457 | })
|
458 | .catch(err => {
|
459 | console.log(err.message);
|
460 | });
|
461 | * @returns {Promise} The response object representing the completion or failure.
|
462 | */
|
463 | readVersions() {
|
464 | return this.request.get(`/service/${this.service_id}/version`);
|
465 | }
|
466 |
|
467 | /**
|
468 | * @typedef {object} Versions
|
469 | *
|
470 | * Describes the most relevant versions of the service.
|
471 | *
|
472 | * @property {number} latest - The latest version of the service.
|
473 | * @property {number} active - The currently active version number.
|
474 | * @property {number} current - The latest editable version number.
|
475 | */
|
476 | /**
|
477 | * Gets the version footprint for the service.
|
478 | *
|
479 | * @returns {Versions} The latest, current, and active versions of the service.
|
480 | */
|
481 | async getVersions() {
|
482 | if (this.versions.latest) {
|
483 | return this.versions;
|
484 | }
|
485 | const { data } = await this.readVersions();
|
486 | this.versions.initial = 1;
|
487 | this.versions.latest = data
|
488 | .map(({ number }) => number)
|
489 | .pop();
|
490 | this.versions.active = data
|
491 | .filter((version) => version.active)
|
492 | .map(({ number }) => number)
|
493 | .pop();
|
494 | this.versions.current = data
|
495 | .filter((version) => !version.locked)
|
496 | .map(({ number }) => number)
|
497 | .pop();
|
498 |
|
499 | return this.versions;
|
500 | }
|
501 |
|
502 | async getVersion(version, ...fallbackname) {
|
503 | if (version) {
|
504 | return version;
|
505 | }
|
506 | const versions = await this.getVersions();
|
507 | return fallbackname.map((attempt) => versions[attempt]).filter((e) => e)[0];
|
508 | }
|
509 |
|
510 | /**
|
511 | * Clone the current configuration into a new version.
|
512 | *
|
513 | * @param {string} version - The version to be cloned.
|
514 | * @see https://docs.fastly.com/api/config#version_7f4937d0663a27fbb765820d4c76c709
|
515 | * @example
|
516 | * instance.cloneVersion('45')
|
517 | .then(res => {
|
518 | console.log(res.data);
|
519 | })
|
520 | .catch(err => {
|
521 | console.log(err.message);
|
522 | });
|
523 | * @returns {Promise} The response object representing the completion or failure.
|
524 | */
|
525 | async cloneVersion(version) {
|
526 | const versions = await this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'active', 'current', 'latest', 'initial')}/clone`);
|
527 | this.versions.current = versions.data.number;
|
528 | this.versions.latest = versions.data.number;
|
529 | return versions;
|
530 | }
|
531 |
|
532 | /**
|
533 | * Activate the current version.
|
534 | *
|
535 | * @param {string} version - The version to be activated.
|
536 | * @see https://docs.fastly.com/api/config#version_0b79ae1ba6aee61d64cc4d43fed1e0d5
|
537 | * @example
|
538 | * instance.activateVersion('23')
|
539 | .then(res => {
|
540 | console.log(res.data);
|
541 | })
|
542 | .catch(err => {
|
543 | console.log(err.message);
|
544 | });
|
545 | * @returns {Promise} The response object representing the completion or failure.
|
546 | */
|
547 | async activateVersion(version) {
|
548 | const versions = await this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/activate`);
|
549 | this.versions.active = versions.data.number;
|
550 | this.versions.latest = versions.data.number;
|
551 | return versions;
|
552 | }
|
553 |
|
554 | // === start ===
|
555 |
|
556 | /**
|
557 | * List all dictionary items for a particular service and version.
|
558 | *
|
559 | * @see https://docs.fastly.com/api/config#dictionary_item_a48de28cd7e76c1ea58523f39bb7204b
|
560 | * @example
|
561 | * instance.readDictItems(1, 'my_dictionary')
|
562 | .then(res => {
|
563 | console.log(res.data);
|
564 | })
|
565 | .catch(err => {
|
566 | console.log(err.message);
|
567 | });
|
568 | * @param {string} version - The version of the dictionary.
|
569 | * @param {string} name - The name of the dictionary.
|
570 | * @returns {Promise} The response object representing the completion or failure.
|
571 | */
|
572 | async readDictItems(version, name) {
|
573 | return this.readDictionary(
|
574 | await this.getVersion(version, 'latest'),
|
575 | name,
|
576 | ).then(({ data }) => this.request.get(`/service/${this.service_id}/dictionary/${data.id}/items`));
|
577 | }
|
578 |
|
579 | /**
|
580 | * Get details of a single dictionary item.
|
581 | *
|
582 | * @see https://docs.fastly.com/api/config#dictionary_item_08f090cd03ed4602ae63f131087e2f29
|
583 | * @example
|
584 | * instance.readDictItem('12', 'extensions', 'some_key')
|
585 | .then(res => {
|
586 | console.log(res.data);
|
587 | })
|
588 | .catch(err => {
|
589 | console.log(err.message);
|
590 | });
|
591 | * @param {string} version - The current version of a service.
|
592 | * @param {string} name - Name of the dictionary.
|
593 | * @param {string} key - The key to retrieve values by.
|
594 | * @returns {Promise} The response object representing the completion or failure.
|
595 | */
|
596 | async readDictItem(version, name, key) {
|
597 | return this.readDictionary(
|
598 | await this.getVersion(version, 'latest'),
|
599 | name,
|
600 | ).then(({ data }) => {
|
601 | if (data.write_only) {
|
602 | return {
|
603 | status: 403, // not permitted to read from write-only dicts
|
604 | data: {
|
605 | dictionary_id: data.id,
|
606 | service_id: this.service_id,
|
607 | item_key: key,
|
608 | item_value: undefined,
|
609 | created_at: undefined,
|
610 | deleted_at: undefined,
|
611 | updated_at: undefined,
|
612 | },
|
613 | };
|
614 | }
|
615 | // always use uncached version here
|
616 | return this.request.get.fresh(`/service/${this.service_id}/dictionary/${data.id}/item/${encodeURIComponent(key)}`);
|
617 | });
|
618 | }
|
619 |
|
620 | /**
|
621 | * Create a new dictionary item for a particular service and version.
|
622 | *
|
623 | * @see https://docs.fastly.com/api/config#dictionary_item_6ec455c0ba1b21671789e1362bc7fe55
|
624 | * @param {number} version - The version number (current if omitted).
|
625 | * @param {object} name - The dictionary definition.
|
626 | * @param {string} key - The key.
|
627 | * @param {string} value - The value to write.
|
628 | * @returns {Promise} The reponse object.
|
629 | */
|
630 | async createDictItem(version, name, key, value) {
|
631 | return this.readDictionary(
|
632 | await this.getVersion(version, 'latest'),
|
633 | name,
|
634 | ).then(({ data }) => this.request.post(`/service/${this.service_id}/dictionary/${data.id}/item`, {
|
635 | item_key: key,
|
636 | item_value: value,
|
637 | }));
|
638 | }
|
639 |
|
640 | /**
|
641 | * @typedef {object} DictUpdate
|
642 | * Specifies a dictionary update operation. In most cases, `upsert` is the best way
|
643 | * to update values, as it will work for existing and non-existing items.
|
644 | * @property {string} op - The operation: `create`, `update`, `delete`, or `upsert`.
|
645 | * @property {string} item_key - The lookup key.
|
646 | * @property {string} item_value - The dictionary value.
|
647 | */
|
648 | /**
|
649 | * Updates multiple dictionary items in bulk.
|
650 | *
|
651 | * @param {number} version - The version numer (current if ommitted).
|
652 | * @param {string} name - Name of the dictionary.
|
653 | * @param {...DictUpdate} items - The dictionary update operations.
|
654 | * @returns {Promise} The response object.
|
655 | * @example
|
656 | * // single item
|
657 | * fastly.bulkUpdateDictItems(1, 'secret_dictionary',
|
658 | * { item_key: 'some_key', item_value: 'some_value', op: 'upsert' });
|
659 | *
|
660 | * // multiple items
|
661 | * fastly.bulkUpdateDictItems(1, 'secret_dictionary',
|
662 | * { item_key: 'some_key', item_value: 'some_value', op: 'update' },
|
663 | * { item_key: 'other_key', item_value: 'other_value', op: 'update' });
|
664 | */
|
665 | async bulkUpdateDictItems(version, name, ...items) {
|
666 | return this.readDictionary(
|
667 | await this.getVersion(version, 'latest'),
|
668 | name,
|
669 | ).then(({ data }) => this.request.patch(`/service/${this.service_id}/dictionary/${data.id}/items`, {
|
670 | items,
|
671 | }));
|
672 | }
|
673 |
|
674 | /**
|
675 | * Update a dictionary item value for a particular service and version.
|
676 | *
|
677 | * @see https://docs.fastly.com/api/config#dictionary_item_34c884a7cdce84dfcfd38dac7a0b5bb0
|
678 | * @example
|
679 | * instance.updateDictItem(1, 'extensions', 'html', 'text/html')
|
680 | .then(res => {
|
681 | console.log(res.data);
|
682 | })
|
683 | .catch(err => {
|
684 | console.log(err.message);
|
685 | });
|
686 | * @param {string} version - The current version of a service.
|
687 | * @param {string} name - The name of the dictionary.
|
688 | * @param {string} key - The key to update data under.
|
689 | * @param {string} value - The value to update the dictionary with.
|
690 | * @returns {Promise} The response object representing the completion or failure.
|
691 | */
|
692 | async updateDictItem(version, name, key, value) {
|
693 | return this.readDictionary(
|
694 | await this.getVersion(version, 'latest'),
|
695 | name,
|
696 | ).then(({ data }) => this.request.put(`/service/${this.service_id}/dictionary/${data.id}/item/${encodeURIComponent(key)}`, {
|
697 | item_value: value,
|
698 | }));
|
699 | }
|
700 |
|
701 | /**
|
702 | * Delete a dictionary item for a particular service and version.
|
703 | *
|
704 | * @see https://docs.fastly.com/api/config#dictionary_item_664347e743b8eafc9a93c729d9da0427
|
705 | * @example
|
706 | * instance.deleteDictItem('34', 'extensions', 'html')
|
707 | .then(res => {
|
708 | console.log(res.data);
|
709 | })
|
710 | .catch(err => {
|
711 | console.log(err.message);
|
712 | });
|
713 | * @param {string} version - The current version of a service.
|
714 | * @param {string} name - The name of the dictionary.
|
715 | * @param {string} key - The key to update data under.
|
716 | * @returns {Promise} The response object representing the completion or failure.
|
717 | */
|
718 | async deleteDictItem(version, name, key) {
|
719 | return this.readDictionary(
|
720 | await this.getVersion(version, 'latest'),
|
721 | name,
|
722 | ).then(({ data }) => this.request.delete(`/service/${this.service_id}/dictionary/${data.id}/item/${encodeURIComponent(key)}`));
|
723 | }
|
724 |
|
725 | /**
|
726 | * Safely create, update or delete a dictionary item in a named dictionary.
|
727 | *
|
728 | * @param {number} version - Service version to use for dictionary lookup.
|
729 | * @param {string} name - Name of the dictionary (not ID).
|
730 | * @param {string} key - Key to create, update or delete.
|
731 | * @param {string} value - Value to update. Empty strings will delete the dictionary entry.
|
732 | * @returns {Promise} The response object representing the completion or failure.
|
733 | */
|
734 | writeDictItem(version, name, key, value) {
|
735 | return this.readDictItem(version, name, key)
|
736 | .then(() => {
|
737 | // the dictionary item already exists
|
738 | if (value) {
|
739 | // update existing value
|
740 | return this.updateDictItem(version, name, key, value);
|
741 | }
|
742 | // value is undefined. Fastly does not support overwriting with empty
|
743 | // values, so we delete the value
|
744 | return this.deleteDictItem(version, name, key);
|
745 | })
|
746 | .catch(() => {
|
747 | // the dictionary item does not exist
|
748 | if (value) {
|
749 | return this.createDictItem(version, name, key, value);
|
750 | }
|
751 | // the item does not exist and there is no data to write, we just pretend it went ok
|
752 | return {
|
753 | status: 200,
|
754 | data: {
|
755 | status: 'ok',
|
756 | },
|
757 | };
|
758 | });
|
759 | }
|
760 |
|
761 | // === done ===
|
762 |
|
763 | /**
|
764 | * List all dictionaries for a particular service and version.
|
765 | *
|
766 | * @see https://docs.fastly.com/api/config#dictionary_6d2cc293b994eb8c16d93e92e91f3915
|
767 | * @example
|
768 | * instance.readDictionaries('12')
|
769 | .then(res => {
|
770 | console.log(res.data);
|
771 | })
|
772 | .catch(err => {
|
773 | console.log(err.message);
|
774 | });
|
775 | * @param {string} version - The current version of a service.
|
776 | * @returns {Promise} The response object representing the completion or failure.
|
777 | */
|
778 | async readDictionaries(version) {
|
779 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/dictionary`);
|
780 | }
|
781 |
|
782 | /**
|
783 | * Get details of a single dictionary.
|
784 | *
|
785 | * @see https://docs.fastly.com/api/config#dictionary_0e16df083830ed3b6c30b73dcef64014
|
786 | * @example
|
787 | * instance.readDictionary('12', 'extensions')
|
788 | .then(res => {
|
789 | console.log(res.data);
|
790 | })
|
791 | .catch(err => {
|
792 | console.log(err.message);
|
793 | });
|
794 | * @param {string} version - The current version of a service.
|
795 | * @param {string} name - Name of the dictionary.
|
796 | * @returns {Promise} The response object representing the completion or failure.
|
797 | */
|
798 | async readDictionary(version, name) {
|
799 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/dictionary/${name}`);
|
800 | }
|
801 |
|
802 | /**
|
803 | * Create a new dictionary for a particular service and version.
|
804 | *
|
805 | * @see https://docs.fastly.com/api/config#dictionary_7d48b87bf82433162a3b209292722125
|
806 | * @param {number} version - The version number (current if omitted).
|
807 | * @param {object} data - The dictionary definition.
|
808 | * @returns {Promise} The reponse object.
|
809 | */
|
810 | async createDictionary(version, data) {
|
811 | return this.request.post(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/dictionary`, data);
|
812 | }
|
813 |
|
814 | /**
|
815 | * Update a dictionary for a particular service and version.
|
816 | *
|
817 | * @see https://docs.fastly.com/api/config#dictionary_8c9da370b1591d99e5389143a5589a32
|
818 | * @example
|
819 | * instance.updateDictionary('34', 'old-name', { name: 'new-name' })
|
820 | .then(res => {
|
821 | console.log(res.data);
|
822 | })
|
823 | .catch(err => {
|
824 | console.log(err.message);
|
825 | });
|
826 | * @param {string} version - The current version of a service.
|
827 | * @param {string} name - The name of the dictionary.
|
828 | * @param {object} data - The data to be sent as the request body.
|
829 | * @returns {Promise} The response object representing the completion or failure.
|
830 | */
|
831 | async updateDictionary(version, name, data) {
|
832 | return this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/dictionary/${encodeURIComponent(name)}`, data);
|
833 | }
|
834 |
|
835 | async writeDictionary(version, name, data) {
|
836 | try {
|
837 | const existing = await this.readDictionary(version, name);
|
838 | // keep the write-only status
|
839 | const mydata = {
|
840 | name: data.name,
|
841 | write_only: existing.data.write_only,
|
842 | };
|
843 | if (mydata.name && mydata.name !== existing.data.name) {
|
844 | return this.updateDictionary(version, name, mydata);
|
845 | }
|
846 | return existing;
|
847 | } catch (e) {
|
848 | return this.createDictionary(version, data);
|
849 | }
|
850 | }
|
851 |
|
852 | /**
|
853 | * Delete a dictionary for a particular service and version.
|
854 | *
|
855 | * @see https://docs.fastly.com/api/config#dictionary_8c9da370b1591d99e5389143a5589a32
|
856 | * @example
|
857 | * instance.deleteDictionary('34', 'extensions')
|
858 | .then(res => {
|
859 | console.log(res.data);
|
860 | })
|
861 | .catch(err => {
|
862 | console.log(err.message);
|
863 | });
|
864 | * @param {string} version - The current version of a service.
|
865 | * @param {string} name - The name of the dictionary.
|
866 | * @returns {Promise} The response object representing the completion or failure.
|
867 | */
|
868 | async deleteDictionary(version, name) {
|
869 | return this.request.delete(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/dictionary/${encodeURIComponent(name)}`);
|
870 | }
|
871 |
|
872 | /* ==CONDITIONS */
|
873 |
|
874 | /**
|
875 | * List all conditions for a particular service and version.
|
876 | *
|
877 | * @see https://docs.fastly.com/api/config#condition_b61196c572f473c89863a81cc5912861
|
878 | * @example
|
879 | * instance.readConditions('12')
|
880 | .then(res => {
|
881 | console.log(res.data);
|
882 | })
|
883 | .catch(err => {
|
884 | console.log(err.message);
|
885 | });
|
886 | * @param {string} version - The current version of a service.
|
887 | * @returns {Promise} The response object representing the completion or failure.
|
888 | */
|
889 | async readConditions(version) {
|
890 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/condition`);
|
891 | }
|
892 |
|
893 | /**
|
894 | * Get details of a single named condition.
|
895 | *
|
896 | * @see https://docs.fastly.com/api/config#condition_149a2f48485ceb335f70504e5269b77e
|
897 | * @example
|
898 | * instance.readCondition('12', 'returning')
|
899 | .then(res => {
|
900 | console.log(res.data);
|
901 | })
|
902 | .catch(err => {
|
903 | console.log(err.message);
|
904 | });
|
905 | * @param {string} version - The current version of a service.
|
906 | * @param {string} name - Name of the condition.
|
907 | * @returns {Promise} The response object representing the completion or failure.
|
908 | */
|
909 | async readCondition(version, name) {
|
910 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/condition/${name}`);
|
911 | }
|
912 |
|
913 | /**
|
914 | * Create a new condition for a particular service and version.
|
915 | *
|
916 | * @see https://docs.fastly.com/api/config#condition_551199dbec2271195319b675d8659226
|
917 | * @param {number} version - The version number (current if omitted).
|
918 | * @param {object} data - The condition definition.
|
919 | * @returns {Promise} The reponse object.
|
920 | */
|
921 | async createCondition(version, data) {
|
922 | return this.request.post(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/condition`, data);
|
923 | }
|
924 |
|
925 | /**
|
926 | * Update a condition for a particular service and version.
|
927 | *
|
928 | * @see https://docs.fastly.com/api/config#condition_01a2c4e4b44943b541e001013b665deb
|
929 | * @example
|
930 | * instance.updateCondition('34', 'returning', { name: 'returning-visitor' })
|
931 | .then(res => {
|
932 | console.log(res.data);
|
933 | })
|
934 | .catch(err => {
|
935 | console.log(err.message);
|
936 | });
|
937 | * @param {string} version - The current version of a service.
|
938 | * @param {string} name - The name of the condition.
|
939 | * @param {object} data - The data to be sent as the request body.
|
940 | * @returns {Promise} The response object representing the completion or failure.
|
941 | */
|
942 | async updateCondition(version, name, data) {
|
943 | return this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/condition/${encodeURIComponent(name)}`, data);
|
944 | }
|
945 |
|
946 | /**
|
947 | * Delete a condition for a particular service and version.
|
948 | *
|
949 | * @see https://docs.fastly.com/api/config#condition_2b902b7649c46b4541f00a920d06c94d
|
950 | * @example
|
951 | * instance.deleteCondition('34', 'extensions')
|
952 | .then(res => {
|
953 | console.log(res.data);
|
954 | })
|
955 | .catch(err => {
|
956 | console.log(err.message);
|
957 | });
|
958 | * @param {string} version - The current version of a service.
|
959 | * @param {string} name - The name of the condition.
|
960 | * @returns {Promise} The response object representing the completion or failure.
|
961 | */
|
962 | async deleteCondition(version, name) {
|
963 | return this.request.delete(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/condition/${encodeURIComponent(name)}`);
|
964 | }
|
965 |
|
966 | /* == HEADERS */
|
967 |
|
968 | /**
|
969 | * List all headers for a particular service and version.
|
970 | *
|
971 | * @see https://docs.fastly.com/api/config#header_dd9da0592b2f1ff8ef0a4c1943f8abff
|
972 | * @example
|
973 | * instance.readHeaders('12')
|
974 | .then(res => {
|
975 | console.log(res.data);
|
976 | })
|
977 | .catch(err => {
|
978 | console.log(err.message);
|
979 | });
|
980 | * @param {string} version - The current version of a service.
|
981 | * @returns {Promise} The response object representing the completion or failure.
|
982 | */
|
983 | async readHeaders(version) {
|
984 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/header`);
|
985 | }
|
986 |
|
987 | /**
|
988 | * Get details of a single named header.
|
989 | *
|
990 | * @see https://docs.fastly.com/api/config#header_86469e5eba4e5d6b1463e81f82a847e0
|
991 | * @example
|
992 | * instance.readHeader('12', 'returning')
|
993 | .then(res => {
|
994 | console.log(res.data);
|
995 | })
|
996 | .catch(err => {
|
997 | console.log(err.message);
|
998 | });
|
999 | * @param {string} version - The current version of a service.
|
1000 | * @param {string} name - Name of the header.
|
1001 | * @returns {Promise} The response object representing the completion or failure.
|
1002 | */
|
1003 | async readHeader(version, name) {
|
1004 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/header/${name}`);
|
1005 | }
|
1006 |
|
1007 | /**
|
1008 | * Create a new header for a particular service and version.
|
1009 | *
|
1010 | * @see https://docs.fastly.com/api/config#header_151df4ce647a8e222e730b260287cb39
|
1011 | * @param {number} version - The version number (current if omitted).
|
1012 | * @param {object} data - The header definition.
|
1013 | * @returns {Promise} The reponse object.
|
1014 | */
|
1015 | async createHeader(version, data) {
|
1016 | return this.request.post(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/header`, data);
|
1017 | }
|
1018 |
|
1019 | /**
|
1020 | * Update a header for a particular service and version.
|
1021 | *
|
1022 | * @see https://docs.fastly.com/api/config#header_c4257a0fd0eb017ea47b1fbb318fd61c
|
1023 | * @example
|
1024 | * instance.updateHeader('34', 'returning', { name: 'returning-visitor' })
|
1025 | .then(res => {
|
1026 | console.log(res.data);
|
1027 | })
|
1028 | .catch(err => {
|
1029 | console.log(err.message);
|
1030 | });
|
1031 | * @param {string} version - The current version of a service.
|
1032 | * @param {string} name - The name of the header.
|
1033 | * @param {object} data - The data to be sent as the request body.
|
1034 | * @returns {Promise} The response object representing the completion or failure.
|
1035 | */
|
1036 | async updateHeader(version, name, data) {
|
1037 | return this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/header/${encodeURIComponent(name)}`, data);
|
1038 | }
|
1039 |
|
1040 | /**
|
1041 | * Delete a header for a particular service and version.
|
1042 | *
|
1043 | * @see https://docs.fastly.com/api/config#header_4bbb73fffda4d189bf5a19b474399a83
|
1044 | * @example
|
1045 | * instance.deleteHeader('34', 'extensions')
|
1046 | .then(res => {
|
1047 | console.log(res.data);
|
1048 | })
|
1049 | .catch(err => {
|
1050 | console.log(err.message);
|
1051 | });
|
1052 | * @param {string} version - The current version of a service.
|
1053 | * @param {string} name - The name of the header.
|
1054 | * @returns {Promise} The response object representing the completion or failure.
|
1055 | */
|
1056 | async deleteHeader(version, name) {
|
1057 | return this.request.delete(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/header/${encodeURIComponent(name)}`);
|
1058 | }
|
1059 |
|
1060 | /**
|
1061 | * List all backends for a particular service and version.
|
1062 | *
|
1063 | * @see https://docs.fastly.com/api/config#backend_fb0e875c9a7669f071cbf89ca32c7f69
|
1064 | * @example
|
1065 | * instance.readBackends('12')
|
1066 | .then(res => {
|
1067 | console.log(res.data);
|
1068 | })
|
1069 | .catch(err => {
|
1070 | console.log(err.message);
|
1071 | });
|
1072 | * @param {string} version - The current version of a service.
|
1073 | * @returns {Promise} The response object representing the completion or failure.
|
1074 | */
|
1075 | async readBackends(version) {
|
1076 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/backend`);
|
1077 | }
|
1078 |
|
1079 | /**
|
1080 | * Update the backend for a particular service and version.
|
1081 | *
|
1082 | * @see https://docs.fastly.com/api/config#backend_fb3b3529417c70f57458644f7aec652e
|
1083 | * @example
|
1084 | * instance.updateBackend('34', 'slow-server', { name: 'fast-server' })
|
1085 | .then(res => {
|
1086 | console.log(res.data);
|
1087 | })
|
1088 | .catch(err => {
|
1089 | console.log(err.message);
|
1090 | });
|
1091 | * @param {string} version - The current version of a service.
|
1092 | * @param {string} name - The name of the backend.
|
1093 | * @param {object} data - The data to be sent as the request body.
|
1094 | * @returns {Promise} The response object representing the completion or failure.
|
1095 | */
|
1096 | async updateBackend(version, name, data) {
|
1097 | return this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/backend/${encodeURIComponent(name)}`, data);
|
1098 | }
|
1099 |
|
1100 | /**
|
1101 | * Create a new backend for a particular service and version.
|
1102 | *
|
1103 | * @see https://docs.fastly.com/api/config#backend_85c170418ee71191dbb3b5046aeb6c2c
|
1104 | * @param {number} version - The version number (current if omitted).
|
1105 | * @param {object} data - The backend definition.
|
1106 | * @returns {Promise} The reponse object.
|
1107 | */
|
1108 | async createBackend(version, data) {
|
1109 | return this.request.post(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/backend`, data);
|
1110 | }
|
1111 | /**
|
1112 | * @typedef {object} Snippet
|
1113 | * @property {string} name The name of the snippet, as visible in the Fastly UI.
|
1114 | * @property {string} content The VCL body of the snippet.
|
1115 | */
|
1116 |
|
1117 | /**
|
1118 | * List all snippets for a particular service and version.
|
1119 | *
|
1120 | * @see https://docs.fastly.com/api/config#api-section-snippet
|
1121 | * @example
|
1122 | * instance.readSnippets('12')
|
1123 | .then(res => {
|
1124 | console.log(res.data);
|
1125 | })
|
1126 | .catch(err => {
|
1127 | console.log(err.message);
|
1128 | });
|
1129 | * @param {string} version - The current version of a service.
|
1130 | * @returns {Promise} The response object representing the completion or failure.
|
1131 | */
|
1132 | async readSnippets(version) {
|
1133 | return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/snippet`);
|
1134 | }
|
1135 |
|
1136 | /**
|
1137 | * Create a snippet for a particular service and version.
|
1138 | *
|
1139 | * @see https://docs.fastly.com/api/config#snippet_41e0e11c662d4d56adada215e707f30d
|
1140 | * @example
|
1141 | * instance.createSnippet('36', {
|
1142 | name: 'your_snippet',
|
1143 | priority: 10,
|
1144 | dynamic: 1,
|
1145 | content: 'table referer_blacklist {}',
|
1146 | type: 'init'
|
1147 | })
|
1148 | .then(res => {
|
1149 | console.log(res.data);
|
1150 | })
|
1151 | .catch(err => {
|
1152 | console.log(err.message);
|
1153 | });
|
1154 | * @param {string} version - The current version of a service.
|
1155 | * @param {Snippet} data - The data to be sent as the request body.
|
1156 | * @returns {Promise} The response object representing the completion or failure.
|
1157 | */
|
1158 | async createSnippet(version, data) {
|
1159 | return this.request.post(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/snippet`, data);
|
1160 | }
|
1161 |
|
1162 | /**
|
1163 | * Update a VCL snippet for a particular service and version.
|
1164 | *
|
1165 | * @param {string} version - The current version of a service.
|
1166 | * @param {string} name - The name of the snippet to update.
|
1167 | * @param {Snippet} data - The data to be sent as the request body.
|
1168 | * @returns {Promise} The response object representing the completion or failure.
|
1169 | */
|
1170 | async updateSnippet(version, name, data) {
|
1171 | return this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/snippet/${name}`, data);
|
1172 | }
|
1173 |
|
1174 | /**
|
1175 | * @typedef {object} VCL
|
1176 | * @property {string} name The name of the VCL, as visible in the Fastly UI.
|
1177 | * Note: setting the name to 'main' here won't make it the main VCL,
|
1178 | * unless you also call `setMainVCL`.
|
1179 | * @property {string} content The VCL body of the custom VCL.
|
1180 | */
|
1181 |
|
1182 | /**
|
1183 | * Create custom VCL for a particular service and version.
|
1184 | *
|
1185 | * @see https://docs.fastly.com/api/config#vcl_7ade6ab5926b903b6acf3335a85060cc
|
1186 | * @param {string} version - The current version of a service.
|
1187 | * @param {VCL} data - The data to be sent as the request body.
|
1188 | * @returns {Promise} The response object representing the completion or failure.
|
1189 | */
|
1190 | async createVCL(version, data) {
|
1191 | return this.request.post(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/vcl`, data);
|
1192 | }
|
1193 |
|
1194 | /**
|
1195 | * Update custom VCL for a particular service and version.
|
1196 | *
|
1197 | * @see https://docs.fastly.com/api/config#vcl_0971365908e17086751c5ef2a8053087
|
1198 | * @param {string} version - The current version of a service.
|
1199 | * @param {string} name - The name of the VCL to update.
|
1200 | * @param {VCL} data - The data to be sent as the request body.
|
1201 | * @returns {Promise} The response object representing the completion or failure.
|
1202 | */
|
1203 | async updateVCL(version, name, data) {
|
1204 | if (typeof name === 'object') {
|
1205 | /* eslint-disable no-param-reassign */
|
1206 | data = name;
|
1207 | name = data.name;
|
1208 | /* eslint-enable no-param-reassign */
|
1209 | }
|
1210 | return this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/vcl/${name}`, data);
|
1211 | }
|
1212 |
|
1213 | /**
|
1214 | * Define a custom VCL to be the main VCL for a particular service and version.
|
1215 | *
|
1216 | * @see https://docs.fastly.com/api/config#vcl_5576c38e7652f5a7261bfcad41c0faf1
|
1217 | * @param {string} version - The current version of a service.
|
1218 | * @param {string} name - The name of the VCL to declare main.
|
1219 | * @returns {Promise} The response object representing the completion or failure.
|
1220 | */
|
1221 | async setMainVCL(version, name) {
|
1222 | return this.request.put(`/service/${this.service_id}/version/${await this.getVersion(version, 'current')}/vcl/${name}/main`, {});
|
1223 | }
|
1224 |
|
1225 | /**
|
1226 | * Creates a new version, runs the function `operations` and then
|
1227 | * optionally activates the newly created version. This function
|
1228 | * is useful for making modifications to a service config.
|
1229 | *
|
1230 | * You can provide a `limit` of write operations, which is an estimate
|
1231 | * of the number of write operations that will be attempted. If the
|
1232 | * limit is higher than the number of actions allowed by Fastly's rate
|
1233 | * limits, the function will fail fast after cloning the service config.
|
1234 | *
|
1235 | * @example
|
1236 | * ```javascript
|
1237 | * await fastly.transact(async (newversion) => {
|
1238 | * await fastly.doSomething(newversion);
|
1239 | * });
|
1240 | * // new version has been activated
|
1241 | * ```
|
1242 | * @param {Function} operations - A function that performs changes on the service config.
|
1243 | * @param {boolean} activate - Set to false to prevent automatic activation.
|
1244 | * @param {number} limit - Number of write operations that will be performed in this action.
|
1245 | * @returns {object} The return value of the wrapped function.
|
1246 | */
|
1247 | async transact(operations, activate = true, limit = 0) {
|
1248 | const newversion = (await this.cloneVersion()).data.number;
|
1249 | if (limit > 0 && this.requestmonitor.remaining && this.requestmonitor.remaining < limit) {
|
1250 | throw new RateLimitError(`Insufficient number of requests (${this.requestmonitor.remaining}) remaining for number of scheduled operations (${limit})`);
|
1251 | }
|
1252 | const result = await operations.apply(this, [newversion]);
|
1253 | if (activate) {
|
1254 | await this.activateVersion(newversion);
|
1255 | }
|
1256 | return result;
|
1257 | }
|
1258 |
|
1259 | /**
|
1260 | * See `transact`, but this version does not activate the created version.
|
1261 | *
|
1262 | * @see #transact
|
1263 | * @param {Function} operations - The operations that should be applied to the
|
1264 | * cloned service config version.
|
1265 | * @returns {object} Whatever `operations` returns.
|
1266 | */
|
1267 | async dryrun(operations) {
|
1268 | return this.transact(operations, false);
|
1269 | }
|
1270 | }
|
1271 |
|
1272 | /**
|
1273 | * Function to create a new fastly-promises instance.
|
1274 | *
|
1275 | * @param {string} token - The Fastly API token.
|
1276 | * @param {string} service_id - The Fastly service ID.
|
1277 | * @returns {Fastly} The exported module.
|
1278 | */
|
1279 | module.exports = (token, service_id) => new Fastly(token, service_id);
|