From 628210f1b9d6fda84a2603509f67430d698391ad Mon Sep 17 00:00:00 2001 From: Sharathkumar Anbu Date: Mon, 8 Oct 2018 16:04:45 +0530 Subject: [PATCH] Added tests with documentation of methods in wrapper --- .gitignore | 2 + README.md | 74 +- docs/EventPayload.md | 10 + docs/EventPayloadWoTopic.md | 9 + docs/EventsApi.md | 111 +++ docs/ExtendedService.md | 7 + docs/HealthCheckStatus.md | 6 + docs/HealthchecksApi.md | 90 ++ docs/Payload.md | 9 + docs/PlaceholdersApi.md | 49 + docs/Service.md | 11 + docs/ServiceApi.md | 854 +++++++++++++++++ docs/TopicsApi.md | 92 ++ index.js | 16 +- package-lock.json | 1689 +++++++++++++++++++++++++++++++--- package.json | 13 +- src/ServiceApi.js | 20 +- src/common/helper.js | 19 +- test/EventsApi.test.js | 76 ++ test/HealthChecksApi.test.js | 40 + test/PlaceholdersApi.test.js | 32 + test/TopicsApi.test.js | 40 + test/testData.js | 17 + 23 files changed, 3145 insertions(+), 141 deletions(-) create mode 100644 docs/EventPayload.md create mode 100644 docs/EventPayloadWoTopic.md create mode 100644 docs/EventsApi.md create mode 100644 docs/ExtendedService.md create mode 100644 docs/HealthCheckStatus.md create mode 100644 docs/HealthchecksApi.md create mode 100644 docs/Payload.md create mode 100644 docs/PlaceholdersApi.md create mode 100644 docs/Service.md create mode 100644 docs/ServiceApi.md create mode 100644 docs/TopicsApi.md create mode 100644 test/EventsApi.test.js create mode 100644 test/HealthChecksApi.test.js create mode 100644 test/PlaceholdersApi.test.js create mode 100644 test/TopicsApi.test.js create mode 100644 test/testData.js diff --git a/.gitignore b/.gitignore index c2658d7..1123264 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ node_modules/ +coverage/ +.nyc_output/ \ No newline at end of file diff --git a/README.md b/README.md index e95a305..2222e1e 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Wrapper library for Topcoder Bus API ``` const busApi = require('tc-bus-api-wrapper') -busApi(_.pick(config, +const busApiClient = busApi(_.pick(config, ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', 'KAFKA_ERROR_TOPIC'])) @@ -30,17 +30,81 @@ busApi(_.pick(config, - AUTH0_CLIENT_ID - BUSAPI_URL - Bus API URL. E.g. `https://api.topcoder-dev.com/v5` - - KAFKA_ERROR_TOPIC - Error topic in Kafka to which error message need to be posted + 3. Every function in this wrapper will return a promise, Handling promises is at the caller end. Call the functions with appropriate arguments E.g. ``` -const result = yield busApiClient.getTopics() +busApiClient + .getTopics() + .then(result => console.log(result.body, result.status)) + .catch(err => console.log(err)) -yield busApiClient.postEvent(reqBody) +await busApiClient.postEvent(reqBody) ``` -Refer `index.js` for the list of available wrapper functions \ No newline at end of file +Refer `index.js` for the list of available wrapper functions + +## Documentation for Bus API wrapper methods + +All URIs are relative to **BUSAPI_URL** configuration variable. + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**postEvent**](docs/EventsApi.md#postEvent) | **POST** /bus/events | Post event to the message bus. +[**postError**](docs/EventsApi.md#postError) | **POST** /bus/events | Post error event to the message bus. This method is same as postEvent except that topic will be set by the wrapper itself. +[**getHealth**](docs/HealthchecksApi.md#getHealth) | **GET** /bus/health | Check API is healthy. +[**headHealth**](docs/HealthchecksApi.md#headHealth) | **HEAD** /bus/health | Get only response status and headers information but no response body for the endpoint. +[**clearPlaceholdersCache**](docs/PlaceholdersApi.md#clearPlaceholdersCache) | **DELETE** /bus/placeholders | Clear placeholders cache. +[**createService**](docs/ServiceApi.md#createService) | **POST** /bus/services | Create a service. +[**createServicePayload**](docs/ServiceApi.md#createServicePayload) | **POST** /bus/services/{serviceName}/payloads | Create the service payload. +[**deleteService**](docs/ServiceApi.md#deleteService) | **DELETE** /bus/services/{serviceName} | Delete the service. +[**deleteServicePayload**](docs/ServiceApi.md#deleteServicePayload) | **DELETE** /bus/services/{serviceName}/payloads/{payloadName} | Delete the service payload. +[**getService**](docs/ServiceApi.md#getService) | **GET** /bus/services/{serviceName} | Get the service. +[**getServicePayload**](docs/ServiceApi.md#getServicePayload) | **GET** /bus/services/{serviceName}/payloads/{payloadName} | Get the service payload. +[**getServicePayloads**](docs/ServiceApi.md#getServicePayloads) | **GET** /bus/services/{serviceName}/payloads | Search the service payloads. +[**getServices**](docs/ServiceApi.md#getServices) | **GET** /bus/services | Get all services. +[**headService**](docs/ServiceApi.md#headService) | **HEAD** /bus/services/{serviceName} | Get only response status and headers information but no response body for the endpoint. +[**headServicePayload**](docs/ServiceApi.md#headServicePayload) | **HEAD** /bus/services/{serviceName}/payloads/{payloadName} | Get only response status and headers information but no response body for the endpoint. +[**headServicePayloads**](docs/ServiceApi.md#headServicePayloads) | **HEAD** /bus/services/{serviceName}/payloads | Get only response status and headers information but no response body for the endpoint. +[**headServices**](docs/ServiceApi.md#headServices) | **HEAD** /bus/services | Get only response status and headers information but no response body for the endpoint. +[**patchService**](docs/ServiceApi.md#patchService) | **PATCH** /bus/services/{serviceName} | Partially update the service. +[**patchServicePayload**](docs/ServiceApi.md#patchServicePayload) | **PATCH** /bus/services/{serviceName}/payloads/{payloadName} | Partially update the payload. +[**updateService**](docs/ServiceApi.md#updateService) | **PUT** /bus/services/{serviceName} | Update the service. +[**updateServicePayload**](docs/ServiceApi.md#updateServicePayload) | **PUT** /bus/services/{serviceName}/payloads/{payloadName} | Update the service payload. +[**getTopics**](docs/TopicsApi.md#getTopics) | **GET** /bus/topics | Get topics. +[**headTopics**](docs/TopicsApi.md#headTopics) | **HEAD** /bus/topics | Get only response status and headers information but no response body for the endpoint. + +## Authorization + +Bus API wrapper internally generates a **JWT token using Auth0 credentials** and pass it in the `Authorization` header. + +## Running tests + +Following environment variables need to be set up before running the tests + +``` +- TEST_AUTH0_URL +- TEST_AUTH0_AUDIENCE +- TEST_AUTH0_CLIENT_ID +- TEST_AUTH0_CLIENT_SECRET +- TEST_BUS_API_URL +- TEST_KAFKA_ERROR_TOPIC +``` + +Refer to Step # 2 in [this section](#how-to-use-this-wrapper) to learn more about the configuration variables. + +To run the tests alone, execute the command + +``` +npm run test +``` + +To run tests with coverage report, execute the command + +``` +npm run cov +``` \ No newline at end of file diff --git a/docs/EventPayload.md b/docs/EventPayload.md new file mode 100644 index 0000000..b12e669 --- /dev/null +++ b/docs/EventPayload.md @@ -0,0 +1,10 @@ +# Event Payload + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**topic** | **String** | Topic name should be a dot separated fully qualified name i.e. domain.type.operation. | +**originator** | **String** | Service repository name, from where message is published. | +**timestamp** | **Date** | Timestamp at which message is published. The date-time notation as defined by RFC 3339, section 5.6, for example, 2018-04-13T00:00:00Z | +**mimeType** | **String** | Mime-type for 'payload'. | +**payload** | **Object** | Actual payload depending on mime-type for consumer. | \ No newline at end of file diff --git a/docs/EventPayloadWoTopic.md b/docs/EventPayloadWoTopic.md new file mode 100644 index 0000000..34ef51e --- /dev/null +++ b/docs/EventPayloadWoTopic.md @@ -0,0 +1,9 @@ +# Event Payload Without Topic + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**originator** | **String** | Service repository name, from where message is published. | +**timestamp** | **Date** | Timestamp at which message is published. The date-time notation as defined by RFC 3339, section 5.6, for example, 2018-04-13T00:00:00Z | +**mimeType** | **String** | Mime-type for 'payload'. | +**payload** | **Object** | Actual payload depending on mime-type for consumer. | \ No newline at end of file diff --git a/docs/EventsApi.md b/docs/EventsApi.md new file mode 100644 index 0000000..a9899bf --- /dev/null +++ b/docs/EventsApi.md @@ -0,0 +1,111 @@ +# Events Api + +All URIs are relative to **BUSAPI_URL** configuration variable. + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**postEvent**](EventsApi.md#postEvent) | **POST** /bus/events | Post event to the message bus. +[**postError**](EventsApi.md#postError) | **POST** /bus/events | Post error event to the message bus. Topic will be set by wrapper itself. + + +# **postEvent** +> postEvent(body) + +Post an event to the message bus. + +### Example +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const reqBody = { + 'topic': 'test.topic.1', + 'originator': 'tester', + 'timestamp': '2018-05-20T07:00:30.123Z', + 'mime-type': 'application/json', + 'payload': { // Payload varies depending on the event + 'name': 'test' + } +} +// Promise model +busApiClient + .postEvent(reqBody) + .then(result => console.log(result.body, result.status)) + .catch(err => console.log(err)) + +// Async / await model +await busApiClient.postEvent(reqBody) +``` + +### Parameters + +Name | Type | Description +------------- | ------------- | ------------- + **body** | [**Event Payload**](EventPayload.md)| Payload of an event + +### Return type + +null (empty response body) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **postError** +> postError(body) + +Post error event to the message bus. + +### Example +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const reqBody = { + 'originator': 'tester', + 'timestamp': '2018-05-20T07:00:30.123Z', + 'mime-type': 'application/json', + 'payload': { // Payload varies depending on the event + 'name': 'test' + } +} +// Promise model +busApiClient + .postError(reqBody) + .then(result => console.log(result.body, result.status)) + .catch(err => console.log(err)) + +// Async / await model +await busApiClient.postError(reqBody) +``` + +### Parameters + +Name | Type | Description +------------- | ------------- | ------------- + **body** | [**Event Payload Without Topic**](EventPayloadWoTopic.md)| Payload of error event without topic + +### Return type + +null (empty response body) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json \ No newline at end of file diff --git a/docs/ExtendedService.md b/docs/ExtendedService.md new file mode 100644 index 0000000..0a59261 --- /dev/null +++ b/docs/ExtendedService.md @@ -0,0 +1,7 @@ +# Extended Service + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**serviceId** | **String** | The service id. | +**service** | [**Service**](Service.md) | Service definition | Attributes from Service will be merged into this object \ No newline at end of file diff --git a/docs/HealthCheckStatus.md b/docs/HealthCheckStatus.md new file mode 100644 index 0000000..f9960fa --- /dev/null +++ b/docs/HealthCheckStatus.md @@ -0,0 +1,6 @@ +# Health Check Status + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**health** | **String** | Health check status. | [default to 'ok'] diff --git a/docs/HealthchecksApi.md b/docs/HealthchecksApi.md new file mode 100644 index 0000000..1a54d7e --- /dev/null +++ b/docs/HealthchecksApi.md @@ -0,0 +1,90 @@ +# Healthchecks Api + +All URIs are relative to **BUSAPI_URL** configuration variable. + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**getHealth**](HealthchecksApi.md#getHealth) | **GET** /bus/health | Check if API is healthy. +[**headHealth**](HealthchecksApi.md#headHealth) | **HEAD** /bus/health | Get only response status and headers information but no response body for the endpoint. + + + +# **getHealth** +> HealthCheckStatus getHealth() + +Check if API is healthy. + +### Example +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +// Promise model +busApiClient + .getHealth() + .then(result => console.log(result.body, result.status)) + .catch(err => console.log(err)) + +// Async / await model +const result = await busApiClient.getHealth() +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +[**Health Check Status**](HealthCheckStatus.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **headHealth** +> headHealth() + +Get response status and headers information for the endpoint. It does not contain response body. + +### Example +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +// Promise model +busApiClient + .headHealth() + .then(result => console.log(result.body, result.status)) // Body will be empty + .catch(err => console.log(err)) + +// Async / await model +const result = await busApiClient.headHealth() +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +null (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + diff --git a/docs/Payload.md b/docs/Payload.md new file mode 100644 index 0000000..ed8f9af --- /dev/null +++ b/docs/Payload.md @@ -0,0 +1,9 @@ +# Payload + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**name** | **String** | The payload name. | [optional] +**topics** | **[String]** | The list of topics for a payload. | +**payloadMimeType** | **String** | The payload mime type. | +**payloadFormat** | **Object** | The payload format. | \ No newline at end of file diff --git a/docs/PlaceholdersApi.md b/docs/PlaceholdersApi.md new file mode 100644 index 0000000..07b24c0 --- /dev/null +++ b/docs/PlaceholdersApi.md @@ -0,0 +1,49 @@ +# Placeholders Api + +All URIs are relative to **BUSAPI_URL** configuration variable. + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**clearPlaceholdersCache**](PlaceholdersApi.md#clearPlaceholdersCache) | **DELETE** /bus/placeholders | Clear placeholders cache. + + + +# **clearPlaceholdersCache** +> clearPlaceholdersCache() + +Clear the cache for placeholder validation of email topics. + +### Example +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +// Promise model +busApiClient + .clearPlaceholdersCache() + .then(result => console.log(result.body, result.status)) // Body will be empty + .catch(err => console.log(err)) + +// Async / await model +await busApiClient.clearPlaceholdersCache() +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +null (empty response body) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + diff --git a/docs/Service.md b/docs/Service.md new file mode 100644 index 0000000..7ded334 --- /dev/null +++ b/docs/Service.md @@ -0,0 +1,11 @@ +# Service + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**name** | **String** | The service name. | +**version** | **String** | The service version. | +**commitHash** | **String** | The service commit hash. | +**description** | **String** | The service description. | +**baseURL** | **String** | The service base URL. | +**payloads** | [**[Payload]**](Payload.md) | The service payloads | \ No newline at end of file diff --git a/docs/ServiceApi.md b/docs/ServiceApi.md new file mode 100644 index 0000000..3a62c3a --- /dev/null +++ b/docs/ServiceApi.md @@ -0,0 +1,854 @@ +# Service Api + +All URIs are relative to **BUSAPI_URL** configuration variable. + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**createService**](ServiceApi.md#createService) | **POST** /bus/services | Create a service. +[**createServicePayload**](ServiceApi.md#createServicePayload) | **POST** /bus/services/{serviceName}/payloads | Create the service payload. +[**deleteService**](ServiceApi.md#deleteService) | **DELETE** /bus/services/{serviceName} | Delete the service. +[**deleteServicePayload**](ServiceApi.md#deleteServicePayload) | **DELETE** /bus/services/{serviceName}/payloads/{payloadName} | Delete the service payload. +[**getService**](ServiceApi.md#getService) | **GET** /bus/services/{serviceName} | Get the service. +[**getServicePayload**](ServiceApi.md#getServicePayload) | **GET** /bus/services/{serviceName}/payloads/{payloadName} | Get the service payload. +[**getServicePayloads**](ServiceApi.md#getServicePayloads) | **GET** /bus/services/{serviceName}/payloads | Search the service payloads. +[**getServices**](ServiceApi.md#getServices) | **GET** /bus/services | Get all services. +[**headService**](ServiceApi.md#headService) | **HEAD** /bus/services/{serviceName} | Get only response status and headers information but no response body for the endpoint. +[**headServicePayload**](ServiceApi.md#headServicePayload) | **HEAD** /bus/services/{serviceName}/payloads/{payloadName} | Get only response status and headers information but no response body for the endpoint. +[**headServicePayloads**](ServiceApi.md#headServicePayloads) | **HEAD** /bus/services/{serviceName}/payloads | Get only response status and headers information but no response body for the endpoint. +[**headServices**](ServiceApi.md#headServices) | **HEAD** /bus/services | Get only response status and headers information but no response body for the endpoint. +[**patchService**](ServiceApi.md#patchService) | **PATCH** /bus/services/{serviceName} | Partially update the service. +[**patchServicePayload**](ServiceApi.md#patchServicePayload) | **PATCH** /bus/services/{serviceName}/payloads/{payloadName} | Partially update the payload. +[**updateService**](ServiceApi.md#updateService) | **PUT** /bus/services/{serviceName} | Update the service. +[**updateServicePayload**](ServiceApi.md#updateServicePayload) | **PUT** /bus/services/{serviceName}/payloads/{payloadName} | Update the service payload. + + + +# **createService** +> ExtendedService createService(body) + +Create a new service. + +### Example + +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const reqBody = { + 'name': 'ap-challenge-service', + 'version': '5.0.1', + 'commitHash': 'b2037acaf982370286b21eca2e40f4353b59e9c9', + 'description': 'TC Challenge API', + 'baseURL': 'https://api.topcoder.com/v5/challenges', + 'payloads': [ + { + 'name': 'createEvent', + 'topics': [ + 'notifications.kafka.queue.java.test' + ], + 'payloadMimeType': 'application/json', + 'payloadFormat': {} + } + ] +} + +// Promise model +busApiClient + .createService(reqBody) + .then(result => console.log(result.body, result.status)) + .catch(err => console.log(err)) + +// Async / await model +await busApiClient.createService(reqBody) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**Service**](Service.md)| Service definition | + +### Return type + +[**Extended Service**](ExtendedService.md) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **createServicePayload** +> Payload createServicePayload(serviceName, body) + +Create a payload for the given service. + +### Example + +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const serviceName = 'ap-challenge-service' + +const reqBody = { + 'name': 'createEvent', + 'topics': [ + 'notifications.kafka.queue.java.test' + ], + 'payloadMimeType': 'application/json', + 'payloadFormat': {} +} + +// Promise model +busApiClient + .createServicePayload(serviceName, reqBody) + .then(result => console.log(result.body, result.status)) + .catch(err => console.log(err)) + +// Async / await model +await busApiClient.createServicePayload(serviceName, reqBody) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **serviceName** | **String**| The service name. | + **body** | [**Payload**](Payload.md)| Payload definition | + +### Return type + +[**Payload**](Payload.md) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **deleteService** +> deleteService(serviceName) + +Delete the service. + +### Example + +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const serviceName = 'ap-challenge-service' + +// Promise model +busApiClient + .deleteService(serviceName) + .then(result => console.log(result.body, result.status)) // Body will be empty + .catch(err => console.log(err)) + +// Async / await model +await busApiClient.deleteService(serviceName) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **serviceName** | **String**| The service name. | + +### Return type + +null (empty response body) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **deleteServicePayload** +> deleteServicePayload(serviceName, payloadName) + +Delete the payload for the given service. + +### Example + +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const serviceName = 'ap-challenge-service' +const payloadName = 'test-payload' + +// Promise model +busApiClient + .deleteServicePayload(serviceName, payloadName) + .then(result => console.log(result.body, result.status)) // Body will be empty + .catch(err => console.log(err)) + +// Async / await model +await busApiClient.deleteServicePayload(serviceName, payloadName) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **serviceName** | **String**| The service name. | + **payloadName** | **String**| The payload name. | + +### Return type + +null (empty response body) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **getService** +> ExtendedService getService(serviceName) + +Get the service by service name. + +### Example + +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const serviceName = 'ap-challenge-service' + +// Promise model +busApiClient + .getService(serviceName) + .then(result => console.log(result.body, result.status)) + .catch(err => console.log(err)) + +// Async / await model +const result = await busApiClient.getService(serviceName) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **serviceName** | **String**| The service name. | + +### Return type + +[**Extended Service**](ExtendedService.md) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **getServicePayload** +> Payload getServicePayload(serviceName, payloadName) + +Get the payload for the given service. + +### Example + +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const serviceName = 'ap-challenge-service' +const payloadName = 'test-payload' + +// Promise model +busApiClient + .getServicePayload(serviceName, payloadName) + .then(result => console.log(result.body, result.status)) + .catch(err => console.log(err)) + +// Async / await model +const result = await busApiClient.getServicePayload(serviceName, payloadName) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **serviceName** | **String**| The service name. | + **payloadName** | **String**| The payload name. | + +### Return type + +[**Payload**](Payload.md) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **getServicePayloads** +> [Payload] getServicePayloads(serviceName, opts) + +Search payloads for the given service. + +### Example + +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const serviceName = 'ap-challenge-service' +// Paging parameters are optional +const opts = { + 'page': 1, + 'perPage': 2 +} + +// Promise model +busApiClient + .getServicePayloads(serviceName, opts) + .then(result => console.log(result.body, result.status)) + .catch(err => console.log(err)) + +// Async / await model +const result = await busApiClient.getServicePayloads(serviceName, opts) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **serviceName** | **String**| The service name. | + **page** | **Number**| The page number. | [optional] [default to 1] + **perPage** | **Number**| The number of items to list per page. | [optional] [default to 20] + +### Return type + +[**[Payload]**](Payload.md) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **getServices** +> [ExtendedService] getServices(opts) + +Get all services. Link headers are sent back and they have rel set to prev, next, first, last and contain the relevant URL. + +### Example + +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +// Paging parameters are optional +const opts = { + 'page': 1, + 'perPage': 2 +} + +// Promise model +busApiClient + .getServices(opts) + .then(result => console.log(result.body, result.status)) + .catch(err => console.log(err)) + +// Async / await model +const result = await busApiClient.getServices(opts) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **page** | **Number**| The page number. | [optional] [default to 1] + **perPage** | **Number**| The number of items to list per page. | [optional] [default to 20] + +### Return type + +[**[Extended Service]**](ExtendedService.md) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **headService** +> headService(serviceName) + +Get response status and headers information for the endpoint. It does not contain response body. + +### Example +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const serviceName = 'ap-challenge-service' + +// Promise model +busApiClient + .headService(serviceName) + .then(result => console.log(result.body, result.status)) // Body will be empty + .catch(err => console.log(err)) + +// Async / await model +const result = await busApiClient.headService(serviceName) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **serviceName** | **String**| The service name. | + +### Return type + +null (empty response body) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **headServicePayload** +> headServicePayload(serviceName, payloadName) + +Get response status and headers information for the endpoint. It does not contain response body. + +### Example +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const serviceName = 'ap-challenge-service' +const payloadName = 'test-payload' + +// Promise model +busApiClient + .headServicePayload(serviceName, payloadName) + .then(result => console.log(result.body, result.status)) // Body will be empty + .catch(err => console.log(err)) + +// Async / await model +const result = await busApiClient.headServicePayload(serviceName, payloadName) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **serviceName** | **String**| The service name. | + **payloadName** | **String**| The payload name. | + +### Return type + +null (empty response body) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **headServicePayloads** +> headServicePayloads(serviceName, opts) + +Get response status and headers information for the endpoint. The Link header is provided in the header and they have rel set to prev, next, first, last and contain the relevant URL. It does not contain response body. + +### Example +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const serviceName = 'ap-challenge-service' +// Paging parameters are optional +const opts = { + 'page': 1, + 'perPage': 2 +} + +// Promise model +busApiClient + .headServicePayloads(serviceName, opts) + .then(result => console.log(result.body, result.status)) // Body will be empty + .catch(err => console.log(err)) + +// Async / await model +const result = await busApiClient.headServicePayloads(serviceName, opts) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **serviceName** | **String**| The service name. | + **page** | **Number**| The page number. | [optional] [default to 1] + **perPage** | **Number**| The number of items to list per page. | [optional] [default to 20] + +### Return type + +null (empty response body) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **headServices** +> headServices(opts) + +Get response status and headers information for the endpoint. The Link header is provided in the header and they have rel set to prev, next, first, last and contain the relevant URL. It does not contain response body. + +### Example +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +// Paging parameters are optional +const opts = { + 'page': 1, + 'perPage': 2 +} + +// Promise model +busApiClient + .headServices(opts) + .then(result => console.log(result.body, result.status)) // Body will be empty + .catch(err => console.log(err)) + +// Async / await model +const result = await busApiClient.headServices(opts) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **page** | **Number**| The page number. | [optional] [default to 1] + **perPage** | **Number**| The number of items to list per page. | [optional] [default to 20] + +### Return type + +null (empty response body) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **patchService** +> ExtendedService patchService(serviceName, body) + +Allows to partially modify the service with the provided request body. + +### Example +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const serviceName = 'ap-challenge-service' + +const reqBody = { + 'version': '5.0.1', + 'commitHash': 'b2037acaf982370286b21eca2e40f4353b59e9c9', + 'baseURL': 'https://api.topcoder.com/v5/challenges' +} + +// Promise model +busApiClient + .patchService(serviceName, reqBody) + .then(result => console.log(result.body, result.status)) + .catch(err => console.log(err)) + +// Async / await model +await busApiClient.patchService(serviceName, reqBody) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **serviceName** | **String**| The service name. | + **body** | [**Service**](Service.md)| Any set of fields from Service entity | + +### Return type + +[**ExtendedService**](ExtendedService.md) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **patchServicePayload** +> Payload patchServicePayload(serviceName, payloadName, body) + +Allows to partially modify the payload with the provided request body. + +### Example +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const serviceName = 'ap-challenge-service' +const payloadName = 'test-payload' + +const reqBody = { + 'topics': [ + 'notifications.kafka.queue.java.test' + ], + 'payloadMimeType': 'application/json' +} + +// Promise model +busApiClient + .patchServicePayload(serviceName, payloadName, reqBody) + .then(result => console.log(result.body, result.status)) + .catch(err => console.log(err)) + +// Async / await model +await busApiClient.patchServicePayload(serviceName, payloadName, reqBody) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **serviceName** | **String**| The service name. | + **payloadName** | **String**| The payload name. | + **body** | [**Payload**](Payload.md)| Any set of fields from the Payload entity except name | + +### Return type + +[**Payload**](Payload.md) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **updateService** +> ExtendedService updateService(serviceName, body) + +Update the service by service name. + +### Example +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const serviceName = 'ap-challenge-service' + +const reqBody = { + 'version': '5.0.1', + 'commitHash': 'b2037acaf982370286b21eca2e40f4353b59e9c9', + 'description': 'TC Challenge API', + 'baseURL': 'https://api.topcoder.com/v5/challenges', + 'payloads': [ + { + 'name': 'createEvent', + 'topics': [ + 'notifications.kafka.queue.java.test' + ], + 'payloadMimeType': 'application/json', + 'payloadFormat': {} + } + ] +} + +// Promise model +busApiClient + .updateService(serviceName, reqBody) + .then(result => console.log(result.body, result.status)) + .catch(err => console.log(err)) + +// Async / await model +await busApiClient.updateService(serviceName, reqBody) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **serviceName** | **String**| The service name. | + **body** | [**Service**](Service.md)| Service entity | + +### Return type + +[**ExtendedService**](ExtendedService.md) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **updateServicePayload** +> Payload updateServicePayload(serviceName, payloadName, body) + +Update the payload for the given service. + +### Example +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +const serviceName = 'ap-challenge-service' +const payloadName = 'test-payload' + +const reqBody = { + 'topics': [ + 'notifications.kafka.queue.java.test' + ], + 'payloadMimeType': 'application/json', + 'payloadFormat': {} +} + +// Promise model +busApiClient + .updateServicePayload(serviceName, payloadName, reqBody) + .then(result => console.log(result.body, result.status)) + .catch(err => console.log(err)) + +// Async / await model +await busApiClient.updateServicePayload(serviceName, payloadName, reqBody) +``` + +### Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **serviceName** | **String**| The service name. | + **payloadName** | **String**| The payload name. | + **body** | [**Payload**](Payload.md)| Payload entity without name | + +### Return type + +[**Payload**](Payload.md) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + diff --git a/docs/TopicsApi.md b/docs/TopicsApi.md new file mode 100644 index 0000000..e704bdf --- /dev/null +++ b/docs/TopicsApi.md @@ -0,0 +1,92 @@ +# Topics Api + +All URIs are relative to **BUSAPI_URL** configuration variable. + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**getTopics**](TopicsApi.md#getTopics) | **GET** /bus/topics | Get topics. +[**headTopics**](TopicsApi.md#headTopics) | **HEAD** /bus/topics | Get only response status and headers information but no response body for the topics endpoint. + + + +# **getTopics** +> getTopics() + +Get topics. + +Get all topic names. + +### Example +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +// Promise model +busApiClient + .getTopics() + .then(result => console.log(result.body, result.status)) + .catch(err => console.log(err)) + +// Async / await model +const result = await busApiClient.getTopics() +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +Array of strings + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + + +# **headTopics** +> headTopics() + +Get response status and headers information for the topics endpoint. It does not contain response body. + +### Example +```javascript +const busApi = require('tc-bus-api-wrapper') +const busApiClient = busApi(_.pick(config, + ['AUTH0_URL', 'AUTH0_AUDIENCE', 'TOKEN_CACHE_TIME', + 'AUTH0_CLIENT_ID', 'AUTH0_CLIENT_SECRET', 'BUSAPI_URL', + 'KAFKA_ERROR_TOPIC'])) + +// Promise model +busApiClient + .headTopics() + .then(result => console.log(result.body, result.status)) // Body will be empty + .catch(err => console.log(err)) + +// Async / await model +const result = await busApiClient.headTopics() +``` + +### Parameters +This endpoint does not need any parameter. + +### Return type + +null (empty response body) + +### Authorization + +[Bearer](../README.md#authorization) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + diff --git a/index.js b/index.js index 796acfc..eabb21c 100644 --- a/index.js +++ b/index.js @@ -54,11 +54,11 @@ module.exports = (config) => { }, // Service API functions - getServices: async () => { - return require('./src/ServiceApi').getServices(config) + getServices: async (opts) => { + return require('./src/ServiceApi').getServices(config, opts) }, - headServices: async () => { - return require('./src/ServiceApi').headServices(config) + headServices: async (opts) => { + return require('./src/ServiceApi').headServices(config, opts) }, createService: async (reqBody) => { return require('./src/ServiceApi').createService(config, reqBody) @@ -79,11 +79,11 @@ module.exports = (config) => { return require('./src/ServiceApi').deleteService(config, serviceName) }, - getServicePayloads: async (serviceName) => { - return require('./src/ServiceApi').getServicePayloads(config, serviceName) + getServicePayloads: async (serviceName, opts) => { + return require('./src/ServiceApi').getServicePayloads(config, serviceName, opts) }, - headServicePayloads: async (serviceName) => { - return require('./src/ServiceApi').headServicePayloads(config, serviceName) + headServicePayloads: async (serviceName, opts) => { + return require('./src/ServiceApi').headServicePayloads(config, serviceName, opts) }, createServicePayload: async (serviceName, reqBody) => { return require('./src/ServiceApi').createServicePayload(config, serviceName, reqBody) diff --git a/package-lock.json b/package-lock.json index ef02bde..68db3ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,115 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.0.0-beta.51", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.51.tgz", + "integrity": "sha1-vXHZsZKvl435FYKdOdQJRFZDmgw=", + "dev": true, + "requires": { + "@babel/highlight": "7.0.0-beta.51" + } + }, + "@babel/generator": { + "version": "7.0.0-beta.51", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.51.tgz", + "integrity": "sha1-bHV1/952HQdIXgS67cA5LG2eMPY=", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.51", + "jsesc": "^2.5.1", + "lodash": "^4.17.5", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-function-name": { + "version": "7.0.0-beta.51", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.51.tgz", + "integrity": "sha1-IbSHSiJ8+Z7K/MMKkDAtpaJkBWE=", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "7.0.0-beta.51", + "@babel/template": "7.0.0-beta.51", + "@babel/types": "7.0.0-beta.51" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0-beta.51", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.51.tgz", + "integrity": "sha1-MoGy0EWvlcFyzpGyCCXYXqRnZBE=", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.51" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0-beta.51", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.51.tgz", + "integrity": "sha1-imw/ZsTSZTUvwHdIT59ugKUauXg=", + "dev": true, + "requires": { + "@babel/types": "7.0.0-beta.51" + } + }, + "@babel/highlight": { + "version": "7.0.0-beta.51", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.51.tgz", + "integrity": "sha1-6IRK4loVlcz9QriWI7Q3bKBtIl0=", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^3.0.0" + } + }, + "@babel/parser": { + "version": "7.0.0-beta.51", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.0.0-beta.51.tgz", + "integrity": "sha1-J87C30Cd9gr1gnDtj2qlVAnqhvY=", + "dev": true + }, + "@babel/template": { + "version": "7.0.0-beta.51", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.51.tgz", + "integrity": "sha1-lgKkCuvPNXrpZ34lMu9fyBD1+/8=", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.51", + "@babel/parser": "7.0.0-beta.51", + "@babel/types": "7.0.0-beta.51", + "lodash": "^4.17.5" + } + }, + "@babel/traverse": { + "version": "7.0.0-beta.51", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.51.tgz", + "integrity": "sha1-mB2vLOw0emIx06odnhgDsDqqpKg=", + "dev": true, + "requires": { + "@babel/code-frame": "7.0.0-beta.51", + "@babel/generator": "7.0.0-beta.51", + "@babel/helper-function-name": "7.0.0-beta.51", + "@babel/helper-split-export-declaration": "7.0.0-beta.51", + "@babel/parser": "7.0.0-beta.51", + "@babel/types": "7.0.0-beta.51", + "debug": "^3.1.0", + "globals": "^11.1.0", + "invariant": "^2.2.0", + "lodash": "^4.17.5" + } + }, + "@babel/types": { + "version": "7.0.0-beta.51", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.51.tgz", + "integrity": "sha1-2AK3tUO1g2x3iqaReXq/APPZfqk=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.5", + "to-fast-properties": "^2.0.0" + } + }, "@types/body-parser": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.0.tgz", @@ -190,6 +299,12 @@ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -306,6 +421,12 @@ "concat-map": "0.0.1" } }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -348,6 +469,29 @@ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chai-as-promised": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", + "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "dev": true, + "requires": { + "check-error": "^1.0.2" + } + }, "chalk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", @@ -385,6 +529,12 @@ "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", "dev": true }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", @@ -449,6 +599,12 @@ "delayed-stream": "~1.0.0" } }, + "commander": { + "version": "2.15.1", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", @@ -528,6 +684,15 @@ "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=", "dev": true }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -599,6 +764,12 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -1148,6 +1319,12 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, "get-stdin": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", @@ -1216,6 +1393,12 @@ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -1260,6 +1443,12 @@ "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", "dev": true }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, "hoek": { "version": "2.16.3", "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", @@ -1349,6 +1538,15 @@ "through": "^2.3.6" } }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -1462,6 +1660,35 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-nPvSZsVlbG9aLhZYaC3Oi1gT/tpyo3Yt5fNyf6NmcKIayz4VV/txxJFFKAK/gU4dcNn8ehsanBbVHVl0+amOLA==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-2.3.2.tgz", + "integrity": "sha512-l7TD/VnBsIB2OJvSyxaLW/ab1+92dxZNH9wLH7uHPPioy3JZ8tnx2UXUdKmdkgmP2EFPzg64CToUP6dAS3U32Q==", + "dev": true, + "requires": { + "@babel/generator": "7.0.0-beta.51", + "@babel/parser": "7.0.0-beta.51", + "@babel/template": "7.0.0-beta.51", + "@babel/traverse": "7.0.0-beta.51", + "@babel/types": "7.0.0-beta.51", + "istanbul-lib-coverage": "^2.0.1", + "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", + "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", + "dev": true + } + } + }, "joi": { "version": "6.10.1", "resolved": "http://registry.npmjs.org/joi/-/joi-6.10.1.tgz", @@ -1499,6 +1726,12 @@ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, + "jsesc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.1.tgz", + "integrity": "sha1-5CGiqOINawgZ3yiQj3glJrlt0f4=", + "dev": true + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -1771,6 +2004,65 @@ "minimist": "0.0.8" } }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "moment": { "version": "2.22.2", "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", @@ -1834,126 +2126,1257 @@ "validate-npm-package-license": "^3.0.1" } }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "nyc": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.0.1.tgz", + "integrity": "sha512-Op/bjhEF74IMtzMmgYt+ModTeMHoPZzHe4qseUguPBwg5qC6r4rYMBt1L3yRXQIbjUpEqmn24/1xAC/umQGU7w==", "dev": true, "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-type": { + "archy": "^1.0.0", + "arrify": "^1.0.1", + "caching-transform": "^2.0.0", + "convert-source-map": "^1.5.1", + "debug-log": "^1.0.1", + "find-cache-dir": "^2.0.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.2", + "istanbul-lib-coverage": "^2.0.1", + "istanbul-lib-hook": "^2.0.1", + "istanbul-lib-instrument": "^2.3.2", + "istanbul-lib-report": "^2.0.1", + "istanbul-lib-source-maps": "^2.0.1", + "istanbul-reports": "^2.0.0", + "make-dir": "^1.3.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.0.0", + "uuid": "^3.3.2", + "yargs": "11.1.0", + "yargs-parser": "^9.0.2" + }, + "dependencies": { + "align-text": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + } + }, + "amdefine": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "append-transform": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "arrify": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "async": { + "version": "1.5.2", + "bundled": true, + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "caching-transform": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "make-dir": "^1.0.0", + "md5-hex": "^2.0.0", + "package-hash": "^2.0.0", + "write-file-atomic": "^2.0.0" + } + }, + "camelcase": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true + }, + "center-align": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "cliui": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "commondir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "convert-source-map": { + "version": "1.5.1", + "bundled": true, + "dev": true + }, + "cross-spawn": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "debug": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "debug-log": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, + "error-ex": { + "version": "1.3.2", + "bundled": true, + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-error": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "execa": { + "version": "0.7.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + } + } + }, + "find-cache-dir": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "foreground-child": { + "version": "1.5.6", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true, + "dev": true + }, + "handlebars": { + "version": "4.0.11", + "bundled": true, + "dev": true, + "requires": { + "async": "^1.4.0", + "optimist": "^0.6.1", + "source-map": "^0.4.4", + "uglify-js": "^2.6" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "bundled": true, + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "has-flag": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "hosted-git-info": { + "version": "2.7.1", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "bundled": true, + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "istanbul-lib-coverage": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-report": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.1", + "make-dir": "^1.3.0", + "supports-color": "^5.4.0" + } + }, + "istanbul-lib-source-maps": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "debug": "^3.1.0", + "istanbul-lib-coverage": "^2.0.1", + "make-dir": "^1.3.0", + "rimraf": "^2.6.2", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "handlebars": "^4.0.11" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "lazy-cache": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "lcid": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash.flattendeep": { + "version": "4.4.0", + "bundled": true, + "dev": true + }, + "longest": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "4.1.3", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "md5-hex": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "md5-o-matic": "^0.1.1" + } + }, + "md5-o-matic": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "mem": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "merge-source-map": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "mimic-fn": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.10", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + } + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "package-hash": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "lodash.flattendeep": "^4.4.0", + "md5-hex": "^2.0.0", + "release-zalgo": "^1.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-type": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "release-zalgo": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "repeat-string": { + "version": "1.6.1", + "bundled": true, + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "right-align": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "align-text": "^0.1.1" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.0.5" + } + }, + "semver": { + "version": "5.5.0", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "source-map": { + "version": "0.5.7", + "bundled": true, + "dev": true, + "optional": true + }, + "spawn-wrap": { + "version": "1.4.2", + "bundled": true, + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "spdx-correct": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "test-exclude": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "arrify": "^1.0.1", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^1.0.1" + } + }, + "uglify-js": { + "version": "2.8.29", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "yargs": { + "version": "3.10.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "uuid": { + "version": "3.3.2", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "window-size": { + "version": "0.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "wordwrap": { + "version": "0.0.3", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "y18n": { + "version": "3.2.1", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "11.1.0", + "bundled": true, + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^9.0.2" + }, + "dependencies": { + "cliui": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "bundled": true, + "dev": true + } + } + }, + "yargs-parser": { + "version": "9.0.2", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "^4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "bundled": true, + "dev": true + } + } + } + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", @@ -1962,6 +3385,12 @@ "pify": "^2.0.0" } }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -2320,6 +3749,12 @@ "is-fullwidth-code-point": "^2.0.0" } }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, "spdx-correct": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.1.tgz", @@ -2567,6 +4002,12 @@ "os-tmpdir": "~1.0.2" } }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, "topo": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz", @@ -2584,6 +4025,12 @@ "punycode": "^1.4.1" } }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -2607,6 +4054,12 @@ "prelude-ls": "~1.1.2" } }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", diff --git a/package.json b/package.json index 4d842a9..43d1dfa 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,9 @@ "main": "index.js", "scripts": { "lint": "standard", - "lint:fix": "standard --fix" + "lint:fix": "standard --fix", + "test": "mocha test/*.test.js --exit", + "cov": "nyc --reporter=html --reporter=text mocha test/*.test.js --exit" }, "dependencies": { "joi": "^13.4.0", @@ -14,6 +16,15 @@ "tc-core-library-js": "appirio-tech/tc-core-library-js.git#feature/m2mtoken" }, "devDependencies": { + "chai": "^4.2.0", + "chai-as-promised": "^7.1.1", + "mocha": "^5.2.0", + "nyc": "^13.0.1", "standard": "^12.0.1" + }, + "standard": { + "env": [ + "mocha" + ] } } diff --git a/src/ServiceApi.js b/src/ServiceApi.js index f10cd64..e7a60d2 100644 --- a/src/ServiceApi.js +++ b/src/ServiceApi.js @@ -9,8 +9,9 @@ const helper = require('./common/helper') * @param {Object} config Configuration object * @returns {Promise} */ -const getServices = async (config) => { - return helper.reqToBusAPI(config, 'GET', `${config.BUSAPI_URL}/bus/services`, null) +const getServices = async (config, opts) => { + const url = helper.buildURLwithParams(`${config.BUSAPI_URL}/bus/services`, opts) + return helper.reqToBusAPI(config, 'GET', url, null) } /** @@ -18,8 +19,9 @@ const getServices = async (config) => { * @param {Object} config Configuration object * @returns {Promise} */ -const headServices = async (config) => { - return helper.reqToBusAPI(config, 'HEAD', `${config.BUSAPI_URL}/bus/services`, null) +const headServices = async (config, opts) => { + const url = helper.buildURLwithParams(`${config.BUSAPI_URL}/bus/services`, opts) + return helper.reqToBusAPI(config, 'HEAD', url, null) } /** @@ -90,8 +92,9 @@ const deleteService = async (config, serviceName) => { * @param {String} serviceName Service name * @returns {Promise} */ -const getServicePayloads = async (config, serviceName) => { - return helper.reqToBusAPI(config, 'GET', `${config.BUSAPI_URL}/bus/services/${serviceName}/payloads`, null) +const getServicePayloads = async (config, serviceName, opts) => { + const url = helper.buildURLwithParams(`${config.BUSAPI_URL}/bus/services/${serviceName}/payloads`, opts) + return helper.reqToBusAPI(config, 'GET', url, null) } /** @@ -100,8 +103,9 @@ const getServicePayloads = async (config, serviceName) => { * @param {String} serviceName Service name * @returns {Promise} */ -const headServicePayloads = async (config, serviceName) => { - return helper.reqToBusAPI(config, 'HEAD', `${config.BUSAPI_URL}/bus/services/${serviceName}/payloads`, null) +const headServicePayloads = async (config, serviceName, opts) => { + const url = helper.buildURLwithParams(`${config.BUSAPI_URL}/bus/services/${serviceName}/payloads`, opts) + return helper.reqToBusAPI(config, 'HEAD', url, null) } /** diff --git a/src/common/helper.js b/src/common/helper.js index 89355b0..ddea845 100644 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -62,6 +62,23 @@ const reqToBusAPI = async (config, reqType, path, reqBody) => { }) } +/* + * Function to build URL with query parameters + * @param {String} url Bus API URL + * @param {Object} params Query parameters + * @returns {String} URL with query parameters + */ +const buildURLwithParams = (url, params) => { + let queryParams = '?' + if (params) { + for (let key in params) { + queryParams += `${key}=${params[key]}&` + } + } + return url + queryParams +} + module.exports = { - reqToBusAPI + reqToBusAPI, + buildURLwithParams } diff --git a/test/EventsApi.test.js b/test/EventsApi.test.js new file mode 100644 index 0000000..fb91a8b --- /dev/null +++ b/test/EventsApi.test.js @@ -0,0 +1,76 @@ +/* + * Tests for Events API + */ + +const _ = require('lodash') +const chai = require('chai') +const chaiAsPromised = require('chai-as-promised') +const { testEvent } = require('./testData') + +chai.should() +chai.use(chaiAsPromised) + +const busApi = require('../index') + +const config = { + AUTH0_CLIENT_ID: process.env.TEST_AUTH0_CLIENT_ID, + AUTH0_CLIENT_SECRET: process.env.TEST_AUTH0_CLIENT_SECRET, + AUTH0_URL: process.env.TEST_AUTH0_URL, + AUTH0_AUDIENCE: process.env.TEST_AUTH0_AUDIENCE, + BUSAPI_URL: process.env.TEST_BUS_API_URL, + KAFKA_ERROR_TOPIC: process.env.TEST_KAFKA_ERROR_TOPIC +} + +const busApiClient = busApi(config) + +describe('Events API Tests', async () => { + describe('Tests for postEvent', async () => { + it('postEvent should be rejected with 400 if the topic is missing', async () => { + await busApiClient.postEvent(_.omit(testEvent, ['topic'])).should.be.rejectedWith('Bad Request') + }).timeout(10000) + + it('postEvent should be rejected with 400 if the originator is missing', async () => { + await busApiClient.postEvent(_.omit(testEvent, ['originator'])).should.be.rejectedWith('Bad Request') + }).timeout(10000) + + it('postEvent should be rejected with 400 if the timestamp is missing', async () => { + await busApiClient.postEvent(_.omit(testEvent, ['timestamp'])).should.be.rejectedWith('Bad Request') + }).timeout(10000) + + it('postEvent should be rejected with 400 if the mime-type is missing', async () => { + await busApiClient.postEvent(_.omit(testEvent, ['mime-type'])).should.be.rejectedWith('Bad Request') + }).timeout(10000) + + it('postEvent should be rejected with 400 if the payload is missing', async () => { + await busApiClient.postEvent(_.omit(testEvent, ['payload'])).should.be.rejectedWith('Bad Request') + }).timeout(10000) + + it('postEvent should return 204 if the valid event is posted to Bus', async () => { + const result = await busApiClient.postEvent(testEvent) + result.statusCode.should.be.eql(204) + }).timeout(10000) + }) + + describe('Tests for postError', async () => { + it('postError should be rejected with 400 if the originator is missing', async () => { + await busApiClient.postError(_.omit(testEvent, ['originator'])).should.be.rejectedWith('Bad Request') + }).timeout(10000) + + it('postError should be rejected with 400 if the timestamp is missing', async () => { + await busApiClient.postError(_.omit(testEvent, ['timestamp'])).should.be.rejectedWith('Bad Request') + }).timeout(10000) + + it('postError should be rejected with 400 if the mime-type is missing', async () => { + await busApiClient.postError(_.omit(testEvent, ['mime-type'])).should.be.rejectedWith('Bad Request') + }).timeout(10000) + + it('postError should be rejected with 400 if the payload is missing', async () => { + await busApiClient.postError(_.omit(testEvent, ['payload'])).should.be.rejectedWith('Bad Request') + }).timeout(10000) + + it('postError should return 204 if the valid event is posted to Bus', async () => { + const result = await busApiClient.postError(testEvent) + result.statusCode.should.be.eql(204) + }).timeout(10000) + }) +}) diff --git a/test/HealthChecksApi.test.js b/test/HealthChecksApi.test.js new file mode 100644 index 0000000..c9a215a --- /dev/null +++ b/test/HealthChecksApi.test.js @@ -0,0 +1,40 @@ +/* + * Tests for Events API + */ + +const chai = require('chai') +const chaiAsPromised = require('chai-as-promised') + +chai.should() +chai.use(chaiAsPromised) + +const busApi = require('../index') + +const config = { + AUTH0_CLIENT_ID: process.env.TEST_AUTH0_CLIENT_ID, + AUTH0_CLIENT_SECRET: process.env.TEST_AUTH0_CLIENT_SECRET, + AUTH0_URL: process.env.TEST_AUTH0_URL, + AUTH0_AUDIENCE: process.env.TEST_AUTH0_AUDIENCE, + BUSAPI_URL: process.env.TEST_BUS_API_URL, + KAFKA_ERROR_TOPIC: process.env.TEST_KAFKA_ERROR_TOPIC +} + +const busApiClient = busApi(config) + +describe('Health Check API Tests', async () => { + describe('Tests for getHealth', async () => { + it('getHealth should return 200 with health status', async () => { + const result = await busApiClient.getHealth() + result.statusCode.should.be.eql(200) + result.body.health.should.be.eql('ok') + }).timeout(10000) + }) + + describe('Tests for headHealth', async () => { + it('headHealth should return 200 with empty body', async () => { + const result = await busApiClient.headHealth() + result.statusCode.should.be.eql(200) + result.body.should.be.eql({}) + }).timeout(10000) + }) +}) diff --git a/test/PlaceholdersApi.test.js b/test/PlaceholdersApi.test.js new file mode 100644 index 0000000..ee493e3 --- /dev/null +++ b/test/PlaceholdersApi.test.js @@ -0,0 +1,32 @@ +/* + * Tests for Events API + */ + +const chai = require('chai') +const chaiAsPromised = require('chai-as-promised') + +chai.should() +chai.use(chaiAsPromised) + +const busApi = require('../index') + +const config = { + AUTH0_CLIENT_ID: process.env.TEST_AUTH0_CLIENT_ID, + AUTH0_CLIENT_SECRET: process.env.TEST_AUTH0_CLIENT_SECRET, + AUTH0_URL: process.env.TEST_AUTH0_URL, + AUTH0_AUDIENCE: process.env.TEST_AUTH0_AUDIENCE, + BUSAPI_URL: process.env.TEST_BUS_API_URL, + KAFKA_ERROR_TOPIC: process.env.TEST_KAFKA_ERROR_TOPIC +} + +const busApiClient = busApi(config) + +describe('Placeholders API Tests', async () => { + describe('Tests for clearPlaceholdersCache', async () => { + // TODO: Swagger says that Return code is 204, but API returns 200 + it('clearPlaceholdersCache should return 200 if the call is successful', async () => { + const result = await busApiClient.clearPlaceholdersCache() + result.statusCode.should.be.eql(200) + }).timeout(10000) + }) +}) diff --git a/test/TopicsApi.test.js b/test/TopicsApi.test.js new file mode 100644 index 0000000..25d1b28 --- /dev/null +++ b/test/TopicsApi.test.js @@ -0,0 +1,40 @@ +/* + * Tests for Events API + */ + +const chai = require('chai') +const chaiAsPromised = require('chai-as-promised') + +chai.should() +chai.use(chaiAsPromised) + +const busApi = require('../index') + +const config = { + AUTH0_CLIENT_ID: process.env.TEST_AUTH0_CLIENT_ID, + AUTH0_CLIENT_SECRET: process.env.TEST_AUTH0_CLIENT_SECRET, + AUTH0_URL: process.env.TEST_AUTH0_URL, + AUTH0_AUDIENCE: process.env.TEST_AUTH0_AUDIENCE, + BUSAPI_URL: process.env.TEST_BUS_API_URL, + KAFKA_ERROR_TOPIC: process.env.TEST_KAFKA_ERROR_TOPIC +} + +const busApiClient = busApi(config) + +describe('Topics API Tests', async () => { + describe('Tests for getTopics', async () => { + it('getTopics should return 200 with array of topics', async () => { + const result = await busApiClient.getTopics() + result.statusCode.should.be.eql(200) + result.body.should.be.an('array') + }).timeout(10000) + }) + + describe('Tests for headTopics', async () => { + it('headTopics should return 200 with empty body', async () => { + const result = await busApiClient.headTopics() + result.statusCode.should.be.eql(200) + result.body.should.be.eql({}) + }).timeout(10000) + }) +}) diff --git a/test/testData.js b/test/testData.js new file mode 100644 index 0000000..7a3713b --- /dev/null +++ b/test/testData.js @@ -0,0 +1,17 @@ +/* + * Test data + */ + +const testEvent = { + 'topic': 'submission.notification.create', + 'originator': 'submission-api', + 'timestamp': '2018-05-20T07:00:30.123Z', + 'mime-type': 'application/json', + 'payload': { + 'name': 'test' + } +} + +module.exports = { + testEvent +}