Skip to content

Commit

Permalink
feat(fastly): Add CRUD support for Dictionary Items
Browse files Browse the repository at this point in the history
Adds support for listing, reading, creating, updating, and deleting items from edge dictionaries.
The best way to use this feature is through the `writeDictItem(version, name, key, value)` method

Fixes #6
  • Loading branch information
trieloff committed Jan 18, 2019
1 parent 8458107 commit f9769ec
Show file tree
Hide file tree
Showing 8 changed files with 666 additions and 0 deletions.
140 changes: 140 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ HTTP status code can be retrieved. Known error status codes include:</p>
* [.activateVersion(version)](#Fastly+activateVersion) ⇒ <code>Promise</code>
* [.domainCheckAll(version)](#Fastly+domainCheckAll) ⇒ <code>Promise</code>
* [.readDomains(version)](#Fastly+readDomains) ⇒ <code>Promise</code>
* [.readDictItems(version, name)](#Fastly+readDictItems) ⇒ <code>Promise</code>
* [.readDictItem(version, name, key)](#Fastly+readDictItem) ⇒ <code>Promise</code>
* [.createDictItem(version, name, key, value)](#Fastly+createDictItem) ⇒ <code>Promise</code>
* [.updateDictItem(version, name, key, value)](#Fastly+updateDictItem) ⇒ <code>Promise</code>
* [.deleteDictItem(version, name, key)](#Fastly+deleteDictItem) ⇒ <code>Promise</code>
* [.writeDictItem(version, name, key, value)](#Fastly+writeDictItem) ⇒ <code>Promise</code>
* [.readDictionaries(version)](#Fastly+readDictionaries) ⇒ <code>Promise</code>
* [.readDictionary(version, name)](#Fastly+readDictionary) ⇒ <code>Promise</code>
* [.createDictionary(version, data)](#Fastly+createDictionary) ⇒ <code>Promise</code>
Expand Down Expand Up @@ -706,6 +712,140 @@ instance.readDomains('182')
console.log(err.message);
});
```
<a name="Fastly+readDictItems"></a>

#### fastly.readDictItems(version, name) ⇒ <code>Promise</code>
List all dictionary items for a particular service and version.

**Kind**: instance method of [<code>Fastly</code>](#Fastly)
**Returns**: <code>Promise</code> - The response object representing the completion or failure.
**See**: https://docs.fastly.com/api/config#dictionary_item_a48de28cd7e76c1ea58523f39bb7204b

| Param | Type | Description |
| --- | --- | --- |
| version | <code>string</code> | The version of the dictionary. |
| name | <code>string</code> | The name of the dictionary. |

**Example**
```js
instance.readDictItems(1, 'my_dictionary')
.then(res => {
console.log(res.data);
})
.catch(err => {
console.log(err.message);
});
```
<a name="Fastly+readDictItem"></a>

#### fastly.readDictItem(version, name, key) ⇒ <code>Promise</code>
Get details of a single dictionary item.

**Kind**: instance method of [<code>Fastly</code>](#Fastly)
**Returns**: <code>Promise</code> - The response object representing the completion or failure.
**See**: https://docs.fastly.com/api/config#dictionary_item_08f090cd03ed4602ae63f131087e2f29

| Param | Type | Description |
| --- | --- | --- |
| version | <code>string</code> | The current version of a service. |
| name | <code>string</code> | Name of the dictionary. |
| key | <code>string</code> | The key to retrieve values by. |

**Example**
```js
instance.readDictItem('12', 'extensions', 'some_key')
.then(res => {
console.log(res.data);
})
.catch(err => {
console.log(err.message);
});
```
<a name="Fastly+createDictItem"></a>

#### fastly.createDictItem(version, name, key, value) ⇒ <code>Promise</code>
Create a new dictionary item for a particular service and version.

**Kind**: instance method of [<code>Fastly</code>](#Fastly)
**Returns**: <code>Promise</code> - The reponse object.
**Fulfil**: [<code>Response</code>](#Response)
**See**: https://docs.fastly.com/api/config#dictionary_item_6ec455c0ba1b21671789e1362bc7fe55

| Param | Type | Description |
| --- | --- | --- |
| version | <code>number</code> | The version number (current if omitted). |
| name | <code>Object</code> | The dictionary definition. |
| key | <code>string</code> | The key. |
| value | <code>string</code> | The value to write. |

<a name="Fastly+updateDictItem"></a>

#### fastly.updateDictItem(version, name, key, value) ⇒ <code>Promise</code>
Update a dictionary item value for a particular service and version.

**Kind**: instance method of [<code>Fastly</code>](#Fastly)
**Returns**: <code>Promise</code> - The response object representing the completion or failure.
**Fulfil**: [<code>Response</code>](#Response)
**See**: https://docs.fastly.com/api/config#dictionary_item_34c884a7cdce84dfcfd38dac7a0b5bb0

| Param | Type | Description |
| --- | --- | --- |
| version | <code>string</code> | The current version of a service. |
| name | <code>string</code> | The name of the dictionary. |
| key | <code>string</code> | The key to update data under. |
| value | <code>string</code> | The value to update the dictionary with. |

**Example**
```js
instance.updateDictItem(1, 'extensions', 'html', 'text/html')
.then(res => {
console.log(res.data);
})
.catch(err => {
console.log(err.message);
});
```
<a name="Fastly+deleteDictItem"></a>

#### fastly.deleteDictItem(version, name, key) ⇒ <code>Promise</code>
Delete a dictionary item for a particular service and version.

**Kind**: instance method of [<code>Fastly</code>](#Fastly)
**Returns**: <code>Promise</code> - The response object representing the completion or failure.
**Fulfil**: [<code>Response</code>](#Response)
**See**: https://docs.fastly.com/api/config#dictionary_item_664347e743b8eafc9a93c729d9da0427

| Param | Type | Description |
| --- | --- | --- |
| version | <code>string</code> | The current version of a service. |
| name | <code>string</code> | The name of the dictionary. |
| key | <code>string</code> | The key to update data under. |

**Example**
```js
instance.deleteDictItem('34', 'extensions', 'html')
.then(res => {
console.log(res.data);
})
.catch(err => {
console.log(err.message);
});
```
<a name="Fastly+writeDictItem"></a>

#### fastly.writeDictItem(version, name, key, value) ⇒ <code>Promise</code>
Safely create, update or delete a dictionary item in a named dictionary.

**Kind**: instance method of [<code>Fastly</code>](#Fastly)
**Returns**: <code>Promise</code> - The response object representing the completion or failure.

| Param | Type | Description |
| --- | --- | --- |
| version | <code>number</code> | Service version to use for dictionary lookup. |
| name | <code>string</code> | Name of the dictionary (not ID). |
| key | <code>string</code> | Key to create, update or delete. |
| value | <code>string</code> | Value to update. Empty strings will delete the dictionary entry. |

<a name="Fastly+readDictionaries"></a>

#### fastly.readDictionaries(version) ⇒ <code>Promise</code>
Expand Down
161 changes: 161 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,167 @@ class Fastly {
return this.request.get(`/service/${this.service_id}/version/${await this.getVersion(version, 'latest')}/domain`);
}

// === start ===

/**
* List all dictionary items for a particular service and version.
*
* @see https://docs.fastly.com/api/config#dictionary_item_a48de28cd7e76c1ea58523f39bb7204b
* @example
* instance.readDictItems(1, 'my_dictionary')
.then(res => {
console.log(res.data);
})
.catch(err => {
console.log(err.message);
});
* @param {string} version - The version of the dictionary.
* @param {string} name - The name of the dictionary.
* @returns {Promise} The response object representing the completion or failure.
*/
async readDictItems(version, name) {
return this.readDictionary(
await this.getVersion(version, 'latest'),
name,
).then(({ data }) => this.request.get(`/service/${this.service_id}/dictionary/${data.id}/items`));
}

/**
* Get details of a single dictionary item.
*
* @see https://docs.fastly.com/api/config#dictionary_item_08f090cd03ed4602ae63f131087e2f29
* @example
* instance.readDictItem('12', 'extensions', 'some_key')
.then(res => {
console.log(res.data);
})
.catch(err => {
console.log(err.message);
});
* @param {string} version - The current version of a service.
* @param {string} name - Name of the dictionary.
* @param {string} key - The key to retrieve values by.
* @returns {Promise} The response object representing the completion or failure.
*/
async readDictItem(version, name, key) {
return this.readDictionary(
await this.getVersion(version, 'latest'),
name,
).then(({ data }) => this.request.get(`/service/${this.service_id}/dictionary/${data.id}/item/${key}`));
}

/**
* Create a new dictionary item for a particular service and version.
*
* @see https://docs.fastly.com/api/config#dictionary_item_6ec455c0ba1b21671789e1362bc7fe55
* @param {number} version - The version number (current if omitted).
* @param {Object} name - The dictionary definition.
* @param {string} key - The key.
* @param {string} value - The value to write.
* @returns {Promise} The reponse object.
* @fulfil {Response}
*/
async createDictItem(version, name, key, value) {
return this.readDictionary(
await this.getVersion(version, 'latest'),
name,
).then(({ data }) => this.request.post(`/service/${this.service_id}/dictionary/${data.id}/item`, {
item_key: key,
item_value: value,
}));
}

/**
* Update a dictionary item value for a particular service and version.
*
* @see https://docs.fastly.com/api/config#dictionary_item_34c884a7cdce84dfcfd38dac7a0b5bb0
* @example
* instance.updateDictItem(1, 'extensions', 'html', 'text/html')
.then(res => {
console.log(res.data);
})
.catch(err => {
console.log(err.message);
});
* @param {string} version - The current version of a service.
* @param {string} name - The name of the dictionary.
* @param {string} key - The key to update data under.
* @param {string} value - The value to update the dictionary with.
* @returns {Promise} The response object representing the completion or failure.
* @fulfil {Response}
*/
async updateDictItem(version, name, key, value) {
return this.readDictionary(
await this.getVersion(version, 'latest'),
name,
).then(({ data }) => this.request.put(`/service/${this.service_id}/dictionary/${data.id}/item/${key}`, {
item_value: value,
}));
}

/**
* Delete a dictionary item for a particular service and version.
*
* @see https://docs.fastly.com/api/config#dictionary_item_664347e743b8eafc9a93c729d9da0427
* @example
* instance.deleteDictItem('34', 'extensions', 'html')
.then(res => {
console.log(res.data);
})
.catch(err => {
console.log(err.message);
});
* @param {string} version - The current version of a service.
* @param {string} name - The name of the dictionary.
* @param {string} key - The key to update data under.
* @returns {Promise} The response object representing the completion or failure.
* @fulfil {Response}
*/
async deleteDictItem(version, name, key) {
return this.readDictionary(
await this.getVersion(version, 'latest'),
name,
).then(({ data }) => this.request.delete(`/service/${this.service_id}/dictionary/${data.id}/item/${key}`));
}

/**
* Safely create, update or delete a dictionary item in a named dictionary.
*
* @param {number} version - Service version to use for dictionary lookup.
* @param {string} name - Name of the dictionary (not ID).
* @param {string} key - Key to create, update or delete.
* @param {string} value - Value to update. Empty strings will delete the dictionary entry.
* @returns {Promise} The response object representing the completion or failure.
*/
writeDictItem(version, name, key, value) {
return this.readDictItem(version, name, key)
.then(() => {
// the dictionary item already exists
if (value) {
// update existing value
return this.updateDictItem(version, name, key, value);
}
// value is undefined. Fastly does not support overwriting with empty
// values, so we delete the value
return this.deleteDictItem(version, name, key);
})
.catch(() => {
// the dictionary item does not exist
if (value) {
return this.createDictItem(version, name, key, value);
}
// the item does not exist and there is no data to write, we just pretend it went ok
return {
status: 200,
data: {
status: 'ok',
},
};
});
}

// === done ===

/**
* List all dictionaries for a particular service and version.
*
Expand Down
60 changes: 60 additions & 0 deletions test/readDictItems.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use strict';

/* eslint-env mocha */

const nock = require('nock');
const expect = require('expect');
const config = require('../src/config');
const fastlyPromises = require('../src/index');
const response = require('./response/dictitem.response');

describe('#readDictItems', () => {
const fastly = fastlyPromises('923b6bd5266a7f932e41962755bd4254', 'SU1Z0isxPaozGVKXdv0eY');
let res;

nock(config.mainEntryPoint)
// get the dictionary first
.get('/service/SU1Z0isxPaozGVKXdv0eY/version/1/dictionary/my_dictionary')
.reply(200, response.dict.get)
// list
.get('/service/SU1Z0isxPaozGVKXdv0eY/dictionary/5clCytcTJrnvPi8wjqPH0q/items')
.reply(200, response.item.list);

before(async () => {
res = await fastly.readDictItems(1, 'my_dictionary');
});

it('response should be a status 200', () => {
expect(res.status).toBe(200);
});

it('response body should exist', () => {
expect(res.data).toBeTruthy();
});

it('response body should be an array', () => {
expect(Array.isArray(res.data)).toBe(true);
});

it('response body should be an array of objects', () => {
res.data.forEach((item) => {
expect(typeof item).toBe('object');
});
});

it('response body should contain all properties', () => {
res.data.forEach((item) => {
[
'dictionary_id',
'service_id',
'item_key',
'item_value',
'created_at',
'deleted_at',
'updated_at',
].forEach((e) => {
expect(Object.keys(item)).toContain(e);
});
});
});
});
Loading

0 comments on commit f9769ec

Please sign in to comment.