diff --git a/.eslintignore b/.eslintignore index d849ec6cc..91cef1057 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,12 +3,26 @@ src/**/*.d.ts src/**/*.js.map src/Kuzzle.js +src/KuzzleError.js src/controllers/Auth.js src/controllers/Document.js +src/controllers/Realtime.js +src/controllers/Index.js +src/controllers/Collection.js src/controllers/Base.js src/core/security/User.js src/core/security/Profile.js src/core/security/Role.js +src/protocols/abstract/Base.js +src/protocols/abstract/Realtime.js +src/protocols/Http.js +src/protocols/WebSocket.js +src/protocols/index.js src/utils/interfaces.js +src/core/KuzzleEventEmitter.js src/core/searchResult/SearchResultBase.js src/core/searchResult/Document.js +src/core/searchResult/Profile.js +src/core/searchResult/Role.js +src/core/searchResult/Specifications.js +src/core/searchResult/User.js diff --git a/.eslintc-ts.json b/.eslintrc-ts.json similarity index 100% rename from .eslintc-ts.json rename to .eslintrc-ts.json diff --git a/.gitignore b/.gitignore index 1a1af6994..1f5aa706a 100644 --- a/.gitignore +++ b/.gitignore @@ -31,12 +31,26 @@ test-*.js *.js.map index.js src/Kuzzle.js +src/KuzzleError.js src/controllers/Auth.js src/controllers/Document.js +src/controllers/Index.js +src/controllers/Collection.js src/controllers/Base.js +src/controllers/Realtime.js src/core/security/User.js src/core/security/Profile.js src/core/security/Role.js +src/protocols/abstract/Base.js +src/protocols/abstract/Realtime.js +src/protocols/Http.js +src/protocols/WebSocket.js +src/protocols/index.js src/utils/interfaces.js +src/core/KuzzleEventEmitter.js src/core/searchResult/SearchResultBase.js src/core/searchResult/Document.js +src/core/searchResult/Profile.js +src/core/searchResult/Role.js +src/core/searchResult/Specifications.js +src/core/searchResult/User.js diff --git a/.travis.yml b/.travis.yml index aa2ac4cef..e932f0495 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,6 +32,7 @@ jobs: install: - npm install + - npm run build script: - npm run test:lint @@ -78,7 +79,7 @@ jobs: - npm install - npm run build script: - - npm run doc-testing + - travis_retry npm run doc-testing - stage: Tests name: Dead link check @@ -93,7 +94,7 @@ jobs: - $(npm bin)/kuzdoc framework:link -d /sdk/js/7/ -v 7 script: - gem install typhoeus - - cd doc/framework/ && HYDRA_MAX_CONCURRENCY=20 ruby .ci/dead-links.rb -p src/sdk/js/7/ + - cd doc/framework/ && HYDRA_MAX_CONCURRENCY=20 travis_retry ruby .ci/dead-links.rb -p src/sdk/js/7/ - stage: Deployment Doc Dev name: Deploy next-docs.kuzzle.io diff --git a/doc/7/controllers/auth/create-api-key/index.md b/doc/7/controllers/auth/create-api-key/index.md index d7a2ca918..f0f301b9f 100644 --- a/doc/7/controllers/auth/create-api-key/index.md +++ b/doc/7/controllers/auth/create-api-key/index.md @@ -56,7 +56,7 @@ The API key content has the following properties: | Name | Type | Description | | --------- | ----------------- | ---------------- | | `userId` |
string
| User kuid | -| `expiresAt` |
number
| Expiration date in UNIX micro-timestamp format (`-1` if the token never expires) | +| `expiresAt` |
number
| Expiration date in Epoch-millis format (`-1` if the token never expires) | | `ttl` |
number
| Original TTL | | `description` |
string
| API key description | | `token` |
string
| Authentication token associated with this API key | diff --git a/doc/7/controllers/auth/create-api-key/snippets/create-api-key.test.yml b/doc/7/controllers/auth/create-api-key/snippets/create-api-key.test.yml index 40db9afa6..96029d0b1 100644 --- a/doc/7/controllers/auth/create-api-key/snippets/create-api-key.test.yml +++ b/doc/7/controllers/auth/create-api-key/snippets/create-api-key.test.yml @@ -2,7 +2,7 @@ name: auth#createApiKey description: Creates a new API key for the currently loggued user. hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": ["default"] }, diff --git a/doc/7/controllers/auth/delete-api-key/snippets/delete-api-key.js b/doc/7/controllers/auth/delete-api-key/snippets/delete-api-key.js index e6f1feb2b..7a91a2109 100644 --- a/doc/7/controllers/auth/delete-api-key/snippets/delete-api-key.js +++ b/doc/7/controllers/auth/delete-api-key/snippets/delete-api-key.js @@ -1,5 +1,5 @@ try { - await kuzzle.auth.login('local', { username: 'john.doe', password: 'password' }); + await kuzzle.auth.login('local', { username: 'jane.doe', password: 'password' }); await kuzzle.auth.deleteApiKey('fQRa28BsidO6V_wmOcL'); diff --git a/doc/7/controllers/auth/delete-api-key/snippets/delete-api-key.test.yml b/doc/7/controllers/auth/delete-api-key/snippets/delete-api-key.test.yml index 7dbd119ef..96797828a 100644 --- a/doc/7/controllers/auth/delete-api-key/snippets/delete-api-key.test.yml +++ b/doc/7/controllers/auth/delete-api-key/snippets/delete-api-key.test.yml @@ -2,23 +2,23 @@ name: auth#deleteApiKey description: Deletes an API key for the currently loggued user hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": ["default"] }, "credentials": { "local": { - "username": "john.doe", + "username": "jane.doe", "password": "password" } } - }' "kuzzle:7512/users/john.doe/_create?refresh=wait_for" + }' "kuzzle:7512/users/jane.doe/_create?refresh=wait_for" && curl -XPOST -H "Content-type: application/json" -d '{ "description": "Sigfox API key" - }' "kuzzle:7512/users/john.doe/api-keys/_create?_id=fQRa28BsidO6V_wmOcL&refresh=wait_for" + }' "kuzzle:7512/users/jane.doe/api-keys/_create?_id=fQRa28BsidO6V_wmOcL&refresh=wait_for" after: - curl -XDELETE kuzzle:7512/users/john.doe + curl -XDELETE kuzzle:7512/users/jane.doe template: default expected: - API key successfully deleted diff --git a/doc/7/controllers/auth/search-api-keys/snippets/search-api-keys.js b/doc/7/controllers/auth/search-api-keys/snippets/search-api-keys.js index a8b0981c3..f558bf8d0 100644 --- a/doc/7/controllers/auth/search-api-keys/snippets/search-api-keys.js +++ b/doc/7/controllers/auth/search-api-keys/snippets/search-api-keys.js @@ -1,22 +1,22 @@ try { const promises = []; - // Create some API keys for user "john.doe" + // Create some API keys for user "jared.doe" promises.push( - kuzzle.security.createApiKey('john.doe', 'Sigfox API key')); + kuzzle.security.createApiKey('jared.doe', 'Sigfox API key')); promises.push( - kuzzle.security.createApiKey('john.doe', 'LoRa 6 month API key', { + kuzzle.security.createApiKey('jared.doe', 'LoRa 6 month API key', { expiresIn: '6m' })); promises.push( - kuzzle.security.createApiKey('john.doe', 'LoRa permanent API key', { + kuzzle.security.createApiKey('jared.doe', 'LoRa permanent API key', { refresh: 'wait_for' })); await Promise.all(promises); - // Log as "john.doe" - await kuzzle.auth.login('local', { username: 'john.doe', password: 'password' }); + // Log as "jared.doe" + await kuzzle.auth.login('local', { username: 'jared.doe', password: 'password' }); const results = await kuzzle.auth.searchApiKeys({ match: { @@ -33,7 +33,7 @@ try { "_id": "znEwbG8BJASM_0-bWU-q", "_source": { "description": "LoRa permanent API key", - "userId": "john.doe", + "userId": "jared.doe", "expiresAt": -1, "ttl": -1 } @@ -42,7 +42,7 @@ try { "_id": "zXEwbG8BJASM_0-bWU-q", "_source": { "description": "LoRa 1 year API key", - "userId": "john.doe", + "userId": "jared.doe", "expiresAt": 31557600000, "ttl": 360000 } diff --git a/doc/7/controllers/auth/search-api-keys/snippets/search-api-keys.test.yml b/doc/7/controllers/auth/search-api-keys/snippets/search-api-keys.test.yml index f6eca283f..49723656e 100644 --- a/doc/7/controllers/auth/search-api-keys/snippets/search-api-keys.test.yml +++ b/doc/7/controllers/auth/search-api-keys/snippets/search-api-keys.test.yml @@ -2,19 +2,19 @@ name: auth#searchApiKeys description: Searches API keys for the currently loggued user. hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": ["default"] }, "credentials": { "local": { - "username": "john.doe", + "username": "jared.doe", "password": "password" } } - }' "kuzzle:7512/users/john.doe/_create?refresh=wait_for" + }' "kuzzle:7512/users/jared.doe/_create?refresh=wait_for" after: - curl -XDELETE kuzzle:7512/users/john.doe + curl -XDELETE kuzzle:7512/users/jared.doe template: default expected: - Found 2 API keys matching "LoRa" diff --git a/doc/7/controllers/bulk/delete-by-query/snippets/delete-by-query.test.yml b/doc/7/controllers/bulk/delete-by-query/snippets/delete-by-query.test.yml index f1a308132..429878101 100644 --- a/doc/7/controllers/bulk/delete-by-query/snippets/delete-by-query.test.yml +++ b/doc/7/controllers/bulk/delete-by-query/snippets/delete-by-query.test.yml @@ -7,11 +7,11 @@ hooks: curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi for i in 1 2 3 4 5; do - curl -H "Content-type: application/json" -d '{"capacity": 4}' kuzzle:7512/nyc-open-data/yellow-taxi/_create + curl --fail -H "Content-type: application/json" -d '{"capacity": 4}' kuzzle:7512/nyc-open-data/yellow-taxi/_create done for i in 1 2 3 4 5; do - curl -H "Content-type: application/json" -d '{"capacity": 7}' kuzzle:7512/nyc-open-data/yellow-taxi/_create + curl --fail -H "Content-type: application/json" -d '{"capacity": 7}' kuzzle:7512/nyc-open-data/yellow-taxi/_create done curl -XPOST kuzzle:7512/nyc-open-data/yellow-taxi/_refresh diff --git a/doc/7/controllers/collection/create/index.md b/doc/7/controllers/collection/create/index.md index 68ada4bda..4346f2a6d 100644 --- a/doc/7/controllers/collection/create/index.md +++ b/doc/7/controllers/collection/create/index.md @@ -7,17 +7,22 @@ description: Create a new collection # create -Creates a new [collection](/core/2/guides/essentials/store-access-data) in Kuzzle via the persistence engine, in the provided index. +Creates a new [collection](/core/2/guides/essentials/store-access-data) in the provided index. You can also provide an optional data mapping that allow you to exploit the full capabilities of our -persistent data storage layer, [ElasticSearch](https://www.elastic.co/elastic-stack) (check here the [mapping capabilities of ElasticSearch](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/mapping.html)). +persistent data storage layer, [ElasticSearch](https://www.elastic.co/elastic-stack) (check here the [mapping capabilities of ElasticSearch](/core/2/guides/essentials/database-mappings/)). This method will only update the mapping if the collection already exists. + + + +You can also provide Elasticsearch [index settings](https://www.elastic.co/guide/en/elasticsearch/reference/7.5/index-modules.html#index-modules-settings) when creating a new collection. +
```js -create(index, collection, [mapping], [options]); +create(index, collection, [definition], [options]); ```
@@ -26,17 +31,48 @@ create(index, collection, [mapping], [options]); | ------------ | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `index` |
string
| Index name | | `collection` |
string
| Collection name | -| `mapping` |
object
| Describes the data mapping to associate to the new collection, using Elasticsearch [mapping format](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/mapping.html) | +| `definition` |
object
| Describes the collection mappings and the ES index settings | | `options` |
object
| Query options | + -### mapping - -An object representing the data mapping of the collection. +### definition +An object containings: + - [collection mappings](/core/2/guides/essentials/database-mappings). + - Elasticsearch [index settings](https://www.elastic.co/guide/en/elasticsearch/reference/7.5/index-modules.html#index-modules-settings) The mapping must have a root field `properties` that contain the mapping definition: ```js -const mapping = { +const definition = { + mappings: { + properties: { + field1: { type: 'text' }, + field2: { + properties: { + nestedField: { type: 'keyword' } + } + } + } + }, + settings: { + + } +}; +``` + + + + + + +### definition + +An object representing the data mappings of the collection. + +The mappings must have a root field `properties` that contain the mappings properties definition: + +```js +const mappings = { properties: { field1: { type: 'text' }, field2: { @@ -50,6 +86,8 @@ const mapping = { More informations about database mappings [here](/core/2/guides/essentials/database-mappings). + + ### options Additional query options diff --git a/doc/7/controllers/collection/create/snippets/create.js b/doc/7/controllers/collection/create/snippets/create.js index 4c10502d6..89cc8a348 100644 --- a/doc/7/controllers/collection/create/snippets/create.js +++ b/doc/7/controllers/collection/create/snippets/create.js @@ -1,4 +1,4 @@ -const mapping = { +const mappings = { properties: { license: { type: 'keyword' }, driver: { @@ -11,7 +11,7 @@ const mapping = { }; try { - await kuzzle.collection.create('nyc-open-data', 'yellow-taxi', mapping); + await kuzzle.collection.create('nyc-open-data', 'yellow-taxi', { mappings }); console.log('Success'); } catch (error) { diff --git a/doc/7/controllers/collection/delete/index.md b/doc/7/controllers/collection/delete/index.md new file mode 100644 index 000000000..3cfa16394 --- /dev/null +++ b/doc/7/controllers/collection/delete/index.md @@ -0,0 +1,32 @@ +--- +code: true +type: page +title: delete +description: Deletes a collection +--- + +# delete + +Deletes a collection. + +
+ +```js +delete(index, collection); +``` + +
+ +| Arguments | Type | Description | +| ------------ | ----------------- | --------------- | +| `index` |
string
| Index name | +| `collection` |
string
| Collection name | + + +## Resolves + +Resolves if the collection is successfully deleted. + +## Usage + +<<< ./snippets/delete-specifications.js diff --git a/doc/7/controllers/collection/delete/snippets/delete-specifications.js b/doc/7/controllers/collection/delete/snippets/delete-specifications.js new file mode 100644 index 000000000..5dc6b5fd9 --- /dev/null +++ b/doc/7/controllers/collection/delete/snippets/delete-specifications.js @@ -0,0 +1,7 @@ +try { + await kuzzle.collection.delete('nyc-open-data', 'yellow-taxi'); + + console.log('Success'); +} catch (error) { + console.error(error.message); +} diff --git a/doc/7/controllers/collection/delete/snippets/delete-specifications.test.yml b/doc/7/controllers/collection/delete/snippets/delete-specifications.test.yml new file mode 100644 index 000000000..69c1d5c18 --- /dev/null +++ b/doc/7/controllers/collection/delete/snippets/delete-specifications.test.yml @@ -0,0 +1,7 @@ +name: collection#delete +description: Delete a collection +hooks: + before: curl -X POST kuzzle:7512/nyc-open-data/_create && curl -X PUT kuzzle:7512/nyc-open-data/yellow-taxi + after: +template: default +expected: Success diff --git a/doc/7/controllers/collection/exists/index.md b/doc/7/controllers/collection/exists/index.md index 8a8000677..012fc4300 100644 --- a/doc/7/controllers/collection/exists/index.md +++ b/doc/7/controllers/collection/exists/index.md @@ -7,7 +7,7 @@ description: Check if collection exists # exists -Check if a collection exists in Kuzzle. +Checks if a collection exists in Kuzzle.
diff --git a/doc/7/controllers/collection/get-mapping/index.md b/doc/7/controllers/collection/get-mapping/index.md index 0f0fdcade..c01a9177e 100644 --- a/doc/7/controllers/collection/get-mapping/index.md +++ b/doc/7/controllers/collection/get-mapping/index.md @@ -30,6 +30,7 @@ Additional query options | Property | Type
(default) | Description | | ---------- | ------------------------------- | ---------------------------------------------------------------------------- | | `queuable` |
boolean

(`true`) | If true, queues the request during downtime, until connected to Kuzzle again | +| `includeKuzzleMeta` |
boolean

(`true`) | If true, the returned mappings will contain [Kuzzle metadata](/core/2/guides/essentials/document-metadata/) | ## Resolves diff --git a/doc/7/controllers/collection/refresh/index.md b/doc/7/controllers/collection/refresh/index.md index b79d97a7d..407f0e6b5 100644 --- a/doc/7/controllers/collection/refresh/index.md +++ b/doc/7/controllers/collection/refresh/index.md @@ -7,7 +7,7 @@ description: Forces an Elasticsearch search index update # refresh -When writing or deleting documents in Kuzzle, the update needs to be indexed before being available in search results. +Refreshes a collection to reindex the written and deleted documents so they are available in search results. :::info A refresh operation comes with some performance costs. diff --git a/doc/7/controllers/collection/update-specifications/index.md b/doc/7/controllers/collection/update-specifications/index.md index af9b1981d..b7947f2d7 100644 --- a/doc/7/controllers/collection/update-specifications/index.md +++ b/doc/7/controllers/collection/update-specifications/index.md @@ -7,7 +7,7 @@ description: Update the validation specifications # updateSpecifications -The updateSpecifications method allows you to create or update the validation specifications for a collection. +Creates or updates the validation specifications for a collection. When the validation specification is not formatted correctly, a detailed error message is returned to help you to debug. diff --git a/doc/7/controllers/collection/update/index.md b/doc/7/controllers/collection/update/index.md index f7edd238a..c39bc0e6b 100644 --- a/doc/7/controllers/collection/update/index.md +++ b/doc/7/controllers/collection/update/index.md @@ -13,28 +13,66 @@ You can define the collection [dynamic mapping policy](/core/2/guides/essentials You can define [collection additional metadata](/core/2/guides/essentials/database-mappings#collection-metadata) within the `_meta` root field. + + + +You can also provide Elasticsearch [index settings](https://www.elastic.co/guide/en/elasticsearch/reference/7.5/index-modules.html#index-modules-settings) when creating a new collection. +
```js -update(index, collection, mapping); +update(index, collection, definition); ```
-| Arguments | Type | Description | -| ------------ | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `index` |
string
| Index name | -| `collection` |
string
| Collection name | -| `mapping` |
object
| Describes the collection mapping | +| Arguments | Type | Description | +|--------------|-------------------|-------------------------------------------------------------| +| `index` |
string
| Index name | +| `collection` |
string
| Collection name | +| `definition` |
object
| Describes the collection mappings and the ES index settings | +| `options` |
object
| Query options | + + -### mapping +### definition -An object representing the collection data mapping. +An object containing: + - [collection mappings](/core/2/guides/essentials/database-mappings). + - Elasticsearch [index settings](https://www.elastic.co/guide/en/elasticsearch/reference/7.5/index-modules.html#index-modules-settings) -This object must have a root field `properties` that contain the mapping definition: ```js -const mapping = { +const definition = { + mappings: { + properties: { + field1: { type: 'text' }, + field2: { + properties: { + nestedField: { type: 'keyword' } + } + } + } + }, + settings: { + // index settings (e.g. analyzers) + } +}; +``` + + + + + + +### definition + +An object representing the data mappings of the collection. + +The mappings must have a root field `properties` that contain the mappings properties definition: + +```js +const mappings = { properties: { field1: { type: 'text' }, field2: { @@ -48,6 +86,9 @@ const mapping = { More informations about database mappings [here](/core/2/guides/essentials/database-mappings). + + + ## Resolves Resolve if the collection is successfully updated. diff --git a/doc/7/controllers/collection/validate-specifications/index.md b/doc/7/controllers/collection/validate-specifications/index.md index cd5cf676b..f10474abe 100644 --- a/doc/7/controllers/collection/validate-specifications/index.md +++ b/doc/7/controllers/collection/validate-specifications/index.md @@ -7,7 +7,7 @@ description: Validate specifications format # validateSpecifications -The validateSpecifications method checks if a validation specification is well formatted. It does not store or modify the existing specification. +Checks if a validation specification is well formatted. It does not store nor modify the existing specification. When the validation specification is not formatted correctly, a detailed error message is returned to help you to debug. diff --git a/doc/7/controllers/document/count/snippets/count.test.yml b/doc/7/controllers/document/count/snippets/count.test.yml index bd19e71b0..c9ad44fae 100644 --- a/doc/7/controllers/document/count/snippets/count.test.yml +++ b/doc/7/controllers/document/count/snippets/count.test.yml @@ -7,10 +7,10 @@ hooks: curl -XPOST kuzzle:7512/nyc-open-data/_create curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi for i in 1 2 3 4 5; do - curl -H "Content-type: application/json" -d '{"license": "valid"}' kuzzle:7512/nyc-open-data/yellow-taxi/_create + curl --fail -H "Content-type: application/json" -d '{"license": "valid"}' kuzzle:7512/nyc-open-data/yellow-taxi/_create done for i in 1 2 3 4 5; do - curl -H "Content-type: application/json" -d '{}' kuzzle:7512/nyc-open-data/yellow-taxi/_create + curl --fail -H "Content-type: application/json" -d '{}' kuzzle:7512/nyc-open-data/yellow-taxi/_create done curl -XPOST kuzzle:7512/nyc-open-data/yellow-taxi/_refresh after: diff --git a/doc/7/controllers/document/delete-by-query/snippets/delete-by-query.test.yml b/doc/7/controllers/document/delete-by-query/snippets/delete-by-query.test.yml index a95123d23..a59359403 100644 --- a/doc/7/controllers/document/delete-by-query/snippets/delete-by-query.test.yml +++ b/doc/7/controllers/document/delete-by-query/snippets/delete-by-query.test.yml @@ -7,11 +7,11 @@ hooks: curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi for i in 1 2 3 4 5; do - curl -H "Content-type: application/json" -d '{"capacity": 4}' kuzzle:7512/nyc-open-data/yellow-taxi/_create + curl --fail -H "Content-type: application/json" -d '{"capacity": 4}' kuzzle:7512/nyc-open-data/yellow-taxi/_create done for i in 1 2 3 4 5; do - curl -H "Content-type: application/json" -d '{"capacity": 7}' kuzzle:7512/nyc-open-data/yellow-taxi/_create + curl --fail -H "Content-type: application/json" -d '{"capacity": 7}' kuzzle:7512/nyc-open-data/yellow-taxi/_create done curl -XPOST kuzzle:7512/nyc-open-data/yellow-taxi/_refresh diff --git a/doc/7/controllers/document/delete/snippets/delete.test.yml b/doc/7/controllers/document/delete/snippets/delete.test.yml index e25145e3d..0ce344bb0 100644 --- a/doc/7/controllers/document/delete/snippets/delete.test.yml +++ b/doc/7/controllers/document/delete/snippets/delete.test.yml @@ -5,7 +5,7 @@ hooks: curl -XDELETE kuzzle:7512/nyc-open-data curl -XPOST kuzzle:7512/nyc-open-data/_create curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi - curl -H "Content-type: application/json" -XPUT -d '{}' kuzzle:7512/nyc-open-data/yellow-taxi/some-id + curl --fail -H "Content-type: application/json" -XPUT -d '{}' kuzzle:7512/nyc-open-data/yellow-taxi/some-id after: template: default expected: Success diff --git a/doc/7/controllers/document/update-by-query/snippets/update-by-query.test.yml b/doc/7/controllers/document/update-by-query/snippets/update-by-query.test.yml index a51c40859..7cd7f4704 100644 --- a/doc/7/controllers/document/update-by-query/snippets/update-by-query.test.yml +++ b/doc/7/controllers/document/update-by-query/snippets/update-by-query.test.yml @@ -6,10 +6,10 @@ hooks: curl -XPOST kuzzle:7512/nyc-open-data/_create curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi for i in 1 2 ; do - curl -H "Content-type: application/json" -d '{"capacity": 4}' kuzzle:7512/nyc-open-data/yellow-taxi/document_$i/_create + curl --fail -H "Content-type: application/json" -d '{"capacity": 4}' kuzzle:7512/nyc-open-data/yellow-taxi/document_$i/_create done for i in 1 2 3 4 5; do - curl -H "Content-type: application/json" -d '{"capacity": 7}' kuzzle:7512/nyc-open-data/yellow-taxi/_create + curl --fail -H "Content-type: application/json" -d '{"capacity": 7}' kuzzle:7512/nyc-open-data/yellow-taxi/_create done curl -XPOST kuzzle:7512/nyc-open-data/yellow-taxi/_refresh after: diff --git a/doc/7/controllers/realtime/count/index.md b/doc/7/controllers/realtime/count/index.md index d8beddf88..dd5c460ed 100644 --- a/doc/7/controllers/realtime/count/index.md +++ b/doc/7/controllers/realtime/count/index.md @@ -32,7 +32,7 @@ Additional query options ## Resolves -Resolves to a number represensting active connections using the same provided subscription room. +Resolves to a number representing active connections using the same provided subscription room. ## Usage diff --git a/doc/7/controllers/security/create-api-key/index.md b/doc/7/controllers/security/create-api-key/index.md index 35202ecb1..ae4722cb0 100644 --- a/doc/7/controllers/security/create-api-key/index.md +++ b/doc/7/controllers/security/create-api-key/index.md @@ -57,7 +57,7 @@ The API key content has the following properties: | Name | Type | Description | | --------- | ----------------- | ---------------- | | `userId` |
string
| User kuid | -| `expiresAt` |
number
| Aexpiration date in UNIX micro-timestamp format (`-1` if the token never expires) | +| `expiresAt` |
number
| Aexpiration date in Epoch-millis format (`-1` if the token never expires) | | `ttl` |
number
| Original TTL | | `description` |
string
| API key description | | `token` |
string
| Authentication token associated with this API key | diff --git a/doc/7/controllers/security/create-api-key/snippets/create-api-key.test.yml b/doc/7/controllers/security/create-api-key/snippets/create-api-key.test.yml index 66485aad9..842b41a39 100644 --- a/doc/7/controllers/security/create-api-key/snippets/create-api-key.test.yml +++ b/doc/7/controllers/security/create-api-key/snippets/create-api-key.test.yml @@ -2,7 +2,7 @@ name: security#createApiKey description: Creates a new API key for an user hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": ["default"] } diff --git a/doc/7/controllers/security/delete-api-key/snippets/delete-api-key.test.yml b/doc/7/controllers/security/delete-api-key/snippets/delete-api-key.test.yml index 0ee031be4..a9ae4bb54 100644 --- a/doc/7/controllers/security/delete-api-key/snippets/delete-api-key.test.yml +++ b/doc/7/controllers/security/delete-api-key/snippets/delete-api-key.test.yml @@ -2,7 +2,7 @@ name: security#deleteApiKey description: Deletes an user API key hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": ["default"] } diff --git a/doc/7/controllers/security/delete-credentials/snippets/delete-credentials.test.yml b/doc/7/controllers/security/delete-credentials/snippets/delete-credentials.test.yml index 30e106e2a..18b3bbb36 100644 --- a/doc/7/controllers/security/delete-credentials/snippets/delete-credentials.test.yml +++ b/doc/7/controllers/security/delete-credentials/snippets/delete-credentials.test.yml @@ -2,7 +2,7 @@ name: security#deleteCredentials description: deletes credentials hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": ["default"] }, diff --git a/doc/7/controllers/security/delete-profile/snippets/delete-profile.test.yml b/doc/7/controllers/security/delete-profile/snippets/delete-profile.test.yml index ef4b73bb4..2d8b92d8e 100644 --- a/doc/7/controllers/security/delete-profile/snippets/delete-profile.test.yml +++ b/doc/7/controllers/security/delete-profile/snippets/delete-profile.test.yml @@ -2,7 +2,7 @@ name: security#deleteProfile description: deletes profile hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "policies": [] }' kuzzle:7512/profiles/myProfile/_create template: default diff --git a/doc/7/controllers/security/delete-role/snippets/delete-role.test.yml b/doc/7/controllers/security/delete-role/snippets/delete-role.test.yml index 47f9e3eb1..b2f06efa2 100644 --- a/doc/7/controllers/security/delete-role/snippets/delete-role.test.yml +++ b/doc/7/controllers/security/delete-role/snippets/delete-role.test.yml @@ -2,7 +2,7 @@ name: security#deleteRole description: deletes role hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "controllers": { "*": { "actions": { diff --git a/doc/7/controllers/security/delete-user/snippets/delete-user.test.yml b/doc/7/controllers/security/delete-user/snippets/delete-user.test.yml index f82599c33..764b04c97 100644 --- a/doc/7/controllers/security/delete-user/snippets/delete-user.test.yml +++ b/doc/7/controllers/security/delete-user/snippets/delete-user.test.yml @@ -2,7 +2,7 @@ name: security#deleteUser description: Deletes a user hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": ["default"] }, diff --git a/doc/7/controllers/security/get-credentials-by-id/snippets/get-credentials-by-id.test.yml b/doc/7/controllers/security/get-credentials-by-id/snippets/get-credentials-by-id.test.yml index 073dd18d7..deec2898e 100644 --- a/doc/7/controllers/security/get-credentials-by-id/snippets/get-credentials-by-id.test.yml +++ b/doc/7/controllers/security/get-credentials-by-id/snippets/get-credentials-by-id.test.yml @@ -2,7 +2,7 @@ name: security#getCredentialsById description: get credentials by id hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": ["default"] }, diff --git a/doc/7/controllers/security/get-credentials/snippets/get-credentials.test.yml b/doc/7/controllers/security/get-credentials/snippets/get-credentials.test.yml index d2bb2f8e1..9da59450a 100644 --- a/doc/7/controllers/security/get-credentials/snippets/get-credentials.test.yml +++ b/doc/7/controllers/security/get-credentials/snippets/get-credentials.test.yml @@ -2,7 +2,7 @@ name: security#getCredentials description: get credentials hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": ["default"] }, diff --git a/doc/7/controllers/security/get-profile-rights/snippets/get-profile-rights.test.yml b/doc/7/controllers/security/get-profile-rights/snippets/get-profile-rights.test.yml index 5c7431987..7d0a9cf52 100644 --- a/doc/7/controllers/security/get-profile-rights/snippets/get-profile-rights.test.yml +++ b/doc/7/controllers/security/get-profile-rights/snippets/get-profile-rights.test.yml @@ -2,7 +2,7 @@ name: security#getProfileRights description: get profile rights hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "policies": [ { "roleId": "admin", diff --git a/doc/7/controllers/security/get-profile/snippets/get-profile.test.yml b/doc/7/controllers/security/get-profile/snippets/get-profile.test.yml index 5374523e0..210f1ee28 100644 --- a/doc/7/controllers/security/get-profile/snippets/get-profile.test.yml +++ b/doc/7/controllers/security/get-profile/snippets/get-profile.test.yml @@ -2,7 +2,7 @@ name: security#getProfile description: get profile hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "policies": [ { "roleId": "admin", diff --git a/doc/7/controllers/security/get-role/snippets/get-role.test.yml b/doc/7/controllers/security/get-role/snippets/get-role.test.yml index e17e33b90..eafcd8c95 100644 --- a/doc/7/controllers/security/get-role/snippets/get-role.test.yml +++ b/doc/7/controllers/security/get-role/snippets/get-role.test.yml @@ -2,7 +2,7 @@ name: security#getRole description: get role hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "controllers": { "auth": { "actions": { diff --git a/doc/7/controllers/security/get-user-rights/snippets/get-user-rights.test.yml b/doc/7/controllers/security/get-user-rights/snippets/get-user-rights.test.yml index e0a7de1ec..cda1b8881 100644 --- a/doc/7/controllers/security/get-user-rights/snippets/get-user-rights.test.yml +++ b/doc/7/controllers/security/get-user-rights/snippets/get-user-rights.test.yml @@ -2,7 +2,7 @@ name: security#getUserRights description: get user rights hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": [ "default" ], "fullName": "John Doe" diff --git a/doc/7/controllers/security/get-user/snippets/get-user.test.yml b/doc/7/controllers/security/get-user/snippets/get-user.test.yml index 3857b743f..5171a107e 100644 --- a/doc/7/controllers/security/get-user/snippets/get-user.test.yml +++ b/doc/7/controllers/security/get-user/snippets/get-user.test.yml @@ -2,7 +2,7 @@ name: security#getUser description: get user hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": [ "default" ], "fullName": "John Doe" diff --git a/doc/7/controllers/security/has-credentials/snippets/has-credentials.test.yml b/doc/7/controllers/security/has-credentials/snippets/has-credentials.test.yml index 81f335cd7..8fee898e5 100644 --- a/doc/7/controllers/security/has-credentials/snippets/has-credentials.test.yml +++ b/doc/7/controllers/security/has-credentials/snippets/has-credentials.test.yml @@ -2,7 +2,7 @@ name: security#hasCredentials description: has credentials hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": [ "default" ], "fullName": "John Doe" diff --git a/doc/7/controllers/security/m-delete-profiles/snippets/m-delete-profiles.test.yml b/doc/7/controllers/security/m-delete-profiles/snippets/m-delete-profiles.test.yml index 6fbf0d363..e5aa30556 100644 --- a/doc/7/controllers/security/m-delete-profiles/snippets/m-delete-profiles.test.yml +++ b/doc/7/controllers/security/m-delete-profiles/snippets/m-delete-profiles.test.yml @@ -3,9 +3,9 @@ description: mdelete profiles hooks: before: | for i in 1 2 3 4 5; do - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "policies": [{ "roleId": "default" }] }' kuzzle:7512/profiles/profile${i}/_create done template: default -expected: '^\[ ''profile\d'', ''profile\d'', ''profile\d'', ''profile\d', ''profile\d'' \]$' +expected: '^\[ ''profile\d'', ''profile\d'', ''profile\d'', ''profile\d'', ''profile\d'' \]$' diff --git a/doc/7/controllers/security/m-delete-roles/snippets/m-delete-roles.test.yml b/doc/7/controllers/security/m-delete-roles/snippets/m-delete-roles.test.yml index 5578d3834..e1584334b 100644 --- a/doc/7/controllers/security/m-delete-roles/snippets/m-delete-roles.test.yml +++ b/doc/7/controllers/security/m-delete-roles/snippets/m-delete-roles.test.yml @@ -3,7 +3,7 @@ description: mdelete roles hooks: before: | for i in 1 2 3 4 5; do - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "controllers": { "*": { "actions": { @@ -14,4 +14,4 @@ hooks: }' kuzzle:7512/roles/role${i}/_create done template: default -expected: '^\[ ''role1'', ''role2'', ''role3'', ''role4'', ''role5'' \]$' +expected: '^\[ ''role\d'', ''role\d'', ''role\d'', ''role\d'', ''role\d'' \]$' diff --git a/doc/7/controllers/security/m-delete-users/snippets/m-delete-users.test.yml b/doc/7/controllers/security/m-delete-users/snippets/m-delete-users.test.yml index be9ebea3d..2563308aa 100644 --- a/doc/7/controllers/security/m-delete-users/snippets/m-delete-users.test.yml +++ b/doc/7/controllers/security/m-delete-users/snippets/m-delete-users.test.yml @@ -3,7 +3,7 @@ description: mdelete users hooks: before: | for i in 1 2 3; do - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": [ "default" ] }, @@ -16,4 +16,4 @@ hooks: }' kuzzle:7512/users/user${i}/_create done template: default -expected: '^\[ ''user1'', ''user2'', ''user3'' \]$' +expected: '^\[ ''user\d'', ''user\d'', ''user\d'' \]$' diff --git a/doc/7/controllers/security/m-get-profiles/snippets/m-get-profiles.test.yml b/doc/7/controllers/security/m-get-profiles/snippets/m-get-profiles.test.yml index 35652db1e..df683ef23 100644 --- a/doc/7/controllers/security/m-get-profiles/snippets/m-get-profiles.test.yml +++ b/doc/7/controllers/security/m-get-profiles/snippets/m-get-profiles.test.yml @@ -3,7 +3,7 @@ description: mget profiles hooks: before: | for i in 1 2 3; do - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "policies": [{"roleId": "default"}] }' kuzzle:7512/profiles/profile${i}/_create done diff --git a/doc/7/controllers/security/m-get-roles/snippets/m-get-roles.test.yml b/doc/7/controllers/security/m-get-roles/snippets/m-get-roles.test.yml index 6f2dc043b..b1b4cfe89 100644 --- a/doc/7/controllers/security/m-get-roles/snippets/m-get-roles.test.yml +++ b/doc/7/controllers/security/m-get-roles/snippets/m-get-roles.test.yml @@ -3,7 +3,7 @@ description: mget roles hooks: before: | for i in 1 2 3; do - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "controllers": { "*": { "actions": { diff --git a/doc/7/controllers/security/m-get-users/snippets/m-get-users.test.yml b/doc/7/controllers/security/m-get-users/snippets/m-get-users.test.yml index 58bcc9ee9..11bb312df 100644 --- a/doc/7/controllers/security/m-get-users/snippets/m-get-users.test.yml +++ b/doc/7/controllers/security/m-get-users/snippets/m-get-users.test.yml @@ -3,7 +3,7 @@ description: mget users hooks: before: | for i in 1 2 3; do - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": ["default"], "fullname": "user'${i}'" diff --git a/doc/7/controllers/security/replace-user/snippets/replace-user.test.yml b/doc/7/controllers/security/replace-user/snippets/replace-user.test.yml index 4a1c8e239..07a6c744a 100644 --- a/doc/7/controllers/security/replace-user/snippets/replace-user.test.yml +++ b/doc/7/controllers/security/replace-user/snippets/replace-user.test.yml @@ -2,7 +2,7 @@ name: security#replaceUser description: replace user hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": [ "default" ] }, diff --git a/doc/7/controllers/security/search-api-keys/snippets/search-api-keys.test.yml b/doc/7/controllers/security/search-api-keys/snippets/search-api-keys.test.yml index 91f234349..b6029ecbc 100644 --- a/doc/7/controllers/security/search-api-keys/snippets/search-api-keys.test.yml +++ b/doc/7/controllers/security/search-api-keys/snippets/search-api-keys.test.yml @@ -2,7 +2,7 @@ name: security#searchApiKeys description: Searches for an user API keys hooks: before: > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": ["default"] } diff --git a/doc/7/controllers/security/search-profiles/snippets/search-profiles.test.yml b/doc/7/controllers/security/search-profiles/snippets/search-profiles.test.yml index 8447e0ffd..317755d03 100644 --- a/doc/7/controllers/security/search-profiles/snippets/search-profiles.test.yml +++ b/doc/7/controllers/security/search-profiles/snippets/search-profiles.test.yml @@ -3,7 +3,7 @@ description: search profiles hooks: before: | for i in 1 2 3; do - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "policies": [{ "roleId": "default" }] }' kuzzle:7512/profiles/profile${i}/_create?refresh=wait_for done diff --git a/doc/7/controllers/security/search-users/snippets/search-users.test.yml b/doc/7/controllers/security/search-users/snippets/search-users.test.yml index 31a0b16e3..0fadb2e8d 100644 --- a/doc/7/controllers/security/search-users/snippets/search-users.test.yml +++ b/doc/7/controllers/security/search-users/snippets/search-users.test.yml @@ -3,7 +3,7 @@ description: search users hooks: before: | for i in 1 2 3; do - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "content": { "profileIds": [ "default" ], "status": "student" diff --git a/doc/7/controllers/security/update-credentials/snippets/update-credentials.test.yml b/doc/7/controllers/security/update-credentials/snippets/update-credentials.test.yml index b089d1136..42df29f6d 100644 --- a/doc/7/controllers/security/update-credentials/snippets/update-credentials.test.yml +++ b/doc/7/controllers/security/update-credentials/snippets/update-credentials.test.yml @@ -2,7 +2,7 @@ name: security#updateCredentials description: update credentials hooks: before: > - curl -H "Content-type: application/json" -f -d '{ + curl --fail -H "Content-type: application/json" -f -d '{ "content": { "profileIds": ["default"] }, diff --git a/doc/7/controllers/security/update-profile/snippets/update-profile.test.yml b/doc/7/controllers/security/update-profile/snippets/update-profile.test.yml index 945d3707e..afd0e8ec1 100644 --- a/doc/7/controllers/security/update-profile/snippets/update-profile.test.yml +++ b/doc/7/controllers/security/update-profile/snippets/update-profile.test.yml @@ -3,11 +3,11 @@ description: updates a security profile definition hooks: before: - > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "policies": [] }' kuzzle:7512/profiles/myProfile/_create - > - curl -H "Content-type: application/json" -d '{ + curl --fail -H "Content-type: application/json" -d '{ "controllers": { "*": { "actions": { diff --git a/doc/7/core-classes/kuzzle-error/properties/index.md b/doc/7/core-classes/kuzzle-error/properties/index.md index 1b5655e92..63b07a4f9 100644 --- a/doc/7/core-classes/kuzzle-error/properties/index.md +++ b/doc/7/core-classes/kuzzle-error/properties/index.md @@ -14,3 +14,6 @@ order: 10 | `message` |
string
| Error message | | `status` |
number
| Error status code | | `stack` |
string
| Error stacktrace (only in development mode) | +| `id` |
string
| Error unique identifier | +| `code` |
string
| Error unique code | + diff --git a/doc/7/core-classes/kuzzle/constructor/index.md b/doc/7/core-classes/kuzzle/constructor/index.md index 2203444bc..6f076596f 100644 --- a/doc/7/core-classes/kuzzle/constructor/index.md +++ b/doc/7/core-classes/kuzzle/constructor/index.md @@ -46,6 +46,7 @@ Kuzzle SDK instance options. | `queueTTL` |
number

(`120000`) | Time a queued request is kept during offline mode, in milliseconds | | `queueMaxSize` |
number

(`500`) | Number of maximum requests kept during offline mode | | `replayInterval` |
number

(`10`) | Delay between each replayed requests, in milliseconds | +| `tokenExpiredInterval` |
number

(`1000`) | Time (in ms) during which a TokenExpired event is ignored | | `volatile` |
object

(`{}`) | Common volatile data, will be sent to all future requests | ## Return diff --git a/doc/7/essentials/error-handling/index.md b/doc/7/essentials/error-handling/index.md index f19e943a8..fa56caac4 100644 --- a/doc/7/essentials/error-handling/index.md +++ b/doc/7/essentials/error-handling/index.md @@ -15,7 +15,9 @@ All SDK methods return a promise, that can be rejected with a `KuzzleError` valu | Property | Type | Description | | -------- | ----------------- | ------------------------------------------------------------------------------------------ | | `status` |
number
| Status following [HTTP Standards](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) | -| `stack` |
string
| Error stacktrace (Only in development mode) | +| `stack` |
string
| Error stacktrace (Only in development mode) | `id` |
string
| Error unique identifier | +| `code` |
string
| Error unique code | + You can find a detailed list of possible errors messages and statuses in the [documentation API](/core/2/api/essentials/error-handling). diff --git a/doc/7/essentials/realtime-notifications/index.md b/doc/7/essentials/realtime-notifications/index.md index cdc976ce7..86583db0d 100644 --- a/doc/7/essentials/realtime-notifications/index.md +++ b/doc/7/essentials/realtime-notifications/index.md @@ -23,7 +23,7 @@ These notifications represent [documents changes & messages](/core/2/api/essenti | `protocol` |
string
| Network protocol used to modify the document | | `result` |
object
| Notification content | | `room` |
string
| Subscription channel identifier. Can be used to link a notification to its corresponding subscription | -| `scope` |
string
| `in`: document enters (or stays) in the scope
string | `in`: document enters (or stays) in the scope
`out`: document leaves the scope | | `timestamp` |
number
| Timestamp of the event, in Epoch-millis format | | `type` |
string
| `document`: Notification type | | `volatile` |
object
| Request [volatile data](/core/2/api/essentials/volatile-data) | @@ -50,7 +50,7 @@ These notifications represent [user events](/core/2/api/essentials/notifications | `room` |
string
| Subscription channel identifier. Can be used to link a notification to its corresponding subscription | | `timestamp` |
number
| Timestamp of the event, in Epoch-millis format | | `type` |
string
| `user`: Notification type | -| `user` |
string
| `in`: a new user has subscribed to the same filters
string | `in`: a new user has subscribed to the same filters
`out`: a user cancelled a shared subscription | | `volatile` |
object
| Request [volatile data](/core/2/api/essentials/volatile-data) | The `result` object is the notification content, and it has the following structure: diff --git a/doc/7/protocols/http/constructor/index.md b/doc/7/protocols/http/constructor/index.md index d5ff3892f..a1aaddae1 100644 --- a/doc/7/protocols/http/constructor/index.md +++ b/doc/7/protocols/http/constructor/index.md @@ -30,7 +30,8 @@ Http protocol connection options. | Property | Type
(default) | Description | | --------------- | -------------------------------- | ----------------------------------- | | `port` |
number

(`7512`) | Kuzzle server port | -| `sslConnection` |
boolean

(`false`) | Use SSL to connect to Kuzzle server | +| `sslConnection` |
boolean

(`false`) | Use SSL to connect to Kuzzle server | +| `ssl` |
boolean

(`false`) | Use SSL to connect to Kuzzle server. Defaults to `true` for ports 443 and 7443. | | `customRoutes` |
object

(`{}`) | Add custom routes | | `timeout` |
number

(`0`) | Connection timeout in milliseconds (`0` means no timeout) | diff --git a/doc/7/protocols/websocket/constructor/index.md b/doc/7/protocols/websocket/constructor/index.md index 736df3deb..7f770d046 100644 --- a/doc/7/protocols/websocket/constructor/index.md +++ b/doc/7/protocols/websocket/constructor/index.md @@ -31,9 +31,10 @@ WebSocket protocol connection options. | ------------------- | -------------------------------- | -------------------------------------------------------------------------------------------- | | `autoReconnect` |
boolean

(`true`) | Automatically reconnect to kuzzle after a `disconnected` event | | `port` |
number

(`7512`) | Kuzzle server port | -| `headers` |
object
(`{}`) | Connection HTTP headers (e.g. origin, subprotocols, ...)
**(Not supported by browsers)** | +| `headers` |
object
(`{}`) | Connection custom HTTP headers (e.g. origin, subprotocols, ...)
**(Not supported by browsers)** | | `reconnectionDelay` |
number

(`1000`) | Number of milliseconds between reconnection attempts | -| `sslConnection` |
boolean

(`false`) | Use SSL to connect to Kuzzle server | +| `sslConnection` |
boolean

(`false`) | Use SSL to connect to Kuzzle server | +| `ssl` |
boolean

(`false`) | Use SSL to connect to Kuzzle server. Defaults to `true` for ports 443 and 7443. | ## Return diff --git a/index.ts b/index.ts index b88efa680..dc87dfb68 100644 --- a/index.ts +++ b/index.ts @@ -8,34 +8,15 @@ if (typeof window !== 'undefined' && typeof BUILT === 'undefined') { 'Learn more at https://github.com/kuzzleio/sdk-javascript/tree/master#browser'); } -import { Kuzzle } from './src/Kuzzle'; -import { Http, WebSocket } from './src/protocols'; -import { BaseController } from './src/controllers/Base'; -import { KuzzleAbstractProtocol } from './src/protocols/abstract/Base'; -import { KuzzleEventEmitter } from './src/core/KuzzleEventEmitter'; +export * from './src/Kuzzle'; +export * from './src/protocols'; +export * from './src/controllers/Base'; +export * from './src/protocols/abstract/Base'; +export * from './src/core/KuzzleEventEmitter'; -import { SearchResultBase } from './src/core/searchResult/SearchResultBase'; -import { DocumentSearchResult } from './src/core/searchResult/Document'; -import { ProfileSearchResult } from './src/core/searchResult/Profile'; -import { RoleSearchResult } from './src/core/searchResult/Role'; -import { SpecificationSearchResult } from './src/core/searchResult/Specifications'; -import { UserSearchResult } from './src/core/searchResult/User'; - -const exported = { - Kuzzle, - Http, - WebSocket, - BaseController, - KuzzleAbstractProtocol, - KuzzleEventEmitter, - SearchResultBase, - DocumentSearchResult, - ProfileSearchResult, - RoleSearchResult, - SpecificationSearchResult, - UserSearchResult -} - -export default exported; - -module.exports = exported; +export * from './src/core/searchResult/SearchResultBase'; +export * from './src/core/searchResult/Document'; +export * from './src/core/searchResult/Profile'; +export * from './src/core/searchResult/Role'; +export * from './src/core/searchResult/Specifications'; +export * from './src/core/searchResult/User'; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 87472d4ad..c2d1500f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "kuzzle-sdk", - "version": "7.3.1", + "version": "7.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -14,9 +14,9 @@ } }, "@babel/compat-data": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.10.5.tgz", - "integrity": "sha512-mPVoWNzIpYJHbWje0if7Ck36bpbtTvIxOi9+6WSK9wjGEXearAqlwBoTQvVjsAY2VIwgcs8V940geY3okzRCEw==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.11.0.tgz", + "integrity": "sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ==", "dev": true, "requires": { "browserslist": "^4.12.0", @@ -25,19 +25,19 @@ } }, "@babel/core": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.5.tgz", - "integrity": "sha512-O34LQooYVDXPl7QWCdW9p4NR+QlzOr7xShPPJz8GsuCU3/8ua/wqTr7gmnxXv+WBESiGU/G5s16i6tUvHkNb+w==", + "version": "7.11.1", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.1.tgz", + "integrity": "sha512-XqF7F6FWQdKGGWAzGELL+aCO1p+lRY5Tj5/tbT3St1G8NaH70jhhDIKknIZaDans0OQBG5wRAldROLHSt44BgQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.10.5", - "@babel/helper-module-transforms": "^7.10.5", + "@babel/generator": "^7.11.0", + "@babel/helper-module-transforms": "^7.11.0", "@babel/helpers": "^7.10.4", - "@babel/parser": "^7.10.5", + "@babel/parser": "^7.11.1", "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.5", - "@babel/types": "^7.10.5", + "@babel/traverse": "^7.11.0", + "@babel/types": "^7.11.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", @@ -46,23 +46,15 @@ "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" - }, - "dependencies": { - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", - "dev": true - } } }, "@babel/generator": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.5.tgz", - "integrity": "sha512-3vXxr3FEW7E7lJZiWQ3bM4+v/Vyr9C+hpolQ8BGFr9Y8Ri2tFLWTixmwKBafDujO1WVah4fhZBeU1bieKdghig==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", + "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", "dev": true, "requires": { - "@babel/types": "^7.10.5", + "@babel/types": "^7.11.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" } @@ -133,14 +125,6 @@ "@babel/helper-function-name": "^7.10.4", "@babel/types": "^7.10.5", "lodash": "^4.17.19" - }, - "dependencies": { - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", - "dev": true - } } }, "@babel/helper-explode-assignable-expression": { @@ -183,12 +167,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.5.tgz", - "integrity": "sha512-HiqJpYD5+WopCXIAbQDG0zye5XYVvcO9w/DHp5GsaGkRUaamLj2bEtu6i8rnGGprAhHM3qidCMgp71HF4endhA==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", + "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", "dev": true, "requires": { - "@babel/types": "^7.10.5" + "@babel/types": "^7.11.0" } }, "@babel/helper-module-imports": { @@ -201,26 +185,18 @@ } }, "@babel/helper-module-transforms": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.5.tgz", - "integrity": "sha512-4P+CWMJ6/j1W915ITJaUkadLObmCRRSC234uctJfn/vHrsLNxsR8dwlcXv9ZhJWzl77awf+mWXSZEKt5t0OnlA==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", + "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.10.4", "@babel/helper-replace-supers": "^7.10.4", "@babel/helper-simple-access": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", "@babel/template": "^7.10.4", - "@babel/types": "^7.10.5", + "@babel/types": "^7.11.0", "lodash": "^4.17.19" - }, - "dependencies": { - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", - "dev": true - } } }, "@babel/helper-optimise-call-expression": { @@ -245,14 +221,6 @@ "dev": true, "requires": { "lodash": "^4.17.19" - }, - "dependencies": { - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", - "dev": true - } } }, "@babel/helper-remap-async-to-generator": { @@ -290,13 +258,22 @@ "@babel/types": "^7.10.4" } }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz", + "integrity": "sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, "@babel/helper-split-export-declaration": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", - "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.11.0" } }, "@babel/helper-validator-identifier": { @@ -340,9 +317,9 @@ } }, "@babel/parser": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.5.tgz", - "integrity": "sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==", + "version": "7.11.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.3.tgz", + "integrity": "sha512-REo8xv7+sDxkKvoxEywIdsNFiZLybwdI7hcT5uEPyQrSMB4YQ973BfC9OOrD/81MaIjh6UxdulIQXkjmiH3PcA==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { @@ -376,6 +353,16 @@ "@babel/plugin-syntax-dynamic-import": "^7.8.0" } }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz", + "integrity": "sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, "@babel/plugin-proposal-json-strings": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz", @@ -386,6 +373,16 @@ "@babel/plugin-syntax-json-strings": "^7.8.0" } }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz", + "integrity": "sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, "@babel/plugin-proposal-nullish-coalescing-operator": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz", @@ -407,9 +404,9 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.4.tgz", - "integrity": "sha512-6vh4SqRuLLarjgeOf4EaROJAHjvu9Gl+/346PbDH9yWbJyfnJ/ah3jmYKYtswEyCoWZiidvVHjHshd4WgjB9BA==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz", + "integrity": "sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -428,12 +425,13 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.4.tgz", - "integrity": "sha512-ZIhQIEeavTgouyMSdZRap4VPPHqJJ3NEs2cuHs5p0erH+iz6khB0qfgU8g7UuJkG88+fBMy23ZiU+nuHvekJeQ==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz", + "integrity": "sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0", "@babel/plugin-syntax-optional-chaining": "^7.8.0" } }, @@ -484,6 +482,15 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, "@babel/plugin-syntax-json-strings": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", @@ -493,6 +500,15 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, "@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", @@ -577,9 +593,9 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.5.tgz", - "integrity": "sha512-6Ycw3hjpQti0qssQcA6AMSFDHeNJ++R6dIMnpRqUjFeBBTmTDPa8zgF90OVfTvAo11mXZTlVUViY1g8ffrURLg==", + "version": "7.11.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz", + "integrity": "sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" @@ -805,12 +821,13 @@ } }, "@babel/plugin-transform-spread": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.4.tgz", - "integrity": "sha512-1e/51G/Ni+7uH5gktbWv+eCED9pP8ZpRhZB3jOaI3mmzfvJTWHkuyYTv0Z5PYtyM+Tr2Ccr9kUdQxn60fI5WuQ==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz", + "integrity": "sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0" } }, "@babel/plugin-transform-sticky-regex": { @@ -862,30 +879,34 @@ } }, "@babel/preset-env": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.10.4.tgz", - "integrity": "sha512-tcmuQ6vupfMZPrLrc38d0sF2OjLT3/bZ0dry5HchNCQbrokoQi4reXqclvkkAT5b+gWc23meVWpve5P/7+w/zw==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.11.0.tgz", + "integrity": "sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg==", "dev": true, "requires": { - "@babel/compat-data": "^7.10.4", + "@babel/compat-data": "^7.11.0", "@babel/helper-compilation-targets": "^7.10.4", "@babel/helper-module-imports": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-proposal-async-generator-functions": "^7.10.4", "@babel/plugin-proposal-class-properties": "^7.10.4", "@babel/plugin-proposal-dynamic-import": "^7.10.4", + "@babel/plugin-proposal-export-namespace-from": "^7.10.4", "@babel/plugin-proposal-json-strings": "^7.10.4", + "@babel/plugin-proposal-logical-assignment-operators": "^7.11.0", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", "@babel/plugin-proposal-numeric-separator": "^7.10.4", - "@babel/plugin-proposal-object-rest-spread": "^7.10.4", + "@babel/plugin-proposal-object-rest-spread": "^7.11.0", "@babel/plugin-proposal-optional-catch-binding": "^7.10.4", - "@babel/plugin-proposal-optional-chaining": "^7.10.4", + "@babel/plugin-proposal-optional-chaining": "^7.11.0", "@babel/plugin-proposal-private-methods": "^7.10.4", "@babel/plugin-proposal-unicode-property-regex": "^7.10.4", "@babel/plugin-syntax-async-generators": "^7.8.0", "@babel/plugin-syntax-class-properties": "^7.10.4", "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.0", @@ -918,14 +939,14 @@ "@babel/plugin-transform-regenerator": "^7.10.4", "@babel/plugin-transform-reserved-words": "^7.10.4", "@babel/plugin-transform-shorthand-properties": "^7.10.4", - "@babel/plugin-transform-spread": "^7.10.4", + "@babel/plugin-transform-spread": "^7.11.0", "@babel/plugin-transform-sticky-regex": "^7.10.4", "@babel/plugin-transform-template-literals": "^7.10.4", "@babel/plugin-transform-typeof-symbol": "^7.10.4", "@babel/plugin-transform-unicode-escapes": "^7.10.4", "@babel/plugin-transform-unicode-regex": "^7.10.4", "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.10.4", + "@babel/types": "^7.11.0", "browserslist": "^4.12.0", "core-js-compat": "^3.6.2", "invariant": "^2.2.2", @@ -947,9 +968,9 @@ } }, "@babel/runtime": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.5.tgz", - "integrity": "sha512-otddXKhdNn7d0ptoFRHtMLa8LqDxLYwTjB4nYgM1yy5N6gU/MUf8zqyyLltCH3yAVitBzmwK4us+DD0l/MauAg==", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", + "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -977,47 +998,31 @@ } }, "@babel/traverse": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.5.tgz", - "integrity": "sha512-yc/fyv2gUjPqzTz0WHeRJH2pv7jA9kA7mBX2tXl/x5iOE81uaVPuGPtaYk7wmkx4b67mQ7NqI8rmT2pF47KYKQ==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", + "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.10.5", + "@babel/generator": "^7.11.0", "@babel/helper-function-name": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4", - "@babel/parser": "^7.10.5", - "@babel/types": "^7.10.5", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.0", + "@babel/types": "^7.11.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" - }, - "dependencies": { - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", - "dev": true - } } }, "@babel/types": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz", - "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" - }, - "dependencies": { - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", - "dev": true - } } }, "@istanbuljs/load-nyc-config": { @@ -1284,9 +1289,9 @@ } }, "@sinonjs/samsam": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.0.3.tgz", - "integrity": "sha512-QucHkc2uMJ0pFGjJUDP3F9dq5dx8QIaqISl9QgwLOh6P9yv877uONPGXh/OH/0zmM3tW1JjuJltAZV2l7zU+uQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.1.0.tgz", + "integrity": "sha512-42nyaQOVunX5Pm6GRJobmzbS7iLI+fhERITnETXzzwDZh+TtDr/Au3yAvXVjFmZ4wEUaE4Y3NFZfKv0bV0cbtg==", "dev": true, "requires": { "@sinonjs/commons": "^1.6.0", @@ -1335,18 +1340,18 @@ } }, "@types/node": { - "version": "14.0.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.24.tgz", - "integrity": "sha512-btt/oNOiDWcSuI721MdL8VQGnjsKjlTMdrKyTcLCKeQp/n4AAMFJ961wMbp+09y8WuGPClDEv07RIItdXKIXAA==", + "version": "14.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.0.tgz", + "integrity": "sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA==", "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.7.0.tgz", - "integrity": "sha512-4OEcPON3QIx0ntsuiuFP/TkldmBGXf0uKxPQlGtS/W2F3ndYm8Vgdpj/woPJkzUc65gd3iR+qi3K8SDQP/obFg==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.9.1.tgz", + "integrity": "sha512-XIr+Mfv7i4paEdBf0JFdIl9/tVxyj+rlilWIfZ97Be0lZ7hPvUbS5iHt9Glc8kRI53dsr0PcAEudbf8rO2wGgg==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "3.7.0", + "@typescript-eslint/experimental-utils": "3.9.1", "debug": "^4.1.1", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.0.0", @@ -1363,57 +1368,45 @@ } }, "@typescript-eslint/experimental-utils": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.7.0.tgz", - "integrity": "sha512-xpfXXAfZqhhqs5RPQBfAFrWDHoNxD5+sVB5A46TF58Bq1hRfVROrWHcQHHUM9aCBdy9+cwATcvCbRg8aIRbaHQ==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.9.1.tgz", + "integrity": "sha512-lkiZ8iBBaYoyEKhCkkw4SAeatXyBq9Ece5bZXdLe1LWBUwTszGbmbiqmQbwWA8cSYDnjWXp9eDbXpf9Sn0hLAg==", "dev": true, "requires": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/types": "3.7.0", - "@typescript-eslint/typescript-estree": "3.7.0", + "@typescript-eslint/types": "3.9.1", + "@typescript-eslint/typescript-estree": "3.9.1", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" - }, - "dependencies": { - "eslint-scope": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", - "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - } } }, "@typescript-eslint/parser": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.7.0.tgz", - "integrity": "sha512-2LZauVUt7jAWkcIW7djUc3kyW+fSarNEuM3RF2JdLHR9BfX/nDEnyA4/uWz0wseoWVZbDXDF7iF9Jc342flNqQ==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.9.1.tgz", + "integrity": "sha512-y5QvPFUn4Vl4qM40lI+pNWhTcOWtpZAJ8pOEQ21fTTW4xTJkRplMjMRje7LYTXqVKKX9GJhcyweMz2+W1J5bMg==", "dev": true, "requires": { "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "3.7.0", - "@typescript-eslint/types": "3.7.0", - "@typescript-eslint/typescript-estree": "3.7.0", + "@typescript-eslint/experimental-utils": "3.9.1", + "@typescript-eslint/types": "3.9.1", + "@typescript-eslint/typescript-estree": "3.9.1", "eslint-visitor-keys": "^1.1.0" } }, "@typescript-eslint/types": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.7.0.tgz", - "integrity": "sha512-reCaK+hyKkKF+itoylAnLzFeNYAEktB0XVfSQvf0gcVgpz1l49Lt6Vo9x4MVCCxiDydA0iLAjTF/ODH0pbfnpg==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.9.1.tgz", + "integrity": "sha512-15JcTlNQE1BsYy5NBhctnEhEoctjXOjOK+Q+rk8ugC+WXU9rAcS2BYhoh6X4rOaXJEpIYDl+p7ix+A5U0BqPTw==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.7.0.tgz", - "integrity": "sha512-xr5oobkYRebejlACGr1TJ0Z/r0a2/HUf0SXqPvlgUMwiMqOCu/J+/Dr9U3T0IxpE5oLFSkqMx1FE/dKaZ8KsOQ==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.9.1.tgz", + "integrity": "sha512-IqM0gfGxOmIKPhiHW/iyAEXwSVqMmR2wJ9uXHNdFpqVvPaQ3dWg302vW127sBpAiqM9SfHhyS40NKLsoMpN2KA==", "dev": true, "requires": { - "@typescript-eslint/types": "3.7.0", - "@typescript-eslint/visitor-keys": "3.7.0", + "@typescript-eslint/types": "3.9.1", + "@typescript-eslint/visitor-keys": "3.9.1", "debug": "^4.1.1", "glob": "^7.1.6", "is-glob": "^4.0.1", @@ -1431,9 +1424,9 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.7.0.tgz", - "integrity": "sha512-k5PiZdB4vklUpUX4NBncn5RBKty8G3ihTY+hqJsCdMuD0v4jofI5xuqwnVcWxfv6iTm2P/dfEa2wMUnsUY8ODw==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.9.1.tgz", + "integrity": "sha512-zxdtUjeoSh+prCpogswMwVUJfEFmCOjdzK9rpNjNBfm6EyPt99x3RrJoBOGZO23FCt0WPKUCOL5mb/9D5LjdwQ==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" @@ -1700,9 +1693,9 @@ "dev": true }, "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true }, "ansi-colors": { @@ -1751,13 +1744,23 @@ "dev": true }, "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", "dev": true, + "optional": true, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "dependencies": { + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "optional": true + } } }, "append-transform": { @@ -1845,14 +1848,23 @@ } }, "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", "dev": true, "requires": { "bn.js": "^4.0.0", "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "assert": { @@ -1915,7 +1927,8 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true + "dev": true, + "optional": true }, "atob": { "version": "2.1.2", @@ -2034,20 +2047,11 @@ "dev": true }, "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } + "optional": true }, "bluebird": { "version": "3.7.2", @@ -2056,9 +2060,9 @@ "dev": true }, "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", + "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", "dev": true }, "body-parser": { @@ -2192,21 +2196,56 @@ "requires": { "bn.js": "^4.1.0", "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } } }, "browserify-zlib": { @@ -2219,15 +2258,15 @@ } }, "browserslist": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.13.0.tgz", - "integrity": "sha512-MINatJ5ZNrLnQ6blGvePd/QOz9Xtu+Ne+x29iQSCHfkU5BugKVJwZKn/iiL8UbpIpa3JhviKjz+XxMo0m2caFQ==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.0.tgz", + "integrity": "sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001093", - "electron-to-chromium": "^1.3.488", - "escalade": "^3.0.1", - "node-releases": "^1.1.58" + "caniuse-lite": "^1.0.30001111", + "electron-to-chromium": "^1.3.523", + "escalade": "^3.0.2", + "node-releases": "^1.1.60" } }, "buffer": { @@ -2239,6 +2278,14 @@ "base64-js": "^1.0.2", "ieee754": "^1.1.4", "isarray": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } } }, "buffer-from": { @@ -2289,9 +2336,9 @@ }, "dependencies": { "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true } } @@ -2355,9 +2402,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001105", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001105.tgz", - "integrity": "sha512-JupOe6+dGMr7E20siZHIZQwYqrllxotAhiaej96y6x00b/48rPt42o+SzOSCPbrpsDWvRja40Hwrj0g0q6LZJg==", + "version": "1.0.30001115", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001115.tgz", + "integrity": "sha512-NZrG0439ePYna44lJX8evHX2L7Z3/z3qjVLnHgbBb/duNEnGo348u+BQS5o4HTWcrb++100dHFrU36IesIrC1Q==", "dev": true }, "cardinal": { @@ -2388,30 +2435,65 @@ "dev": true }, "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", + "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", "dev": true, + "optional": true, "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" }, "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "optional": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "optional": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "optional": true + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "dev": true, + "optional": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "optional": true, + "requires": { + "is-number": "^7.0.0" + } } } }, @@ -2872,13 +2954,21 @@ "dev": true }, "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", "dev": true, "requires": { "bn.js": "^4.1.0", - "elliptic": "^6.0.0" + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "create-hash": { @@ -3173,6 +3263,14 @@ "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "doctrine": { @@ -3219,9 +3317,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.505", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.505.tgz", - "integrity": "sha512-Aunrp3HWtmdiJLIl+IPSFtEvJ/4Q9a3eKaxmzCthaZF1gbTbpHUTCU2zOVnFPH7r/AD7zQXyuFidYXzSHXBdsw==", + "version": "1.3.534", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.534.tgz", + "integrity": "sha512-7x2S3yUrspNHQOoPk+Eo+iHViSiJiEGPI6BpmLy1eT2KRNGCkBt/NUYqjfXLd1DpDCQp7n3+LfA1RkbG+LqTZQ==", "dev": true }, "elegant-spinner": { @@ -3231,9 +3329,9 @@ "dev": true }, "elliptic": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", - "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", "dev": true, "requires": { "bn.js": "^4.4.0", @@ -3243,6 +3341,14 @@ "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0", "minimalistic-crypto-utils": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "emoji-regex": { @@ -3273,9 +3379,9 @@ } }, "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", + "integrity": "sha512-3e87LvavsdxyoCfGusJnrZ5G8SLPOFeHSNpZI/ATL9a5leXo2k0w6MKnbqhdBad9qTobSfB20Ld7UmgoNbAZkQ==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -3438,9 +3544,9 @@ "dev": true }, "eslint": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.5.0.tgz", - "integrity": "sha512-vlUP10xse9sWt9SGRtcr1LAC67BENcQMFeV+w5EvLEoFe3xJ8cF1Skd0msziRx/VMC+72B4DxreCE+OR12OA6Q==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.7.0.tgz", + "integrity": "sha512-1KUxLzos0ZVsyL81PnRN335nDtQ8/vZUD6uMtWbF+5zDtjKcsklIi78XoE0MVL93QvWTu+E5y44VyyCsOMBrIg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -3533,25 +3639,6 @@ "which": "^2.0.1" } }, - "eslint-scope": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", - "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, "globals": { "version": "12.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", @@ -3567,12 +3654,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", - "dev": true - }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -3814,9 +3895,9 @@ } }, "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -3900,9 +3981,9 @@ "dev": true }, "events": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", - "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", "dev": true }, "evp_bytestokey": { @@ -4261,13 +4342,6 @@ "flat-cache": "^2.0.1" } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, "fill-keys": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", @@ -4467,649 +4541,105 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fromentries": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.1.tgz", - "integrity": "sha512-Xu2Qh8yqYuDhQGOhD5iJGninErSfI9A3FrriD3tjUgV5VbJFeH8vfgZ9HnC6jWN80QDVNQK5vmxRAmEAp7Mevw==", - "dev": true - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.12", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", - "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1", - "node-pre-gyp": "*" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "3.2.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.6", - "bundled": true, - "dev": true, - "optional": 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" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.9.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - } - }, - "nopt": { - "version": "4.0.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "readable-stream": { - "version": "2.3.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.7.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.13", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "optional": true, "requires": { - "string-width": "^1.0.2 || 2" + "shebang-regex": "^3.0.0" } }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true }, - "yallist": { - "version": "3.1.1", - "bundled": true, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "optional": true + "requires": { + "isexe": "^2.0.0" + } } } }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fromentries": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.1.tgz", + "integrity": "sha512-Xu2Qh8yqYuDhQGOhD5iJGninErSfI9A3FrriD3tjUgV5VbJFeH8vfgZ9HnC6jWN80QDVNQK5vmxRAmEAp7Mevw==", + "dev": true + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -5176,24 +4706,12 @@ } }, "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "dev": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } + "is-glob": "^4.0.1" } }, "globals": { @@ -5285,13 +4803,39 @@ } }, "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } } }, "hash.js": { @@ -5481,7 +5025,7 @@ }, "inherits": { "version": "2.0.3", - "resolved": "", + "resolved": false, "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, @@ -5696,12 +5240,13 @@ "dev": true }, "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "optional": true, "requires": { - "binary-extensions": "^1.0.0" + "binary-extensions": "^2.0.0" } }, "is-buffer": { @@ -5905,9 +5450,9 @@ "dev": true }, "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "isexe": { @@ -6646,6 +6191,14 @@ "requires": { "bn.js": "^4.0.0", "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "mime": { @@ -7027,13 +6580,6 @@ "thenify-all": "^1.0.0" } }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", - "dev": true, - "optional": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -7072,9 +6618,9 @@ "dev": true }, "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, "next-tick": { @@ -7090,9 +6636,9 @@ "dev": true }, "nise": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.3.tgz", - "integrity": "sha512-EGlhjm7/4KvmmE6B/UFsKh7eHykRl9VH+au8dduHLCyWUO/hr7+N+WtTvDUwc9zHuM1IaIJs/0lQ6Ag1jDkQSg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz", + "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0", @@ -7677,14 +7223,13 @@ } }, "parse-asn1": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", - "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", "dev": true, "requires": { - "asn1.js": "^4.0.0", + "asn1.js": "^5.2.0", "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", "evp_bytestokey": "^1.0.0", "pbkdf2": "^3.0.3", "safe-buffer": "^5.1.1" @@ -7722,7 +7267,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true + "dev": true, + "optional": true }, "path-exists": { "version": "3.0.0", @@ -7755,20 +7301,12 @@ "dev": true, "requires": { "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } } }, "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", "dev": true, "requires": { "create-hash": "^1.1.2", @@ -7907,6 +7445,14 @@ "parse-asn1": "^5.0.0", "randombytes": "^2.0.1", "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } } }, "pump": { @@ -8016,17 +7562,24 @@ "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } } }, "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", "dev": true, + "optional": true, "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" + "picomatch": "^2.2.1" } }, "redeyed": { @@ -8555,10 +8108,13 @@ } }, "serialize-javascript": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", - "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } }, "serve-static": { "version": "1.14.1", @@ -8694,7 +8250,7 @@ }, "should-util": { "version": "1.0.0", - "resolved": "", + "resolved": false, "integrity": "sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM=", "dev": true }, @@ -8705,24 +8261,24 @@ "dev": true }, "sinon": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.2.tgz", - "integrity": "sha512-0uF8Q/QHkizNUmbK3LRFqx5cpTttEVXudywY9Uwzy8bTfZUhljZ7ARzSxnRHWYWtVTeh4Cw+tTb3iU21FQVO9A==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.3.tgz", + "integrity": "sha512-IKo9MIM111+smz9JGwLmw5U1075n1YXeAq8YeSFlndCLhAL5KGn6bLgu7b/4AYHTV/LcEMcRm2wU2YiL55/6Pg==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.2", "@sinonjs/fake-timers": "^6.0.1", "@sinonjs/formatio": "^5.0.1", - "@sinonjs/samsam": "^5.0.3", + "@sinonjs/samsam": "^5.1.0", "diff": "^4.0.2", - "nise": "^4.0.1", + "nise": "^4.0.4", "supports-color": "^7.1.0" }, "dependencies": { "@sinonjs/commons": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.2.tgz", - "integrity": "sha512-+DUO6pnp3udV/v2VfUWgaY5BIE1IfT7lLfeDzPVeMT1XKkaAp9LgSI9x5RtrFQoZ9Oi0PgXQQHPaoKu7dCjVxw==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -9298,9 +8854,9 @@ } }, "terser": { - "version": "4.6.12", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.12.tgz", - "integrity": "sha512-fnIwuaKjFPANG6MAixC/k1TDtnl1YlPLUlLVIxxGZUn1gfUx2+l3/zGNB72wya+lgsb50QBi2tUV75RiODwnww==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", + "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", "dev": true, "requires": { "commander": "^2.20.0", @@ -9323,16 +8879,16 @@ } }, "terser-webpack-plugin": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", - "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", "dev": true, "requires": { "cacache": "^12.0.2", "find-cache-dir": "^2.1.0", "is-wsl": "^1.1.0", "schema-utils": "^1.0.0", - "serialize-javascript": "^2.1.2", + "serialize-javascript": "^4.0.0", "source-map": "^0.6.1", "terser": "^4.1.2", "webpack-sources": "^1.4.0", @@ -9702,6 +9258,12 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true } } }, @@ -9709,7 +9271,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true + "dev": true, + "optional": true }, "upper-case": { "version": "1.1.3", @@ -9825,20 +9388,143 @@ "dev": true }, "watchpack": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", - "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", + "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", "dev": true, "requires": { - "chokidar": "^2.1.8", + "chokidar": "^3.4.1", "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.0" + } + }, + "watchpack-chokidar2": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", + "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "dev": true, + "optional": true, + "requires": { + "chokidar": "^2.1.8" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "optional": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "optional": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "optional": true + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "dev": true, + "optional": true + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "optional": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "optional": true + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + } } }, "webpack": { - "version": "4.43.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz", - "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==", + "version": "4.44.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.1.tgz", + "integrity": "sha512-4UOGAohv/VGUNQJstzEywwNxqX417FnjZgZJpJQegddzPmTvph37eBIRbRTfdySXzVtJXLJfbMN3mMYhM6GdmQ==", "dev": true, "requires": { "@webassemblyjs/ast": "1.9.0", @@ -9849,7 +9535,7 @@ "ajv": "^6.10.2", "ajv-keywords": "^3.4.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.1.0", + "enhanced-resolve": "^4.3.0", "eslint-scope": "^4.0.3", "json-parse-better-errors": "^1.0.2", "loader-runner": "^2.4.0", @@ -9862,7 +9548,7 @@ "schema-utils": "^1.0.0", "tapable": "^1.1.3", "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.6.1", + "watchpack": "^1.7.4", "webpack-sources": "^1.4.1" }, "dependencies": { @@ -9872,6 +9558,16 @@ "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "dev": true }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, "schema-utils": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", diff --git a/package.json b/package.json index 9e6a88c71..7ae9466dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kuzzle-sdk", - "version": "7.3.1", + "version": "7.4.0", "description": "Official Javascript SDK for Kuzzle", "author": "The Kuzzle Team ", "repository": { @@ -24,7 +24,9 @@ "test:functional": "cucumber-js --exit --fail-fast", "test:lint": "npm run test:lint:js && npm run test:lint:ts", "test:lint:js": "eslint --max-warnings=0 ./src ./test ./features", - "test:lint:ts": "eslint ./src --ext .ts --config .eslintc-ts.json", + "test:lint:js:fix": "eslint --max-warnings=0 ./src ./test ./features --fix", + "test:lint:ts": "eslint ./src --ext .ts --config .eslintrc-ts.json", + "test:lint:ts:fix": "eslint ./src --ext .ts --config .eslintrc-ts.json --fix", "build": "npm run build-ts && node build.js", "build-ts": "tsc --build tsconfig.json", "doc": "docker-compose -f doc/docker-compose.yml up", @@ -45,15 +47,15 @@ "ws": "^7.3.1" }, "devDependencies": { - "@babel/core": "^7.10.5", - "@babel/preset-env": "^7.10.4", - "@types/node": "^14.0.24", - "@typescript-eslint/eslint-plugin": "^3.7.0", - "@typescript-eslint/parser": "^3.7.0", + "@babel/core": "^7.11.1", + "@babel/preset-env": "^7.11.0", + "@types/node": "^14.6.0", + "@typescript-eslint/eslint-plugin": "^3.9.1", + "@typescript-eslint/parser": "^3.9.1", "babel-loader": "^8.1.0", "codecov": "^3.7.2", "cucumber": "^6.0.5", - "eslint": "^7.5.0", + "eslint": "^7.7.0", "eslint-friendly-formatter": "^4.0.1", "eslint-loader": "^4.0.2", "kuzdoc": "^1.2.2", @@ -66,10 +68,10 @@ "rewire": "^5.0.0", "should": "13.2.3", "should-sinon": "0.0.6", - "sinon": "^9.0.2", + "sinon": "^9.0.3", "ts-node": "^8.10.2", "typescript": "^3.9.7", - "webpack": "^4.43.0" + "webpack": "^4.44.1" }, "engines": { "node": ">= 10.13.0" diff --git a/src/Kuzzle.ts b/src/Kuzzle.ts index 98a27138e..b19d4ed90 100644 --- a/src/Kuzzle.ts +++ b/src/Kuzzle.ts @@ -1,4 +1,5 @@ import { KuzzleEventEmitter } from './core/KuzzleEventEmitter'; +import { KuzzleAbstractProtocol } from './protocols/abstract/Base'; import { AuthController } from './controllers/Auth'; import { BulkController } from './controllers/Bulk'; @@ -12,7 +13,7 @@ import { MemoryStorageController } from './controllers/MemoryStorage'; import { uuidv4 } from './utils/uuidv4'; import { proxify } from './utils/proxify'; -import { JSONObject, KuzzleRequest } from './utils/interfaces'; +import { JSONObject, KuzzleRequest, KuzzleResponse } from './utils/interfaces'; // Defined by webpack plugin declare const SDKVERSION: any; @@ -31,6 +32,9 @@ const events = [ ]; export class Kuzzle extends KuzzleEventEmitter { + // We need to define any string key because users can register new controllers + [key: string]: any; + /** * Protocol used by the SDK to communicate with Kuzzle. */ @@ -48,7 +52,7 @@ export class Kuzzle extends KuzzleEventEmitter { */ public sdkVersion: string; /** - * SDK name (e.g: js@7.4.2). + * SDK name (e.g: `js@7.4.2`). */ public sdkName: string; /** @@ -58,11 +62,11 @@ export class Kuzzle extends KuzzleEventEmitter { public auth: AuthController; public bulk: any; - public collection: any; + public collection: CollectionController; public document: DocumentController; - public index: any; + public index: IndexController; public ms: any; - public realtime: any; + public realtime: RealtimeController; public security: any; public server: any; @@ -82,10 +86,84 @@ export class Kuzzle extends KuzzleEventEmitter { private __proxy__: any; /** - * @param protocol - the protocol to use - * @param [options] - Kuzzle options + * Instantiate a new SDK + * + * @example + * + * import { Kuzzle, WebSocket } from 'kuzzle-sdk'; + * + * const kuzzle = new Kuzzle( + * new WebSocket('localhost') + * ); */ - constructor(protocol: any, options: any = {}) { + constructor( + /** + * Network protocol to connect to Kuzzle. (e.g. `Http` or `WebSocket`) + */ + protocol: KuzzleAbstractProtocol, + options: { + /** + * Automatically renew all subscriptions on a `reconnected` event + * Default: `true` + */ + autoResubscribe?: boolean; + /** + * Time (in ms) during which a similar event is ignored + * Default: `200` + */ + eventTimeout?: number; + /** + * Common volatile data, will be sent to all future requests + * Default: `{}` + */ + volatile?: JSONObject; + /** + * If `true`, automatically queues all requests during offline mode + * Default: `false` + */ + autoQueue?: boolean; + /** + * If `true`, automatically replays queued requests + * on a `reconnected` event + * Default: `false` + */ + autoReplay?: boolean; + /** + * Custom function called during offline mode to filter + * queued requests on-the-fly + */ + queueFilter?: (request: KuzzleRequest) => boolean; + /** + * Called before dequeuing requests after exiting offline mode, + * to add items at the beginning of the offline queue + */ + offlineQueueLoader?: (...any) => any; + /** + * Number of maximum requests kept during offline mode + * Default: `500` + */ + queueMaxSize?: number; + /** + * Time a queued request is kept during offline mode, in milliseconds + * Default: `120000` + */ + queueTTL?: number; + /** + * Delay between each replayed requests, in milliseconds + * Default: `10` + */ + replayInterval?: number; + /** + * Time (in ms) during which a TokenExpired event is ignored + * Default: `1000` + */ + tokenExpiredInterval?: number; + /** + * If set to `auto`, the `autoQueue` and `autoReplay` are also set to `true` + */ + offlineMode?: 'auto'; + } = {} + ) { super(); if (protocol === undefined || protocol === null) { @@ -324,13 +402,12 @@ export class Kuzzle extends KuzzleEventEmitter { return this._superEmit(eventName, ...payload); } - _superEmit (eventName, ...payload) { + private _superEmit (eventName, ...payload) { return super.emit(eventName, ...payload); } /** - * Connects to a Kuzzle instance using the provided host name - * @returns {Promise} + * Connects to a Kuzzle instance */ connect (): Promise { if (this.protocol.isReady()) { @@ -361,15 +438,10 @@ export class Kuzzle extends KuzzleEventEmitter { if (this.autoQueue) { this.startQueuing(); } - - this.realtime.disconnected(); - this.emit('networkError', error); }); this.protocol.addListener('disconnect', () => { - this.realtime.disconnected(); - this.emit('disconnected'); }); @@ -382,8 +454,6 @@ export class Kuzzle extends KuzzleEventEmitter { this.playQueue(); } - this.realtime.reconnected(); - if (this.auth.authenticationToken) { return this.auth.checkToken() .then(res => { @@ -421,7 +491,7 @@ export class Kuzzle extends KuzzleEventEmitter { return this._superAddListener(event, listener); } - _superAddListener (event, listener) { + private _superAddListener (event, listener) { return super.addListener(event, listener); } @@ -451,11 +521,10 @@ export class Kuzzle extends KuzzleEventEmitter { * - volatile (object, default: null): * Additional information passed to notifications to other users * - * @param {object} request - * @param {object} [options] - Optional arguments - * @returns {Promise} + * @param request + * @param options - Optional arguments */ - query (request: KuzzleRequest = {}, options: JSONObject = {}): Promise { + query (request: KuzzleRequest = {}, options: JSONObject = {}): Promise { if (typeof request !== 'object' || Array.isArray(request)) { throw new Error(`Kuzzle.query: Invalid request: ${JSON.stringify(request)}`); } @@ -570,11 +639,10 @@ Discarded request: ${JSON.stringify(request)}`)); /** * Adds a new controller and make it available in the SDK. * - * @param {BaseController} ControllerClass - * @param {string} accessor - * @returns {Kuzzle} + * @param ControllerClass + * @param accessor */ - useController (ControllerClass, accessor) { + useController (ControllerClass: any, accessor: string) { if (!(accessor && accessor.length > 0)) { throw new Error('You must provide a valid accessor.'); } @@ -601,7 +669,7 @@ Discarded request: ${JSON.stringify(request)}`)); return this; } - _checkPropertyType (prop, typestr, value) { + private _checkPropertyType (prop, typestr, value) { const wrongType = typestr === 'array' ? !Array.isArray(value) : typeof value !== typestr; if (wrongType) { @@ -612,7 +680,7 @@ Discarded request: ${JSON.stringify(request)}`)); /** * Clean up the queue, ensuring the queryTTL and queryMaxSize properties are respected */ - _cleanQueue () { + private _cleanQueue () { const now = Date.now(); let lastDocumentIndex = -1; @@ -644,7 +712,7 @@ Discarded request: ${JSON.stringify(request)}`)); /** * Play all queued requests, in order. */ - _dequeue() { + private _dequeue() { const uniqueQueue = {}, dequeuingProcess = () => { @@ -693,7 +761,4 @@ Discarded request: ${JSON.stringify(request)}`)); dequeuingProcess(); } - } - -module.exports = { Kuzzle }; diff --git a/src/KuzzleError.js b/src/KuzzleError.js deleted file mode 100644 index fd9ee4ce3..000000000 --- a/src/KuzzleError.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; - -class KuzzleError extends Error { - constructor (apiError) { - super(apiError.message); - - this.status = apiError.status; - this.stack = apiError.stack; - this.id = apiError.id; - this.code = apiError.code; - - // PartialError - if (this.status === 206) { - this.errors = apiError.errors; - this.count = apiError.count; - } - } -} - -module.exports = KuzzleError; diff --git a/src/KuzzleError.ts b/src/KuzzleError.ts new file mode 100644 index 000000000..505227ac4 --- /dev/null +++ b/src/KuzzleError.ts @@ -0,0 +1,67 @@ +'use strict'; + +/** + * Standard Kuzzle error. + * + * @see https://docs.kuzzle.io/core/2/api/essentials/error-handling/ + */ +export class KuzzleError extends Error { + /** + * Http status code + */ + public status: number; + /** + * Stacktrace + */ + public stack: string; + /** + * Kuzzle stacktrace (development mode only) + */ + public kuzzleStack?: string; + /** + * Unique ID + */ + public id: string; + /** + * Code + */ + public code: number; + + /** + * Associated errors + * (PartialError only) + */ + public errors?: Array; + /** + * Number of associated errors + * (PartialError only) + */ + public count?: number; + + constructor (apiError, stack = null) { + super(apiError.message); + + this.status = apiError.status; + if (apiError.stack) { + Reflect.defineProperty(this, 'kuzzleStack', { + value: apiError.stack + }); + } + + if (stack) { + const lines = stack.split('\n'); + lines[0] += apiError.message; + lines[3] = ' 🡆 ' + lines[3].trimStart(); + this.stack = lines.join('\n'); + } + + this.id = apiError.id; + this.code = apiError.code; + + // PartialError + if (this.status === 206) { + this.errors = apiError.errors; + this.count = apiError.count; + } + } +} diff --git a/src/controllers/Auth.ts b/src/controllers/Auth.ts index 2d8ef3ce6..9ed867c18 100644 --- a/src/controllers/Auth.ts +++ b/src/controllers/Auth.ts @@ -495,7 +495,7 @@ export class AuthController extends BaseController { */ _id: string; /** - * Expiration date in UNIX micro-timestamp format (-1 if the token never expires) + * Expiration date in Epoch-millis format (-1 if the token never expires) */ expiresAt: number; /** @@ -520,5 +520,3 @@ export class AuthController extends BaseController { }); } } - -module.exports = { AuthController }; diff --git a/src/controllers/Base.ts b/src/controllers/Base.ts index b67d63f58..8115fc82a 100644 --- a/src/controllers/Base.ts +++ b/src/controllers/Base.ts @@ -40,5 +40,3 @@ export class BaseController { return this._kuzzle.query(request, options); } } - -module.exports = { BaseController }; diff --git a/src/controllers/Collection.js b/src/controllers/Collection.js deleted file mode 100644 index 97727ab6b..000000000 --- a/src/controllers/Collection.js +++ /dev/null @@ -1,151 +0,0 @@ -const { BaseController } = require('./Base'); -const { SpecificationsSearchResult } = require('../core/searchResult/Specifications'); - -class CollectionController extends BaseController { - - /** - * @param {Kuzzle} kuzzle - */ - constructor (kuzzle) { - super(kuzzle, 'collection'); - } - - create (index, collection, mappings = {}, options = {}) { - const request = { - index, - collection, - body: mappings, - action: 'create' - }; - return this.query(request, options) - .then(response => response.result); - } - - deleteSpecifications (index, collection, options = {}) { - const request = { - index, - collection, - action: 'deleteSpecifications' - }; - return this.query(request, options) - .then(response => response.result); - } - - exists (index, collection, options = {}) { - return this.query({ - index, - collection, - action: 'exists' - }, options) - .then(response => response.result); - } - - refresh (index, collection, options = {}) { - return this.query({ - index, - collection, - action: 'refresh' - }, options) - .then(response => response.result); - } - - getMapping (index, collection, options = {}) { - const request = { - index, - collection, - action: 'getMapping', - includeKuzzleMeta: options.includeKuzzleMeta || false - }; - - return this.query(request, options) - .then(response => response.result); - } - - getSpecifications (index, collection, options = {}) { - return this.query({ - index, - collection, - action: 'getSpecifications' - }, options) - .then(response => response.result); - } - - list (index, options = {}) { - const request = { - index, - action: 'list', - size: options.size || 0, - from: options.from - }; - - return this.query(request, options) - .then(response => response.result); - } - - searchSpecifications (body = {}, options = {}) { - const request = { - body, - action: 'searchSpecifications' - }; - - for (const opt of ['from', 'size', 'scroll']) { - request[opt] = options[opt]; - } - - return this.query(request, options) - .then(response => new SpecificationsSearchResult(this.kuzzle, request, options, response.result)); - } - - truncate (index, collection, options = {}) { - const request = { - index, - collection, - action: 'truncate' - }; - return this.query(request, options) - .then(response => response.result); - } - - update(index, collection, body) { - return this.query({ - index, - collection, - body, - action: 'update' - }) - .then(response => response.result); - } - - // @deprecated - updateMapping (index, collection, body, options = {}) { - return this.query({ - index, - collection, - body, - action: 'updateMapping' - }, options) - .then(response => response.result); - } - - updateSpecifications (index, collection, specifications, options = {}) { - return this.query({ - index, - collection, - body: specifications, - action: 'updateSpecifications' - }, options) - .then(response => response.result); - } - - validateSpecifications (index, collection, specifications, options = {}) { - return this.query({ - index, - collection, - body: specifications, - action: 'validateSpecifications' - }, options) - .then(response => response.result); - } -} - -module.exports = { CollectionController }; diff --git a/src/controllers/Collection.ts b/src/controllers/Collection.ts new file mode 100644 index 000000000..6f1374b22 --- /dev/null +++ b/src/controllers/Collection.ts @@ -0,0 +1,428 @@ +import { BaseController } from './Base'; +import { SpecificationsSearchResult } from '../core/searchResult/Specifications'; +import { CollectionMappings, JSONObject } from '../utils/interfaces'; + +export class CollectionController extends BaseController { + constructor (kuzzle) { + super(kuzzle, 'collection'); + } + + /** + * Creates a new collection in the provided index. + * You can also provide optional mappings and settings that allow you to exploit + * the full capabilities of our persistent data storage layer. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/collection/create/ + * @see https://docs.kuzzle.io/core/2/guides/essentials/database-mappings/ + * + * @param index Index name + * @param collection Collection name + * @param definition Collection mappings and settings + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + */ + create ( + index: string, + collection: string, + definition: + { + /** + * Mappings definition + */ + mappings?: CollectionMappings; + /** + * Elasticsearch index settings + */ + settings?: JSONObject + } | CollectionMappings, + options: { queuable?: boolean } = {} + ): Promise { + const request = { + index, + collection, + body: definition, + action: 'create' + }; + + return this.query(request, options) + .then(() => undefined); + } + + /** + * Deletes validation specifications for a collection. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/collection/delete-specifications/ + * + * @param index Index name + * @param collection Collection name + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + */ + deleteSpecifications ( + index: string, + collection: string, + options: { queuable?: boolean } = {} + ): Promise { + const request = { + index, + collection, + action: 'deleteSpecifications' + }; + return this.query(request, options) + .then(() => undefined); + } + + /** + * Checks if a collection exists in Kuzzle. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/collection/exists/ + * + * @param index Index name + * @param collection Collection name + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + */ + exists ( + index: string, + collection: string, + options: { queuable?: boolean } = {} + ): Promise { + return this.query({ + index, + collection, + action: 'exists' + }, options) + .then(response => response.result); + } + + /** + * Refreshes a collection to reindex the writed and deleted documents + * so they are available in search results. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/collection/refresh/ + * + * @param index Index name + * @param collection Collection name + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + */ + refresh ( + index: string, + collection: string, + options: { queuable?: boolean } = {} + ): Promise { + return this.query({ + index, + collection, + action: 'refresh' + }, options) + .then(() => undefined); + } + + /** + * Returns the collection mapping. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/collection/get-mapping/ + * + * @param index Index name + * @param collection Collection name + * @param options Additional options + * - `includeKuzzleMeta` If true, the returned mappings will contain Kuzzle metadata + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + */ + getMapping ( + index: string, + collection: string, + options: { includeKuzzleMeta?: boolean, queuable?: boolean } = {} + ): Promise { + const request = { + index, + collection, + action: 'getMapping', + includeKuzzleMeta: options.includeKuzzleMeta || false + }; + + return this.query(request, options) + .then(response => response.result); + } + + /** + * Returns the validation specifications associated to the given index and collection. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/collection/get-specifications/ + * + * @param index Index name + * @param collection Collection name + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + * + * @returns The specifications + */ + getSpecifications ( + index: string, + collection: string, + options: { queuable?: boolean } = {} + ): Promise { + return this.query({ + index, + collection, + action: 'getSpecifications' + }, options) + .then(response => response.result); + } + + /** + * Returns the list of collections associated to a provided index. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/collection/list/ + * + * @param index Index name + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + * + * @returns An object containing the collection list + */ + list ( + index: string, + options: { + queuable?: boolean; + /** + * @deprecated + */ + from?: number; + /** + * @deprecated + */ + size?: number; + } = {} + ): Promise<{ + /** + * Types of returned collections. + */ + type: string; + /** + * List of collections + */ + collections: Array<{ + /** + * Collection name + */ + name: string; + /** + * Collection type + */ + type: 'realtime' | 'stored' + }>; + }> { + const request = { + index, + action: 'list', + size: options.size || 0, + from: options.from + }; + + return this.query(request, options) + .then(response => response.result); + } + + /** + * Searches collection specifications. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/collection/search-specifications/ + * + * @param query Search query + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + * - `from` Offset of the first document to fetch + * - `size` Maximum number of documents to retrieve per page + * - `scroll` When set, gets a forward-only cursor having its ttl set to the given value (e.g. `30s`) + */ + searchSpecifications ( + query: JSONObject = {}, + options: { + queuable?: boolean; + from?: number; + size?: number; + scroll?: string; + } = {} + ): Promise { + const request = { + body: query, + action: 'searchSpecifications' + }; + + for (const opt of ['from', 'size', 'scroll']) { + request[opt] = options[opt]; + } + + return this.query(request, options) + .then(response => ( + new SpecificationsSearchResult(this.kuzzle, request, options, response.result) + )); + } + + + /** + * Removes all documents from a collection, while keeping the associated mappings. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/collection/truncate/ + * + * @param index Index name + * @param collection Collection name + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + */ + truncate ( + index: string, + collection: string, + options: { queuable?: boolean } = {} + ): Promise { + const request = { + index, + collection, + action: 'truncate' + }; + return this.query(request, options) + .then(() => undefined); + } + + /** + * Updates a collection informations + * You can also provide optional mappings and settings that allow you to exploit + * the full capabilities of our persistent data storage layer. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/collection/update/ + * @see https://docs.kuzzle.io/core/2/guides/essentials/database-mappings/ + * + * @param index Index name + * @param collection Collection name + * @param definition Collection mappings and settings + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + */ + update ( + index: string, + collection: string, + definition: + { + /** + * Mappings definition + */ + mappings?: CollectionMappings; + /** + * Elasticsearch index settings + */ + settings?: JSONObject + } | CollectionMappings, + options: { queuable?: boolean } = {} + ): Promise { + return this.query({ + index, + collection, + body: definition, + action: 'update' + }, options) + .then(() => undefined); + } + + /** + * @deprecated Use collection.update instead + */ + updateMapping ( + index: string, + collection: string, + mappings: CollectionMappings, + options: { queuable?: boolean } = {} + ): Promise { + return this.query({ + index, + collection, + body: mappings, + action: 'updateMapping' + }, options) + .then(response => response.result); + } + + /** + * Create or updates the validation specifications for a collection. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/collection/update-specifications/ + * + * @param index Index name + * @param collection Collection name + * @param specifications Specifications to update + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + * + * @returns The updated specifications + */ + updateSpecifications ( + index: string, + collection: string, + specifications: JSONObject, + options: { queuable?: boolean } = {} + ): Promise { + return this.query({ + index, + collection, + body: specifications, + action: 'updateSpecifications' + }, options) + .then(response => response.result); + } + + /** + * Checks if a validation specification is well formatted. + * It does not store or modify the existing specification. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/collection/validate-specifications/ + * + * @param index Index name + * @param collection Collection name + * @param specifications Specifications to validate + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + * + * @returns An object which contain information about the specifications validity. + */ + validateSpecifications ( + index: string, + collection: string, + specifications: JSONObject, + options: { queuable?: boolean } = {} + ): Promise<{ + valid: boolean; + details: Array; + description: string; + }> { + return this.query({ + index, + collection, + body: specifications, + action: 'validateSpecifications' + }, options) + .then(response => response.result); + } + + /** + * Deletes a collection. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/collection/delete/ + * + * @param index Index name + * @param collection Collection name + */ + delete ( + index: string, + collection: string + ): Promise { + const request = { + index, + collection, + action: 'delete' + }; + + return this.query(request) + .then(() => undefined); + } +} diff --git a/src/controllers/Document.ts b/src/controllers/Document.ts index 34141a911..60a3c77fc 100644 --- a/src/controllers/Document.ts +++ b/src/controllers/Document.ts @@ -27,7 +27,7 @@ export class DocumentController extends BaseController { count ( index: string, collection: string, - body: JSONObject = null, + body?: JSONObject, options: { queuable?: boolean } = {} ): Promise { const request = { @@ -801,5 +801,3 @@ export class DocumentController extends BaseController { .then(response => response.result); } } - -module.exports = { DocumentController }; diff --git a/src/controllers/Index.js b/src/controllers/Index.js deleted file mode 100644 index 626d8c949..000000000 --- a/src/controllers/Index.js +++ /dev/null @@ -1,58 +0,0 @@ -const { BaseController } = require('./Base'); - -class IndexController extends BaseController { - - /** - * @param {Kuzzle} kuzzle - */ - constructor (kuzzle) { - super(kuzzle, 'index'); - } - - create (index, options = {}) { - const request = { - index, - action: 'create' - }; - return this.query(request, options) - .then(response => response.result); - } - - delete (index, options = {}) { - const request = { - index, - action: 'delete' - }; - return this.query(request, options) - .then(response => response.result.acknowledged); - } - - exists (index, options = {}) { - return this.query({ - index, - action : 'exists' - }, options) - .then(response => response.result); - } - - list (options) { - return this.query({ - action: 'list' - }, options) - .then(response => response.result.indexes); - } - - mDelete (indexes, options = {}) { - const request = { - action: 'mDelete', - body: { - indexes - } - }; - - return this.query(request, options) - .then(response => response.result.deleted); - } -} - -module.exports = { IndexController }; diff --git a/src/controllers/Index.ts b/src/controllers/Index.ts new file mode 100644 index 000000000..61fc13c10 --- /dev/null +++ b/src/controllers/Index.ts @@ -0,0 +1,102 @@ +import { BaseController } from './Base'; + +export class IndexController extends BaseController { + + constructor (kuzzle) { + super(kuzzle, 'index'); + } + + /** + * Creates a new index + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/index/create/ + * + * @param index Index name + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + */ + create (index: string, options: { queuable?: boolean } = {}): Promise { + const request = { + index, + action: 'create' + }; + return this.query(request, options) + .then(() => undefined); + } + + /** + * Deletes an index + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/index/delete/ + * + * @param index Index name + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + */ + delete (index: string, options: { queuable?: boolean } = {}): Promise { + const request = { + index, + action: 'delete' + }; + return this.query(request, options) + .then(() => undefined); + } + + /** + * Checks if the given index exists. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/index/exists/ + * + * @param index Index name + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + */ + exists (index: string, options: { queuable?: boolean } = {}): Promise { + return this.query({ + index, + action : 'exists' + }, options) + .then(response => response.result); + } + + /** + * Returns the complete list of indexes. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/index/list/ + * + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + */ + list (options: { queuable?: boolean } = {}): Promise> { + return this.query({ + action: 'list' + }, options) + .then(response => response.result.indexes); + } + + /** + * Deletes multiple indexes + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/index/m-delete/ + * + * @param indexes List of index names to delete + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + * + * @returns Names of successfully deleted indexes + */ + mDelete ( + indexes: Array, + options: { queuable?: boolean } = {} + ): Promise> { + const request = { + action: 'mDelete', + body: { + indexes + } + }; + + return this.query(request, options) + .then(response => response.result.deleted); + } +} diff --git a/src/controllers/Realtime.js b/src/controllers/Realtime.js deleted file mode 100644 index e68478ba2..000000000 --- a/src/controllers/Realtime.js +++ /dev/null @@ -1,128 +0,0 @@ -const { BaseController } = require('./Base'); -const Room = require('../core/Room'); - - -class RealtimeController extends BaseController { - /** - * @param {Kuzzle} kuzzle - */ - constructor (kuzzle) { - super(kuzzle, 'realtime'); - - this.subscriptions = new Map(); - this.subscriptionsOff = new Map(); - - this.kuzzle.on('tokenExpired', () => this.tokenExpired()); - } - - count (roomId, options = {}) { - return this.query({ - action: 'count', - body: {roomId} - }, options) - .then(response => response.result.count); - } - - publish (index, collection, message, options = {}) { - const request = { - index, - collection, - body: message, - action: 'publish', - _id: options._id - }; - - return this.query(request, options) - .then(response => response.result.published); - } - - subscribe (index, collection, filters, callback, options = {}) { - const room = new Room(this, index, collection, filters, callback, options); - - return room.subscribe() - .then(() => { - if (!this.subscriptions.has(room.id)) { - this.subscriptions.set(room.id, []); - } - this.subscriptions.get(room.id).push(room); - return room.id; - }); - } - - unsubscribe (roomId, options = {}) { - const request = { - action: 'unsubscribe', - body: { roomId } - }; - - return this.query(request, options) - .then(response => { - const rooms = this.subscriptions.get(roomId); - - if (rooms) { - for (const room of rooms) { - room.removeListeners(); - } - - this.subscriptions.delete(roomId); - } - - return response.result; - }); - } - - // called on network error or disconnection - disconnected () { - for (const roomId of this.subscriptions.keys()) { - for (const room of this.subscriptions.get(roomId)) { - room.removeListeners(); - - if (room.autoResubscribe) { - if (!this.subscriptionsOff.has(roomId)) { - this.subscriptionsOff.set(roomId, []); - } - this.subscriptionsOff.get(roomId).push(room); - } - } - - this.subscriptions.delete(roomId); - } - } - - /** - * Called on kuzzle reconnection. - * Resubscribe to eligible disabled rooms. - */ - reconnected () { - for (const roomId of this.subscriptionsOff.keys()) { - for (const room of this.subscriptionsOff.get(roomId)) { - if (!this.subscriptions.has(roomId)) { - this.subscriptions.set(roomId, []); - } - this.subscriptions.get(roomId).push(room); - - room.subscribe() - .catch(() => this.kuzzle.emit('discarded', {request: room.request})); - } - - this.subscriptionsOff.delete(roomId); - } - } - - /** - * Removes all subscriptions. - */ - tokenExpired() { - for (const roomId of this.subscriptions.keys()) { - for (const room of this.subscriptions.get(roomId)) { - room.removeListeners(); - } - } - - this.subscriptions = new Map(); - this.subscriptionsOff = new Map(); - } - -} - -module.exports = { RealtimeController }; diff --git a/src/controllers/Realtime.ts b/src/controllers/Realtime.ts new file mode 100644 index 000000000..1d1b391c2 --- /dev/null +++ b/src/controllers/Realtime.ts @@ -0,0 +1,259 @@ +import { BaseController } from './Base'; +import Room from '../core/Room'; +import { JSONObject } from '../utils/interfaces'; + +/** + * Enum for `scope` option of realtime.subscribe method + */ +export enum ScopeOption { + /** + * Receive all document notifications + */ + all = 'all', + /** + * Receive notifications when document enter or stay in the scope + */ + in = 'in', + /** + * Receive notification when document exit the scope + */ + out = 'out', + /** + * Do not receive document notifications + */ + none = 'none' +} + +/** + * Enum for `user` option of realtime.subscribe method + */ +export enum UserOption { + /** + * Receive all user notifications + */ + all = 'all', + /** + * Receive notification when users join the room + */ + in = 'in', + /** + * Receive notifications when users leave the room + */ + out = 'out', + /** + * Do not receive user notifications + */ + none = 'none' +} + +export class RealtimeController extends BaseController { + private _subscriptions: Map>; + private _subscriptionsOff: Map>; + + constructor (kuzzle) { + super(kuzzle, 'realtime'); + + this._subscriptions = new Map(); + this._subscriptionsOff = new Map(); + + this.kuzzle.on('tokenExpired', () => this.removeSubscriptions()); + this.kuzzle.on('disconnected', () => this.saveSubscriptions()); + this.kuzzle.on('networkError', () => this.saveSubscriptions()); + this.kuzzle.on('reconnected', () => this.resubscribe()); + } + + /** + * Returns the number of other connections sharing the same subscription. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/realtime/count/ + * + * @param roomId Subscription room ID + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + * + * @returns A number represensting active connections using the same provided subscription room. + */ + count (roomId: string, options: { queuable?: boolean } = {}): Promise { + return this.query({ + action: 'count', + body: { roomId } + }, options) + .then(response => response.result.count); + } + + /** + * Sends a real-time message to Kuzzle. + * + * The message will be dispatched to all clients with subscriptions + * matching the index, the collection and the message content. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/realtime/count/ + * + * @param index Index name + * @param collection Collection name + * @param message Message to send (will be put in `_source` property of the notification) + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + * - `_id` Additional unique ID (will be put in the `_id` property of the notification) + */ + publish ( + index: string, + collection: string, + message: JSONObject, + options: { queuable?: boolean, _id?: string } = {} + ): Promise { + const request = { + index, + collection, + body: message, + action: 'publish', + _id: options._id + }; + + return this.query(request, options) + .then(response => response.result.published); + } + + /** + * Subscribes by providing a set of filters: messages, document changes + * and, optionally, user events matching the provided filters will generate + * real-time notifications. + * + * @see https://docs.kuzzle.io/sdk/js/7/controllers/realtime/subscribe/ + * @see https://docs.kuzzle.io/sdk/js/7/essentials/realtime-notifications/ + * + * @param index Index name + * @param collection Collection name + * @param filters Optional subscription filters (@see https://docs.kuzzle.io/core/2/guides/cookbooks/realtime-api) + * @param callback Callback function to handle notifications + * @param options Additional options + * - `scope` Subscribe to document entering or leaving the scope. (default: 'all') + * - `users` Subscribe to users entering or leaving the room. (default: 'none') + * - `subscribeToSelf` Subscribe to notifications fired by our own queries. (default: true) + * - `volatile` Subscription information sent alongside notifications + * + * @returns A string containing the room ID + */ + subscribe ( + index: string, + collection: string, + filters: JSONObject, + callback: (notification: Notification) => void | Promise, + options: { + /** + * Subscribe to document entering or leaving the scope. (default: 'all') + */ + scope?: ScopeOption; + /** + * Subscribe to users entering or leaving the room. (default: 'none') + */ + users?: UserOption; + /** + * Subscribe to notifications fired by our own queries. (default: true) + */ + subscribeToSelf?: boolean; + /** + * Subscription information sent alongside notifications + */ + volatile?: JSONObject; + } = {} + ): Promise { + const room = new Room(this, index, collection, filters, callback, options); + + return room.subscribe() + .then(() => { + if (!this._subscriptions.has(room.id)) { + this._subscriptions.set(room.id, []); + } + this._subscriptions.get(room.id).push(room); + return room.id; + }); + } + + /** + * Removes a subscription + * + * @param roomId Subscription room ID + * @param options Additional options + * - `queuable` If true, queues the request during downtime, until connected to Kuzzle again + */ + unsubscribe ( + roomId: string, + options: { queuable?: boolean } = {} + ): Promise { + const request = { + action: 'unsubscribe', + body: { roomId } + }; + + return this.query(request, options) + .then(response => { + const rooms = this._subscriptions.get(roomId); + + if (rooms) { + for (const room of rooms) { + room.removeListeners(); + } + + this._subscriptions.delete(roomId); + } + + return response.result; + }); + } + + /** + * Called when kuzzle is disconnected + */ + private saveSubscriptions () { + for (const roomId of this._subscriptions.keys()) { + for (const room of this._subscriptions.get(roomId)) { + room.removeListeners(); + + if (room.autoResubscribe) { + if (!this._subscriptionsOff.has(roomId)) { + this._subscriptionsOff.set(roomId, []); + } + this._subscriptionsOff.get(roomId).push(room); + } + } + + this._subscriptions.delete(roomId); + } + } + + /** + * Called on kuzzle reconnection + */ + private resubscribe () { + for (const roomId of this._subscriptionsOff.keys()) { + for (const room of this._subscriptionsOff.get(roomId)) { + if (!this._subscriptions.has(roomId)) { + this._subscriptions.set(roomId, []); + } + this._subscriptions.get(roomId).push(room); + + room.subscribe() + .catch(() => this.kuzzle.emit('discarded', { request: room.request })); + } + + this._subscriptionsOff.delete(roomId); + } + } + + /** + * Called when a token expire + */ + private removeSubscriptions() { + for (const roomId of this._subscriptions.keys()) { + for (const room of this._subscriptions.get(roomId)) { + room.removeListeners(); + } + } + + this._subscriptions = new Map(); + this._subscriptionsOff = new Map(); + } +} + +module.exports = { RealtimeController }; diff --git a/src/core/KuzzleEventEmitter.js b/src/core/KuzzleEventEmitter.ts similarity index 91% rename from src/core/KuzzleEventEmitter.js rename to src/core/KuzzleEventEmitter.ts index e88ee825c..c10f03b23 100644 --- a/src/core/KuzzleEventEmitter.js +++ b/src/core/KuzzleEventEmitter.ts @@ -1,16 +1,24 @@ class Listener { + public fn: (...any) => any; + public once: boolean; + constructor(fn, once = false) { this.fn = fn; this.once = once; } } -class KuzzleEventEmitter { - constructor() { +/** + * @todo proper TS conversion + */ +export class KuzzleEventEmitter { + private _events: Map>; + + constructor () { this._events = new Map(); } - _exists (listeners, fn) { + private _exists (listeners, fn) { return Boolean(listeners.find(listener => listener.fn === fn)); } @@ -98,7 +106,7 @@ class KuzzleEventEmitter { return this; } - removeAllListeners (eventName) { + removeAllListeners (eventName?: string) { if (eventName) { this._events.delete(eventName); } diff --git a/src/core/Room.js b/src/core/Room.js index ddf0c4af4..25fd7a6ed 100644 --- a/src/core/Room.js +++ b/src/core/Room.js @@ -1,3 +1,5 @@ +'use strict'; + class Room { /** diff --git a/src/core/searchResult/Profile.js b/src/core/searchResult/Profile.js deleted file mode 100644 index ac7de860b..000000000 --- a/src/core/searchResult/Profile.js +++ /dev/null @@ -1,29 +0,0 @@ -const { Profile } = require('../security/Profile'); -const { SearchResultBase } = require('./SearchResultBase'); - -class ProfileSearchResult extends SearchResultBase { - constructor (kuzzle, request, options, response) { - super(kuzzle, request, options, response); - - this._searchAction = 'searchProfiles'; - this._scrollAction = 'scrollProfiles'; - this.hits = response.hits.map( - hit => new Profile(this._kuzzle, hit._id, hit._source)); - } - - next () { - return super.next() - .then(nextSearchResult => { - if (! nextSearchResult) { - return null; - } - - nextSearchResult.hits = nextSearchResult._response.hits.map( - hit => new Profile(nextSearchResult._kuzzle, hit._id, hit._source)); - - return nextSearchResult; - }); - } -} - -module.exports = { ProfileSearchResult }; diff --git a/src/core/searchResult/Profile.ts b/src/core/searchResult/Profile.ts new file mode 100644 index 000000000..08d9e131c --- /dev/null +++ b/src/core/searchResult/Profile.ts @@ -0,0 +1,29 @@ +import { Profile } from '../security/Profile'; +import { SearchResultBase } from './SearchResultBase'; + +export class ProfileSearchResult extends SearchResultBase { + constructor (kuzzle, request, options, response) { + super(kuzzle, request, options, response); + + this._searchAction = 'searchProfiles'; + this._scrollAction = 'scrollProfiles'; + this.hits = response.hits.map(hit => ( + new Profile(this._kuzzle, hit._id, hit._source) + )); + } + + next () { + return super.next() + .then((nextSearchResult: ProfileSearchResult) => { + if (! nextSearchResult) { + return null; + } + + nextSearchResult.hits = nextSearchResult._response.hits.map(hit => ( + new Profile(nextSearchResult._kuzzle, hit._id, hit._source) + )); + + return nextSearchResult; + }); + } +} diff --git a/src/core/searchResult/Role.js b/src/core/searchResult/Role.ts similarity index 63% rename from src/core/searchResult/Role.js rename to src/core/searchResult/Role.ts index 241e310da..4cbbb48aa 100644 --- a/src/core/searchResult/Role.js +++ b/src/core/searchResult/Role.ts @@ -1,7 +1,7 @@ -const { Role } = require('../security/Role'); -const { SearchResultBase } = require('./SearchResultBase'); +import { Role } from '../security/Role'; +import { SearchResultBase } from './SearchResultBase'; -class RoleSearchResult extends SearchResultBase { +export class RoleSearchResult extends SearchResultBase { constructor (kuzzle, query, options, response) { super(kuzzle, query, options, response); @@ -9,7 +9,9 @@ class RoleSearchResult extends SearchResultBase { this._searchAction = 'searchRoles'; this._scrollAction = null; // scrollRoles action does not exists in Kuzzle API. - this.hits = this._response.hits.map(hit => new Role(this._kuzzle, hit._id, hit._source.controllers)); + this.hits = this._response.hits.map(hit => ( + new Role(this._kuzzle, hit._id, hit._source.controllers) + )); } next () { @@ -20,16 +22,16 @@ class RoleSearchResult extends SearchResultBase { } return super.next() - .then(nextSearchResult => { + .then((nextSearchResult: RoleSearchResult) => { if (! nextSearchResult) { return null; } - nextSearchResult.hits = nextSearchResult._response.hits.map(hit => new Role(nextSearchResult._kuzzle, hit._id, hit._source.controllers)); + nextSearchResult.hits = nextSearchResult._response.hits.map(hit => ( + new Role(nextSearchResult._kuzzle, hit._id, hit._source.controllers) + )); return nextSearchResult; }); } } - -module.exports = { RoleSearchResult }; diff --git a/src/core/searchResult/SearchResultBase.ts b/src/core/searchResult/SearchResultBase.ts index a6c2da445..c48ea9c71 100644 --- a/src/core/searchResult/SearchResultBase.ts +++ b/src/core/searchResult/SearchResultBase.ts @@ -55,17 +55,10 @@ export class SearchResultBase implements SearchResult { public fetched: number; - /** - * - * @param {Kuzzle} kuzzle - * @param {object} request - * @param {object} options - * @param {object} response - */ constructor ( kuzzle: Kuzzle, request: KuzzleRequest = {}, - options: any = {}, + options: JSONObject = {}, response: any = {} ) { Reflect.defineProperty(this, '_kuzzle', { @@ -80,10 +73,18 @@ export class SearchResultBase implements SearchResult { Reflect.defineProperty(this, '_response', { value: response }); - - this._controller = request.controller; - this._searchAction = 'search'; - this._scrollAction = 'scroll'; + Reflect.defineProperty(this, '_controller', { + value: request.controller, + writable: true + }); + Reflect.defineProperty(this, '_searchAction', { + value: 'search', + writable: true + }); + Reflect.defineProperty(this, '_scrollAction', { + value: 'scroll', + writable: true + }); this.aggregations = response.aggregations; this.hits = response.hits || []; @@ -166,7 +167,7 @@ export class SearchResultBase implements SearchResult { return Promise.reject(new Error('Unable to retrieve next results from search: missing scrollId, from/sort, or from/size params')); } - _get (object, path) { + protected _get (object, path) { if (!object) { return object; } @@ -179,7 +180,7 @@ export class SearchResultBase implements SearchResult { return this._get(object[key], path); } - _buildNextSearchResult (response) { + protected _buildNextSearchResult (response) { const Constructor: any = this.constructor; const nextSearchResult = new Constructor(this._kuzzle, this._request, this._options, response.result); @@ -187,8 +188,4 @@ export class SearchResultBase implements SearchResult { return nextSearchResult; } - } - - -module.exports = { SearchResultBase }; diff --git a/src/core/searchResult/Specifications.js b/src/core/searchResult/Specifications.ts similarity index 56% rename from src/core/searchResult/Specifications.js rename to src/core/searchResult/Specifications.ts index 15d2d2410..54b21df0f 100644 --- a/src/core/searchResult/Specifications.js +++ b/src/core/searchResult/Specifications.ts @@ -1,6 +1,7 @@ -const { SearchResultBase } = require('./SearchResultBase'); +import { SearchResultBase } from './SearchResultBase'; +import { JSONObject } from '../../utils/interfaces'; -class SpecificationsSearchResult extends SearchResultBase { +export class SpecificationsSearchResult extends SearchResultBase { constructor (kuzzle, query, options, response) { super(kuzzle, query, options, response); @@ -10,5 +11,3 @@ class SpecificationsSearchResult extends SearchResultBase { this._scrollAction = 'scrollSpecifications'; } } - -module.exports = { SpecificationsSearchResult }; diff --git a/src/core/searchResult/User.js b/src/core/searchResult/User.js deleted file mode 100644 index 20ec93dcb..000000000 --- a/src/core/searchResult/User.js +++ /dev/null @@ -1,27 +0,0 @@ -const { SearchResultBase } = require('./SearchResultBase'); -const { User } = require('../security/User'); - -class UserSearchResult extends SearchResultBase { - - constructor (kuzzle, query, options, response) { - super(kuzzle, query, options, response); - - this._searchAction = 'searchUsers'; - this._scrollAction = 'scrollUsers'; - this.hits = this._response.hits.map(hit => new User(this._kuzzle, hit._id, hit._source)); - } - - next () { - return super.next() - .then(nextSearchResult => { - if (! nextSearchResult) { - return null; - } - - nextSearchResult.hits = nextSearchResult._response.hits.map(hit => new User(nextSearchResult._kuzzle, hit._id, hit._source)); - return nextSearchResult; - }); - } -} - -module.exports = { UserSearchResult }; diff --git a/src/core/searchResult/User.ts b/src/core/searchResult/User.ts new file mode 100644 index 000000000..501b88b71 --- /dev/null +++ b/src/core/searchResult/User.ts @@ -0,0 +1,30 @@ +import { SearchResultBase } from './SearchResultBase'; +import { User } from '../security/User'; + +export class UserSearchResult extends SearchResultBase { + + constructor (kuzzle, query, options, response) { + super(kuzzle, query, options, response); + + this._searchAction = 'searchUsers'; + this._scrollAction = 'scrollUsers'; + this.hits = this._response.hits.map(hit => ( + new User(this._kuzzle, hit._id, hit._source) + )); + } + + next () { + return super.next() + .then((nextSearchResult: UserSearchResult) => { + if (! nextSearchResult) { + return null; + } + + nextSearchResult.hits = nextSearchResult._response.hits.map(hit => ( + new User(nextSearchResult._kuzzle, hit._id, hit._source) + )); + + return nextSearchResult; + }); + } +} diff --git a/src/core/security/Profile.ts b/src/core/security/Profile.ts index 12e18010a..044844635 100644 --- a/src/core/security/Profile.ts +++ b/src/core/security/Profile.ts @@ -52,6 +52,3 @@ export class Profile { options); } } - -module.exports = { Profile }; - diff --git a/src/protocols/Http.js b/src/protocols/Http.ts similarity index 77% rename from src/protocols/Http.js rename to src/protocols/Http.ts index e7f1d86fe..8525c9bfa 100644 --- a/src/protocols/Http.js +++ b/src/protocols/Http.ts @@ -1,10 +1,40 @@ 'use strict'; -const staticHttpRoutes = require('./routes.json'); -const { KuzzleAbstractProtocol } = require('./abstract/Base'); +import staticHttpRoutes from './routes.json'; +import { KuzzleAbstractProtocol } from './abstract/Base'; +import { HttpRoutes, JSONObject, KuzzleRequest } from '../utils/interfaces'; + +/** + * Http protocol used to connect to a Kuzzle server. + * + * The Http protocol cannot use the realtime capabilities of Kuzzle. + */ +export default class HttpProtocol extends KuzzleAbstractProtocol { + private _routes: HttpRoutes; + private _timeout: number; + private _customRoutes: HttpRoutes; -class HttpProtocol extends KuzzleAbstractProtocol { - constructor(host, options = {}) { + /** + * @param host Kuzzle server hostname or IP + * @param options Http connection options + * - `customRoutes` Add custom routes + * - `port` Kuzzle server port (default: `7512`) + * - `ssl` Use SSL to connect to Kuzzle server. Default `false` unless port is 443 or 7443. + * - `timeout` Connection timeout in milliseconds (default: `0`) + */ + constructor( + host: string, + options: { + port?: number; + /** + * @deprecated Use `ssl` instead + */ + sslConnection?: boolean; + ssl?: boolean; + customRoutes?: HttpRoutes; + timeout?: number + } = {} + ) { super(host, options, 'http'); if (typeof host !== 'string' || host === '') { @@ -15,10 +45,10 @@ class HttpProtocol extends KuzzleAbstractProtocol { this._timeout = options.timeout || 0; - this.customRoutes = options.customRoutes || {}; + this._customRoutes = options.customRoutes || {}; - for (const controller of Object.keys(this.customRoutes)) { - const definition = this.customRoutes[controller]; + for (const controller of Object.keys(this._customRoutes)) { + const definition = this._customRoutes[controller]; for (const action of Object.keys(definition)) { const route = definition[action]; @@ -35,35 +65,49 @@ class HttpProtocol extends KuzzleAbstractProtocol { } } - // @deprecated + /** + * @deprecated Use `routes` instead + */ get http () { return this.routes; } - get routes () { + /** + * Returns a list of available routes + */ + get routes (): HttpRoutes { return this._routes; } - get protocol () { + /** + * `http` or `https` + */ + get protocol (): string { return this.ssl ? 'https' : 'http'; } - get connected () { + /** + * Always returns `true` + */ + get connected (): true { return true; } - get timeout () { + /** + * Connection timeout in milliseconds + */ + get timeout (): number { return this._timeout; } - set timeout (timeout) { + set timeout (timeout: number) { this._timeout = timeout; } /** * Connect to the server */ - connect () { + connect (): Promise { if (this.state === 'ready') { return Promise.resolve(); } @@ -92,7 +136,6 @@ class HttpProtocol extends KuzzleAbstractProtocol { .then(({ result: res, error: err }) => { if (! err) { this._routes = this._constructRoutes(res.serverInfo.kuzzle.api.routes); - this._staticRoutes = false; return; } @@ -114,13 +157,13 @@ class HttpProtocol extends KuzzleAbstractProtocol { throw error; }) .then(() => { - this._routes = Object.assign(this._routes, this.customRoutes); + this._routes = Object.assign(this._routes, this._customRoutes); // Client is ready this.clientConnected(); }) .catch(err => { - const connectionError = new Error(`Unable to connect to kuzzle server at ${this.host}:${this.port}`); + const connectionError: any = new Error(`Unable to connect to kuzzle server at ${this.host}:${this.port}`); connectionError.internal = err; this.emit('networkError', connectionError); @@ -134,19 +177,19 @@ class HttpProtocol extends KuzzleAbstractProtocol { * @param {Object} data * @returns {Promise} */ - send (data, options = {}) { - const route = this.routes[data.controller] - && this.routes[data.controller][data.action]; + send (request: KuzzleRequest, options: JSONObject = {}) { + const route = this.routes[request.controller] + && this.routes[request.controller][request.action]; if (! route) { - const error = new Error(`No URL found for "${data.controller}:${data.action}".`); - this.emit(data.requestId, { status: 400, error }); + const error = new Error(`No URL found for "${request.controller}:${request.action}".`); + this.emit(request.requestId, { status: 400, error }); return; } const method = options.verb || route.verb; - const payload = { + const payload: any = { action: undefined, body: undefined, collection: undefined, @@ -160,8 +203,8 @@ class HttpProtocol extends KuzzleAbstractProtocol { }; const queryArgs = {}; - for (const key of Object.keys(data)) { - const value = data[key]; + for (const key of Object.keys(request)) { + const value = request[key]; if (key === 'body') { if (method === 'GET') { @@ -191,7 +234,7 @@ class HttpProtocol extends KuzzleAbstractProtocol { let matches = regex.exec(url); while (matches) { - const urlParam = data[ matches[1] ]; + const urlParam = request[ matches[1] ]; // check if an url param is missing (eg: "/:index/_create) if (!urlParam) { @@ -201,9 +244,9 @@ class HttpProtocol extends KuzzleAbstractProtocol { return; } - url = url.replace(regex, `/${encodeURIComponent(data[matches[1]])}`); + url = url.replace(regex, `/${encodeURIComponent(request[matches[1]])}`); - delete(queryArgs[ matches[1] ]); + delete queryArgs[matches[1]]; matches = regex.exec(url); } @@ -242,10 +285,11 @@ class HttpProtocol extends KuzzleAbstractProtocol { .catch(error => this.emit(payload.requestId, {error})); } - _sendHttpRequest (method, path, payload = {}) { + _sendHttpRequest (method, path, payload: any = {}) { if (typeof XMLHttpRequest === 'undefined') { // NodeJS implementation, using http.request: + // eslint-disable-next-line @typescript-eslint/no-var-requires const httpClient = require('min-req-promise'); if (path[0] !== '/') { @@ -328,8 +372,8 @@ class HttpProtocol extends KuzzleAbstractProtocol { return routes; }, {}); - for (const controller of Object.keys(this.customRoutes)) { - apiRoutes[controller] = this.customRoutes[controller]; + for (const controller of Object.keys(this._customRoutes)) { + apiRoutes[controller] = this._customRoutes[controller]; } return apiRoutes; @@ -371,5 +415,3 @@ function getCorrectRoute (routes) { // will be in the query string return sameLength ? getRoute : shortestRoute; } - -module.exports = HttpProtocol; diff --git a/src/protocols/WebSocket.js b/src/protocols/WebSocket.ts similarity index 66% rename from src/protocols/WebSocket.js rename to src/protocols/WebSocket.ts index f2d05e1fb..d1438cda3 100644 --- a/src/protocols/WebSocket.js +++ b/src/protocols/WebSocket.ts @@ -1,11 +1,62 @@ 'use strict'; -const KuzzleError = require('../KuzzleError'); -const BaseProtocolRealtime = require('./abstract/Realtime'); +import { KuzzleError } from '../KuzzleError'; +import { BaseProtocolRealtime } from './abstract/Realtime'; +import { JSONObject, KuzzleRequest } from '../utils/interfaces'; + +/** + * WebSocket protocol used to connect to a Kuzzle server. + */ +export default class WebSocketProtocol extends BaseProtocolRealtime { + private WebSocketClient: any; + private options: any; + private client: any; + private lasturl: any; -class WebSocketProtocol extends BaseProtocolRealtime { + /** + * Automatically reconnect after a connection loss + */ + public autoReconnect: boolean; + /** + * `true` if the socket is open + */ + public connected: boolean; + /** + * Kuzzle server host or IP + */ + public host: string; + /** + * Kuzzle server port + */ + public port: number; + /** + * `true` if ssl is active + */ + public ssl: boolean; - constructor(host, options = {}) { + /** + * @param host Kuzzle server hostname or IP + * @param options WebSocket connection options + * - `autoReconnect` Automatically reconnect to kuzzle after a `disconnected` event. (default: `true`) + * - `port` Kuzzle server port (default: `7512`) + * - `headers` Connection custom HTTP headers (Not supported by browsers) + * - `reconnectionDelay` Number of milliseconds between reconnection attempts (default: `1000`) + * - `ssl` Use SSL to connect to Kuzzle server. Default `false` unless port is 443 or 7443. + */ + constructor( + host: string, + options: { + autoReconnect?: boolean; + port?: number; + headers?: JSONObject; + reconnectionDelay?: number; + /** + * @deprecated Use `ssl` instead + */ + sslConnection?: boolean; + ssl?: boolean; + } = {} + ) { super(host, options, 'ws'); if (typeof host !== 'string' || host === '') { @@ -39,7 +90,7 @@ class WebSocketProtocol extends BaseProtocolRealtime { /** * Connect to the websocket server */ - connect () { + connect (): Promise { return new Promise((resolve, reject) => { const url = `${this.ssl ? 'wss' : 'ws'}://${this.host}:${this.port}`; @@ -79,7 +130,7 @@ class WebSocketProtocol extends BaseProtocolRealtime { // do not forward a connection close error if no // connection has been previously established else if (this.wasConnected) { - const error = new Error(reason); + const error: any = new Error(reason); error.status = status; this.clientNetworkError(error); @@ -127,9 +178,9 @@ class WebSocketProtocol extends BaseProtocolRealtime { * * @param {Object} payload */ - send (payload) { + send (request: KuzzleRequest) { if (this.client && this.client.readyState === this.client.OPEN) { - this.client.send(JSON.stringify(payload)); + this.client.send(JSON.stringify(request)); } } @@ -148,5 +199,3 @@ class WebSocketProtocol extends BaseProtocolRealtime { super.close(); } } - -module.exports = WebSocketProtocol; diff --git a/src/protocols/abstract/Base.js b/src/protocols/abstract/Base.ts similarity index 63% rename from src/protocols/abstract/Base.js rename to src/protocols/abstract/Base.ts index 258c6082e..ec60e6cc1 100644 --- a/src/protocols/abstract/Base.js +++ b/src/protocols/abstract/Base.ts @@ -1,12 +1,26 @@ 'use strict'; -const KuzzleError = require('../../KuzzleError'); -const { uuidv4 } = require('../../utils/uuidv4'); -const { KuzzleEventEmitter } = require('../../core/KuzzleEventEmitter'); -const PendingRequest = require('./PendingRequest'); - -class KuzzleAbstractProtocol extends KuzzleEventEmitter { - constructor (host, options = {}, name = undefined) { +import { KuzzleError } from '../../KuzzleError'; +import { uuidv4 } from '../../utils/uuidv4'; +import { KuzzleEventEmitter } from '../../core/KuzzleEventEmitter'; +import { PendingRequest } from './PendingRequest'; +import { KuzzleRequest, JSONObject } from '../../utils/interfaces'; + +/** + * @todo proper TS conversion + */ +export abstract class KuzzleAbstractProtocol extends KuzzleEventEmitter { + private _pendingRequests: Map; + private _host: string; + private _name: string; + private _port: number; + private _ssl: boolean; + + public id: string; + + public state: string; + + constructor (host: string, options: JSONObject = {}, name: string = undefined) { super(); this._pendingRequests = new Map(); @@ -14,7 +28,23 @@ class KuzzleAbstractProtocol extends KuzzleEventEmitter { this._name = name; const port = parseInt(options.port, 10); this._port = isNaN(port) ? 7512 : port; - this._ssl = typeof options.sslConnection === 'boolean' ? options.sslConnection : false; + + if (options.ssl !== undefined && options.sslConnection !== undefined) { + throw new Error('Both "ssl" and "sslConnection" options are set. Use only "ssl".'); + } + + if (typeof options.ssl === 'boolean') { + this._ssl = options.ssl; + } + else if (typeof options.sslConnection === 'boolean') { + this._ssl = options.sslConnection; + } + else if (port === 443 || port === 7443) { + this._ssl = true; + } + else { + this._ssl = false; + } this.id = uuidv4(); this.state = 'offline'; @@ -52,27 +82,14 @@ class KuzzleAbstractProtocol extends KuzzleEventEmitter { return this._pendingRequests; } - /** - * @abstract - * @returns {Promise} - */ - connect () { - throw new Error('Method "connect" is not implemented'); - } + abstract connect (): Promise - /** - * @abstract - * @param request - * @returns {Promise} - */ - send () { - throw new Error('Method "send" is not implemented'); - } + abstract send (request: KuzzleRequest, options: JSONObject): void /** * Called when the client's connection is established */ - clientConnected (state, wasConnected) { + clientConnected (state?: string, wasConnected?: boolean) { this.state = state || 'ready'; this.emit(wasConnected && 'reconnect' || 'connect'); } @@ -92,6 +109,8 @@ class KuzzleAbstractProtocol extends KuzzleEventEmitter { Discarded request: ${JSON.stringify(request)}`)); } + const stack = Error().stack; + const pending = new PendingRequest(request); this._pendingRequests.set(request.requestId, pending); @@ -99,7 +118,7 @@ Discarded request: ${JSON.stringify(request)}`)); this._pendingRequests.delete(request.requestId); if (response.error) { - const error = new KuzzleError(response.error); + const error = new KuzzleError(response.error, stack); this.emit('queryError', error, request); @@ -136,7 +155,4 @@ Discarded request: ${JSON.stringify(request)}`)); this._pendingRequests.clear(); } - } - -module.exports = { KuzzleAbstractProtocol }; diff --git a/src/protocols/abstract/PendingRequest.js b/src/protocols/abstract/PendingRequest.js index 852ea9a0b..73aa5dfbd 100644 --- a/src/protocols/abstract/PendingRequest.js +++ b/src/protocols/abstract/PendingRequest.js @@ -20,4 +20,4 @@ class PendingRequest { } } -module.exports = PendingRequest; +module.exports = { PendingRequest }; diff --git a/src/protocols/abstract/Realtime.js b/src/protocols/abstract/Realtime.ts similarity index 72% rename from src/protocols/abstract/Realtime.js rename to src/protocols/abstract/Realtime.ts index 0dab94019..74bb34cc0 100644 --- a/src/protocols/abstract/Realtime.js +++ b/src/protocols/abstract/Realtime.ts @@ -1,10 +1,16 @@ 'use strict'; -const { KuzzleAbstractProtocol } = require('./Base'); +import { KuzzleAbstractProtocol } from './Base'; -class BaseProtocolRealtime extends KuzzleAbstractProtocol { - constructor (host, options = {}) { - super(host, options); +export abstract class BaseProtocolRealtime extends KuzzleAbstractProtocol { + protected _autoReconnect: boolean; + protected _reconnectionDelay: number; + protected wasConnected: boolean; + protected stopRetryingToConnect: boolean; + protected retrying: boolean; + + constructor (host, options: any = {}, name: string) { + super(host, options, name); this._autoReconnect = typeof options.autoReconnect === 'boolean' ? options.autoReconnect : true; this._reconnectionDelay = typeof options.reconnectionDelay === 'number' ? options.reconnectionDelay : 1000; @@ -18,18 +24,23 @@ class BaseProtocolRealtime extends KuzzleAbstractProtocol { return this._autoReconnect; } - get reconnectionDelay () { + /** + * Number of milliseconds between reconnection attempts + */ + get reconnectionDelay (): number { return this._reconnectionDelay; } - connect() { + connect (): Promise { this.state = 'connecting'; + + return Promise.resolve(); } /** * Called when the client's connection is established */ - clientConnected() { + clientConnected () { super.clientConnected('connected', this.wasConnected); this.state = 'connected'; @@ -40,7 +51,7 @@ class BaseProtocolRealtime extends KuzzleAbstractProtocol { /** * Called when the client's connection is closed */ - clientDisconnected() { + clientDisconnected () { this.clear(); this.emit('disconnect'); } @@ -54,8 +65,7 @@ class BaseProtocolRealtime extends KuzzleAbstractProtocol { this.state = 'offline'; this.clear(); - const connectionError = new Error(`Unable to connect to kuzzle server at ${this.host}:${this.port}`); - connectionError.internal = error; + const connectionError = new Error(`Unable to connect to kuzzle server at ${this.host}:${this.port}: ${error.message} (ws status=${error.status})`); this.emit('networkError', connectionError); @@ -90,5 +100,3 @@ class BaseProtocolRealtime extends KuzzleAbstractProtocol { return this.state === 'connected'; } } - -module.exports = BaseProtocolRealtime; diff --git a/src/protocols/index.js b/src/protocols/index.js deleted file mode 100644 index 1e39ea546..000000000 --- a/src/protocols/index.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict'; - -const Http = require('./Http'); -const WebSocket = require('./WebSocket'); - -module.exports = { - Http, - WebSocket -}; diff --git a/src/protocols/index.ts b/src/protocols/index.ts new file mode 100644 index 000000000..51c13cd4a --- /dev/null +++ b/src/protocols/index.ts @@ -0,0 +1,2 @@ +export { default as WebSocket } from './WebSocket'; +export { default as Http } from './Http'; diff --git a/src/utils/interfaces.ts b/src/utils/interfaces.ts index 6062231a3..cfb3d9ae3 100644 --- a/src/utils/interfaces.ts +++ b/src/utils/interfaces.ts @@ -21,6 +21,31 @@ export interface KuzzleRequest extends JSONObject { jwt?: string; volatile?: JSONObject; body?: JSONObject; + [key: string]: any; +} + +/** + * Kuzzle API response + * + * @see https://docs.kuzzle.io/core/2/api/essentials/kuzzle-response/ + */ +export interface KuzzleResponse extends JSONObject { + controller: string; + action: string; + index?: string; + collection?: string; + error?: { + id: string; + code: number; + message: string; + status: number; + stack?: string; + }; + requestId: string; + result: JSONObject | null; + status: number; + volatile?: JSONObject; + room?: string; } /** @@ -88,8 +113,14 @@ export interface ProfilePolicy { * @see https://docs.kuzzle.io/core/2/guides/essentials/security#defining-roles */ export interface RoleRightsDefinition { + /** + * API controller name + */ [key: string]: { actions: { + /** + * API action name + */ [key: string]: boolean } } @@ -112,7 +143,7 @@ export interface ApiKey { */ userId: string; /** - * Expiration date in UNIX micro-timestamp format (-1 if the token never expires) + * Expiration date in Epoch-millis format (-1 if the token never expires) */ expiresAt: number; /** @@ -178,6 +209,11 @@ export interface Document { /** * Document retrieved from a search + * + * @property _id + * @property _version + * @property _source + * @property _score */ export interface DocumentHit extends Document { /** @@ -185,3 +221,214 @@ export interface DocumentHit extends Document { */ _score: number; } + +export interface MappingsProperties { + /** + * Properties types definition + * + * @see https://docs.kuzzle.io/core/2/guides/essentials/database-mappings/#properties-types-definition + */ + properties?: MappingsProperties, + /** + * Dynamic mapping policy + * + * @see https://docs.kuzzle.io/core/2/guides/essentials/database-mappings/#dynamic-mapping-policy + */ + dynamic?: 'true' | 'false' | 'strict' | boolean +} + +/** + * Collection mappings definition + * + * @see https://docs.kuzzle.io/core/2/guides/essentials/database-mappings/ + */ +export interface CollectionMappings { + /** + * Collection metadata + * + * @see https://docs.kuzzle.io/core/2/guides/essentials/database-mappings/#collection-metadata + */ + _meta?: JSONObject; + /** + * Properties types definition + * + * @see https://docs.kuzzle.io/core/2/guides/essentials/database-mappings/#properties-types-definition + */ + properties?: MappingsProperties, + /** + * Dynamic mapping policy + * + * @see https://docs.kuzzle.io/core/2/guides/essentials/database-mappings/#dynamic-mapping-policy + */ + dynamic?: 'true' | 'false' | 'strict' | boolean, +} + +/** + * Enum for notification types + */ +export enum ENotificationType { + document = 'document', + user = 'user', + TokenExpired = 'TokenExpired' +} + +/** + * Real-time notifications sent by Kuzzle. + * + */ +export interface Notification { + /** + * Notification type + */ + type: ENotificationType; +} + +export interface BaseNotification extends Notification { + /** + * Controller that triggered the notification + */ + controller: string; + /** + * Action that triggered the notification + */ + action: string; + /** + * Index name + */ + index: string; + /** + * Collection name + */ + collection: string; + /** + * Network protocol used to trigger the notification + */ + protocol: string; + /** + * Subscription channel identifier. + * Can be used to link a notification to its corresponding subscription + */ + room: string; + /** + * Timestamp of the event, in Epoch-millis format + */ + timestamp: number; + /** + * Request volatile data + * @see https://docs.kuzzle.io/core/2/guides/essentials/volatile-data/ + */ + volatile: JSONObject; +} + +/** + * State of the document regarding the scope + */ +export enum EDocumentScope { + /** + * Document enters or stays in the scope + */ + in = 'in', + /** + * Document exit the scope + */ + out = 'out' +} + +/** + * Notification triggered by a document change. + * (create, update, delete) + */ +export interface DocumentNotification extends BaseNotification { + /** + * Updated document that triggered the notification + */ + result: Document; + /** + * State of the document regarding the scope (`in` or `out`) + */ + scope: EDocumentScope; + + type: ENotificationType.document; +} + +/** + * Tells wether an user leave or join the subscription room + */ +export enum EUserScope { + /** + * User enters the subscription room + */ + in = 'in', + /** + * User leaves the subscription room + */ + out = 'out' +} + +/** + * Notification triggered by an user joining or leaving a subscription room + */ +export interface UserNotification extends BaseNotification { + /** + * Tell wether an user leave or join the subscription room (`in` or `out`) + */ + user: EUserScope; + + /** + * Contains the actual number of users in the subscription room + */ + result: { + /** + * Updated users count sharing the same subscription room + */ + count: number; + } + + type: ENotificationType.user; +} + +export interface ServerNotification extends BaseNotification { + /** + * Server message explaining why this notifications has been triggered + */ + message: string; + + type: ENotificationType.TokenExpired; +} + +/** + * HTTP routes definition format + * @example + * { + * : { + * : { verb: , url: } + * } + * } + * + * { + * 'my-plugin/my-controller': { + * action: { verb: 'GET', url: '/some/url' }, + * action2: { verb: 'GET', url: '/some/url/with/:parameter' } + * } + * } + */ +export interface HttpRoutes { + /** + * Controller name + */ + [key: string]: { + /** + * Action name + */ + [key: string]: { + /** + * HTTP verb + */ + verb: string, + /** + * URL + */ + url: string + } + } +} diff --git a/test/controllers/collection.test.js b/test/controllers/collection.test.js index 03e83489f..ae9ba248a 100644 --- a/test/controllers/collection.test.js +++ b/test/controllers/collection.test.js @@ -16,7 +16,7 @@ describe('Collection Controller', () => { }); describe('create', () => { - it('should call collection/create query and return a Promise which resolves an acknowledgement', () => { + it('should call collection/create query and return a Promise which resolves', () => { kuzzle.query.resolves({result: {acknowledged: true}}); return kuzzle.collection.create('index', 'collection', null, options) @@ -31,7 +31,7 @@ describe('Collection Controller', () => { collection: 'collection' }, options); - should(res.acknowledged).be.a.Boolean().and.be.true(); + should(res).be.undefined(); }); }); @@ -50,13 +50,13 @@ describe('Collection Controller', () => { collection: 'collection' }, options); - should(res.acknowledged).be.a.Boolean().and.be.true(); + should(res).be.undefined(); }); }); }); describe('deleteSpecifications', () => { - it('should call collection/deleteSpecifications query and return a Promise which resolves an acknowledgement', () => { + it('should call collection/deleteSpecifications query and return a Promise which resolves', () => { kuzzle.query.resolves({result: {acknowledged: true}}); return kuzzle.collection.deleteSpecifications('index', 'collection', options) @@ -70,7 +70,7 @@ describe('Collection Controller', () => { collection: 'collection' }, options); - should(res.acknowledged).be.a.Boolean().and.be.true(); + should(res).be.undefined(); }); }); }); @@ -110,7 +110,7 @@ describe('Collection Controller', () => { collection: 'collection' }, options); - should(res).be.Null(); + should(res).be.undefined(); }); }); }); @@ -301,7 +301,7 @@ describe('Collection Controller', () => { collection: 'collection' }, options); - should(res.acknowledged).be.a.Boolean().and.be.true(); + should(res).be.undefined(); }); }); }); @@ -345,7 +345,7 @@ describe('Collection Controller', () => { collection: 'collection' }); - should(res).match({ foo: 'bar' }); + should(res).be.undefined(); }); }); }); @@ -403,4 +403,22 @@ describe('Collection Controller', () => { }); }); }); + + describe('delete', () => { + it('should call collection/delete query and return a promise which resolves an acknowledgement', () => { + kuzzle.query.resolves({result: {acknowledged: true}}); + return kuzzle.collection.delete('index', 'collection') + .then(res => { + should(kuzzle.query) + .be.calledOnce() + .be.calledWith({ + controller: 'collection', + action: 'delete', + index: 'index', + collection: 'collection', + }); + should(res).be.undefined(); + }); + }); + }); }); diff --git a/test/controllers/index.test.js b/test/controllers/index.test.js index 409a9ed13..8bd2e901a 100644 --- a/test/controllers/index.test.js +++ b/test/controllers/index.test.js @@ -33,8 +33,7 @@ describe('Index Controller', () => { index: 'index' }, options); - should(res.acknowledged).be.a.Boolean().and.be.true(); - should(res.shards_acknowledged).be.a.Boolean().and.be.true(); + should(res).be.undefined(); }); }); }); @@ -55,7 +54,7 @@ describe('Index Controller', () => { index: 'index' }, options); - should(res).be.a.Boolean().and.be.true(); + should(res).be.undefined(); }); }); }); diff --git a/test/controllers/realtime.test.js b/test/controllers/realtime.test.js index c264a24cb..698ecd767 100644 --- a/test/controllers/realtime.test.js +++ b/test/controllers/realtime.test.js @@ -26,17 +26,52 @@ describe('Realtime Controller', () => { }); describe('on: tokenExpired', () => { - it('should call tokenExpired() method', () => { - kuzzle.realtime.tokenExpired = sinon.stub(); + it('should call removeSubscriptions() method', () => { + kuzzle.realtime.removeSubscriptions = sinon.stub(); kuzzle.emit('tokenExpired'); process.nextTick(() => { - should(kuzzle.realtime.tokenExpired).be.called(); + should(kuzzle.realtime.removeSubscriptions).be.called(); }); }); }); + describe('on: disconnected', () => { + it('should call saveSubscriptions() method', () => { + kuzzle.realtime.saveSubscriptions = sinon.stub(); + + kuzzle.emit('disconnected'); + + process.nextTick(() => { + should(kuzzle.realtime.saveSubscriptions).be.called(); + }); + }); + }); + + describe('on: networkError', () => { + it('should call saveSubscriptions() method', () => { + kuzzle.realtime.saveSubscriptions = sinon.stub(); + + kuzzle.emit('networkError'); + + process.nextTick(() => { + should(kuzzle.realtime.saveSubscriptions).be.called(); + }); + }); + }); + + describe('on: reconnected', () => { + it('should call resubscribe() method', () => { + kuzzle.realtime.resubscribe = sinon.stub(); + + kuzzle.emit('reconnected'); + + process.nextTick(() => { + should(kuzzle.realtime.resubscribe).be.called(); + }); + }); + }); describe('#count', () => { it('should call realtime/count query with the roomId and return a Promise which resolves a number', () => { @@ -139,17 +174,17 @@ describe('Realtime Controller', () => { body = {foo: 'bar'}, cb = sinon.stub(); - kuzzle.realtime.subscriptions = new Map(); + kuzzle.realtime._subscriptions = new Map(); return kuzzle.realtime.subscribe('index', 'collection', body, cb, options) .then(() => { - const subscriptions = kuzzle.realtime.subscriptions.get(roomId); + const subscriptions = kuzzle.realtime._subscriptions.get(roomId); should(subscriptions).be.an.Array(); should(subscriptions.length).be.exactly(1); should(subscriptions[0]).be.exactly(room); return kuzzle.realtime.subscribe('index', 'collection', body, cb, options); }).then(() => { - const subscriptions = kuzzle.realtime.subscriptions.get(roomId); + const subscriptions = kuzzle.realtime._subscriptions.get(roomId); should(subscriptions).be.an.Array(); should(subscriptions.length).be.exactly(2); @@ -175,8 +210,8 @@ describe('Realtime Controller', () => { room1.removeListeners.reset(); room2.removeListeners.reset(); - kuzzle.realtime.subscriptions.set(roomId, [room1, room2]); - kuzzle.realtime.subscriptions.set('foo', [room3]); + kuzzle.realtime._subscriptions.set(roomId, [room1, room2]); + kuzzle.realtime._subscriptions.set('foo', [room3]); kuzzle.query.resolves({result: roomId}); }); @@ -193,12 +228,12 @@ describe('Realtime Controller', () => { it('should delete rooms from local storage', () => { return kuzzle.realtime.unsubscribe(roomId) .then(() => { - should(kuzzle.realtime.subscriptions.get(roomId)).be.undefined(); + should(kuzzle.realtime._subscriptions.get(roomId)).be.undefined(); // Check we do not remove other registered rooms: - should(kuzzle.realtime.subscriptions.get('foo')).be.an.Array(); - should(kuzzle.realtime.subscriptions.get('foo').length).be.equal(1); - should(kuzzle.realtime.subscriptions.get('foo')[0]).be.equal(room3); + should(kuzzle.realtime._subscriptions.get('foo')).be.an.Array(); + should(kuzzle.realtime._subscriptions.get('foo').length).be.equal(1); + should(kuzzle.realtime._subscriptions.get('foo')[0]).be.equal(room3); }); }); @@ -218,7 +253,7 @@ describe('Realtime Controller', () => { }); }); - describe('#disconnected', () => { + describe('#saveSubscriptions', () => { it('should disable current subscriptions', () => { const roomA = { autoResubscribe: true, @@ -233,15 +268,15 @@ describe('Realtime Controller', () => { removeListeners: sinon.stub() }; - kuzzle.realtime.subscriptions = new Map([ + kuzzle.realtime._subscriptions = new Map([ ['foo', [roomA, roomB]], ['bar', [roomC]] ]); - kuzzle.realtime.disconnected(); + kuzzle.realtime.saveSubscriptions(); - should(kuzzle.realtime.subscriptions).be.empty(); - should(kuzzle.realtime.subscriptionsOff).eql(new Map([ + should(kuzzle.realtime._subscriptions).be.empty(); + should(kuzzle.realtime._subscriptionsOff).eql(new Map([ ['foo', [roomA]] ])); for (const room of [roomA, roomB, roomC]) { @@ -250,21 +285,21 @@ describe('Realtime Controller', () => { }); }); - describe('#reconnected', () => { + describe('#resubscribe', () => { it('should resubmit pending subcriptions', () => { const roomA = { subscribe: sinon.stub().resolves() }; const roomB = { subscribe: sinon.stub().resolves() }; const roomC = { subscribe: sinon.stub().resolves() }; - kuzzle.realtime.subscriptionsOff = new Map([ + kuzzle.realtime._subscriptionsOff = new Map([ ['foo', [roomA, roomB]], ['bar', [roomC]] ]); - kuzzle.realtime.reconnected(); + kuzzle.realtime.resubscribe(); - should(kuzzle.realtime.subscriptionsOff).be.empty(); - should(kuzzle.realtime.subscriptions).eql(new Map([ + should(kuzzle.realtime._subscriptionsOff).be.empty(); + should(kuzzle.realtime._subscriptions).eql(new Map([ ['foo', [roomA, roomB]], ['bar', [roomC]] ])); @@ -276,19 +311,19 @@ describe('Realtime Controller', () => { }); }); - describe('#tokenExpired', () => { - it('should clear all subscriptions and emit a "tokenExpired" event', () => { + describe('#removeSubscriptions', () => { + it('should clear all subscriptions', () => { const stub = sinon.stub(); kuzzle.jwt = 'foobar'; for (let i = 0; i < 10; i++) { - kuzzle.realtime.subscriptions.set(uuidv4(), [{removeListeners: stub}]); + kuzzle.realtime._subscriptions.set(uuidv4(), [{removeListeners: stub}]); } - kuzzle.realtime.tokenExpired(); + kuzzle.realtime.removeSubscriptions(); - should(kuzzle.realtime.subscriptions).be.empty(); + should(kuzzle.realtime._subscriptions).be.empty(); should(stub.callCount).be.eql(10); }); }); diff --git a/test/kuzzle/connect.test.js b/test/kuzzle/connect.test.js index 63c784b55..a151ffbd5 100644 --- a/test/kuzzle/connect.test.js +++ b/test/kuzzle/connect.test.js @@ -53,7 +53,7 @@ describe('Kuzzle connect', () => { kuzzle = new Kuzzle(protocols.nowhere), eventStub = sinon.stub(); - kuzzle.realtime.disconnected = sinon.stub(); + kuzzle.realtime.saveSubscriptions = sinon.stub(); kuzzle.addListener('networkError', eventStub); @@ -62,7 +62,7 @@ describe('Kuzzle connect', () => { throw new Error('should not happen'); }) .catch(() => { - should(kuzzle.realtime.disconnected).be.calledOnce(); + should(kuzzle.realtime.saveSubscriptions).be.calledOnce(); should(eventStub).be.calledOnce(); }); }); @@ -85,13 +85,13 @@ describe('Kuzzle connect', () => { kuzzle = new Kuzzle(protocols.somewhereagain), eventStub = sinon.stub(); - kuzzle.realtime.reconnected = sinon.stub(); + kuzzle.realtime.resubscribe = sinon.stub(); kuzzle.addListener('reconnected', eventStub); return kuzzle.connect() .then(() => { - should(kuzzle.realtime.reconnected).be.calledOnce(); + should(kuzzle.realtime.resubscribe).be.calledOnce(); should(eventStub).be.calledOnce(); }); }); @@ -137,14 +137,14 @@ describe('Kuzzle connect', () => { kuzzle = new Kuzzle(protocols.somewhere), eventStub = sinon.stub(); - kuzzle.realtime.disconnected = sinon.stub(); + kuzzle.realtime.saveSubscriptions = sinon.stub(); kuzzle.addListener('disconnected', eventStub); return kuzzle.connect() .then(() => kuzzle.protocol.disconnect()) .then(() => { - should(kuzzle.realtime.disconnected).be.calledOnce(); + should(kuzzle.realtime.saveSubscriptions).be.calledOnce(); should(eventStub).be.calledOnce(); }); }); diff --git a/test/kuzzle/listenersManagement.test.js b/test/kuzzle/listenersManagement.test.js index 0bd0599dc..a6d599315 100644 --- a/test/kuzzle/listenersManagement.test.js +++ b/test/kuzzle/listenersManagement.test.js @@ -2,7 +2,7 @@ const should = require('should'); const sinon = require('sinon'); const { Kuzzle } = require('../../src/Kuzzle'); -const { KuzzleEventEmitter } =require('../../src/core/KuzzleEventEmitter'); +const { KuzzleEventEmitter } = require('../../src/core/KuzzleEventEmitter'); const ProtocolMock = require('../mocks/protocol.mock'); describe('Kuzzle listeners management', () => { diff --git a/test/protocol/Base.test.js b/test/protocol/Base.test.js index bd2652459..bec5d3f0b 100644 --- a/test/protocol/Base.test.js +++ b/test/protocol/Base.test.js @@ -1,9 +1,9 @@ -const - should = require('should'), - sinon = require('sinon'), - KuzzleError = require('../../src/KuzzleError'), - { KuzzleAbstractProtocol } = require('../../src/protocols/abstract/Base'), - PendingRequest = require('../../src/protocols/abstract/PendingRequest'); +const should = require('should'); +const sinon = require('sinon'); + +const { KuzzleError } = require('../../src/KuzzleError'); +const { KuzzleAbstractProtocol } = require('../../src/protocols/abstract/Base'); +const { PendingRequest } = require('../../src/protocols/abstract/PendingRequest'); describe('Common Protocol', () => { let @@ -25,6 +25,30 @@ describe('Common Protocol', () => { should(protocol.port).be.eql(443); }); + it('should use ssl option if available and fallback to sslConnection option', () => { + protocol = new KuzzleAbstractProtocol('somewhere', { ssl: true }); + + should(protocol.ssl).be.true(); + + protocol = new KuzzleAbstractProtocol('somewhere', { sslConnection: true }); + + should(protocol.ssl).be.true(); + }); + + it('should use ssl connection when port is 443 or 7443 and option is not defined', () => { + protocol = new KuzzleAbstractProtocol('somewhere', { port: 443 }); + + should(protocol.ssl).be.true(); + + protocol = new KuzzleAbstractProtocol('somewhere', { port: 7443 }); + + should(protocol.ssl).be.true(); + + protocol = new KuzzleAbstractProtocol('somewhere', { port: 4242 }); + + should(protocol.ssl).be.false(); + }); + it('should use 7512 when no port is given or when port is not a parseable number', () => { protocol = new KuzzleAbstractProtocol('somewhere', { port: 'foobar' }); @@ -91,7 +115,7 @@ describe('Common Protocol', () => { const pending = protocol.pendingRequests.get('bar'); - pending.should.be.an.instanceOf(PendingRequest).and.match({request}); + should(pending).be.instanceOf(PendingRequest).and.match({request}); }); it('should fire a "queryError" event and reject if an error occurred', () => { @@ -161,7 +185,7 @@ describe('Common Protocol', () => { should(error).be.instanceOf(KuzzleError); should(error.message).be.eql('foo-bar'); should(error.status).be.eql(442); - should(error.stack).be.eql('you are the bug'); + should(error.kuzzleStack).be.eql('you are the bug'); }); }); @@ -185,7 +209,7 @@ describe('Common Protocol', () => { should(error).be.instanceOf(KuzzleError); should(error.message).be.eql('foo-bar'); should(error.status).be.eql(206); - should(error.stack).be.eql('you are the bug'); + should(error.kuzzleStack).be.eql('you are the bug'); should(error.errors).be.an.Array(); should(error.errors.length).eql(2); should(error.count).eql(42); diff --git a/test/protocol/Http.test.js b/test/protocol/Http.test.js index d435a1b1b..18e122f08 100644 --- a/test/protocol/Http.test.js +++ b/test/protocol/Http.test.js @@ -3,7 +3,7 @@ const should = require('should'); const sinon = require('sinon'); const staticHttpRoutes = require('../../src/protocols/routes.json'); -const Http = require('../../src/protocols/Http'); +const { default: Http } = require('../../src/protocols/Http'); describe('HTTP networking module', () => { let protocol; @@ -557,7 +557,7 @@ describe('HTTP networking module', () => { beforeEach(() => { httpRequestStub = sinon.stub().resolves({body: JSON.stringify(mockResponseBody)}); - const MockHttp = proxyquire('../../src/protocols/Http', { + const { default: MockHttp } = proxyquire('../../src/protocols/Http', { 'min-req-promise': {request: httpRequestStub} }); @@ -663,9 +663,7 @@ describe('HTTP networking module', () => { return xhrStub; }; - protocol = new Http('address', { - port: 1234 - }); + protocol = new Http('address', { port: 1234 }); }); afterEach(() => { @@ -829,13 +827,14 @@ describe('HTTP networking module', () => { } }, }; - - protocol.customRoutes = { + const customRoutes = { foo: { list: { verb: 'GET', url: '/overwrite/me/master' } } }; + protocol = new Http('address', { port: 1234, customRoutes }); + const routes = protocol._constructRoutes(publicApi); should(routes.foo.list.url).be.eql('/overwrite/me/master'); diff --git a/test/protocol/WebSocket.test.js b/test/protocol/WebSocket.test.js index cfd3d0989..205f0d443 100644 --- a/test/protocol/WebSocket.test.js +++ b/test/protocol/WebSocket.test.js @@ -1,10 +1,10 @@ -const - should = require('should'), - sinon = require('sinon'), - lolex = require('lolex'), - NodeWS = require('ws'), - WS = require('../../src/protocols/WebSocket'), - windowMock = require('../mocks/window.mock'); +const should = require('should'); +const sinon = require('sinon'); +const lolex = require('lolex'); +const NodeWS = require('ws'); + +const { default: WS } = require('../../src/protocols/WebSocket'); +const windowMock = require('../mocks/window.mock'); describe('WebSocket networking module', () => { let @@ -246,8 +246,6 @@ describe('WebSocket networking module', () => { clock.tick(10); should(cb).be.calledOnce(); should(cb.firstCall.args[0]).be.an.instanceOf(Error); - should(cb.firstCall.args[0].internal.status).be.equal(4666); - should(cb.firstCall.args[0].internal.message).be.equal('foobar'); should(websocket.listeners('networkError').length).be.eql(1); websocket.clear.should.be.calledOnce(); @@ -259,8 +257,6 @@ describe('WebSocket networking module', () => { clock.tick(10); should(cb).be.calledOnce(); should(cb.firstCall.args[0]).be.an.instanceOf(Error); - should(cb.firstCall.args[0].internal.status).be.equal(4666); - should(cb.firstCall.args[0].internal.message).be.equal('foobar'); should(websocket.listeners('networkError').length).be.eql(1); websocket.clear.should.be.calledOnce(); }); diff --git a/tsconfig.json b/tsconfig.json index 1ea049850..4af52bb73 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,8 @@ "moduleResolution": "node", "sourceMap": true, "baseUrl": ".", - "resolveJsonModule": true + "resolveJsonModule": true, + "esModuleInterop": true }, "rootDir": "src/", "include": [