Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

evrythng

evrythng142Apache-2.06.0.5

Official Javascript SDK for the EVRYTHNG API.

evrythng, iot, wot, internet of things, web of things

readme

evrythng.js

The official evrythng.js SDK facilitates communication with the EVRYTHNG REST API thanks to its fluent and resource oriented API. It can be used both for server-side scripting (Node.js) or in client-side web applications in modern browsers.

Installation

evrythng.js is distributed via NPM and the EVRYTHNG CDN, allowing you to manage the version of the library that your application or scripts uses.

NPM

Install as an app dependency:

npm install --save evrythng

or as a development dependency:

npm install --save-dev evrythng

Then require it in any module:

const evrythng = require('evrythng');

evrythng.api({ url: '/time' }).then(console.log).error(console.error);

Or using ES6 import/export syntax when available:

import { Application } from 'evrythng';
import evrythng from 'evrythng';

// Alternatively
import * as evrythng from 'evrythng';

CDN

Or use a simple script tag to load it from the CDN.

<script src="https://d10ka0m22z5ju5.cloudfront.net/js/evrythng/6.0.5/evrythng-6.0.5.js"></script>

Then use in a browser script tag using the evrythng global variable:

<script>
  evrythng.api({ url: '/time' }).then(console.log).catch(console.error);
</script>

Compatibility

evrythng.js relies on the standard resource fetching API (fetch) to communicate with the EVRYTHNG API. fetch has already been shipped in all the major browsers (see http://caniuse.com/#feat=fetch). The isomorphic-fetch dependency of this project should take care of this for you.

When using Node.js, version 10 and above is required.

Scopes

There are several types of Scopes and API Keys that are used to interact with the API. Each represents a type of user or resource in an EVRYTHNG account.

Note: Only the Application API Key can be safely versioned in public code! The other API key types are secret and secure API Keys with higher permission sets and should not be hard-coded - ideally encrypted in configuration files or fetched at runtime from a server.

In a nutshell, evrythng.js provides the following scopes. Once a scope is created it provides an appropriate API for the resources it can manage (see API below).

For apiVersion:2 these scopes are avaliable:

  • Operator
  • AccessToken- AccessToken is a Scope type for the v2 API with the potential to manage any account resources, depending on the API key's permissions. It represents an API access for a specific purpose, instead of a type of Actor, such as an Operator.

Operator and AccessToken scopes can have a different set of permissions, which is defined in an access policy and assigned during creation of operator access and access token.

const accessToken = new evrythng.AccessToken(ACCESS_TOKEN_API_KEY);

For apiVersion:1 these scopes are avaliable:

  • Operator - Highest level scope that can manage the account structure, all its resources and projects, etc.
const operator = new evrythng.Operator(OPERATOR_API_KEY);
  • Application - Public application scopes used for Identifier Recognition and to authenticate Application Users.
const application = new evrythng.Application(APPLICATION_API_KEY);
  • TrustedApplication - Secret type of Application scope with expended permissions, intended for use for scripting and backend integrations on behalf of the application (e.g. trigger rules or system integration functionality).
const trustedApplication = new evrythng.TrustedApplication(TRUSTED_APP_API_KEY);
  • User - Usually returned from authentication via an Application scope, but can also be created manually with an Application User API Key:
// Registered user with email + password
const credentials = { email: 'example@evrythng.com', password };
app.login(credentials).then((user) => console.log(user.apiKey));

// Or, an anonymous user
app
  .appUser()
  .create({ anonymous: true })
  .then((anonUser) => console.log(anonUser.apiKey));

// Or using a pre-existing API key
const userApiKey = localStorage.getItem('user_api_key');
const user = new evrythng.User(userApiKey);
  • ActionApp - Special version of the Application scope designed to make it as simple as possible to create instrumentation actions in web apps. It creates and remembers an anonymous Application User in LocalStorage and provides a simple interface for creating actions:
import { ActionApp } from 'evrythng';

const actionApp = new ActionApp(appApiKey);
await actionApp.init();

// Create a scan action on a Thng identified in the query
const thng = getQueryParam('thng');
const data = { thng, userAgent };
const action = await actionApp.createAction('scans', data);

// Log a page was visited (the current URL)
await actionApp.pageVisited();

// Retrieve the managed Application User
const anonymousUser = await actionApp.getAnonymousUser();

For any scope, if the scope's own data (such as an Application's customFields) is required immediately, use the init() method to wait until this data is available. If not, this step can be ignored:

import { Application } from 'evrythng';

const application = new Application(apiKey);
application.init().then(() => console.log(application.customFields));

API

The methods available for each of the above scope types matches the general access level defined for each type of API Key for apiVersion:2 or apiVersion:1. For example - the Application scope can read products in its project, but can only create Users who in turn have higher access to manage resources.

Methods

The API for each scope follows a fluent pattern that decreases the time required to begin making effective use of the SDK. In general, the format is:

SCOPE
  .RESOURCE(id)
  .METHOD(payload, params)
  .then(...)
  .catch(console.error)

Where:

  • SCOPE - One of the scope types shown above.
  • RESOURCE - can be any resource type, such as thng, product, collection etc. found in the API Reference.
    • id - specified if manipulating a specific resource of this type.
  • METHOD - one of create, read, update, delete, rescope, find, or upsert.
    • payload - JSON payload object if performing a create or update.
    • params - Parameters object used if required.

Therefore to read all Thngs as a TrustedApplication scope:

trustedApplication
  .thng()
  .read()
  .then((thngs) => console.log(`Read ${thngs.length} Thngs!`));

or to create a product as a User:

const payload = { name: 'Test Product', tags: ['evrythng.js'] };
user
  .product()
  .create(payload)
  .then((product) => console.log(`Created product ${product.id}!`));

or to read a known Thng using its id as an Operator:

const thngId = 'UqKWAsTpdxCA3KwaaGmTxAhp';

operator
  .thng(thngId)
  .read()
  .then((thng) => console.log(`Thng tags: ${thng.tags.join(', ')}`));

Promises

All methods return Promises, making chaining operations and catching errors very simple:

user
  .thng()
  .create(payload)
  .then((res) => console.log('Success!'))
  .catch((err) => console.log(`Oh no! Error: ${err.message}`));

Users of modern browsers and Node.js 8+ can take advantage async/await syntax as an alternative to Promise chaining when performing sequences of operations:

const testThngUpdate = async () => {
  // Read all Thngs and find one
  const thngs = await operator.thng().read();
  const testThng = thngs.find((p) => p.tags.includes('test'));

  // Update its tags
  const payload = { tags: ['updated'] };
  const updatedThng = await operator.thng(testThng.id).update(payload);

  // Check the update was successful
  expect(updatedThng.tags).to.equal(payload.tags);
};

Parameters

Each of the methods described above can accept parameters identical to those available when using the REST API, and are placed in the params object as shown below:

const params = {
  // Only with these tags
  filter: {
    tags: 'test',
  },
  // More items per page
  perPage: 100,
};

user
  .product()
  .read({ params })
  .then((products) => console.log(`Found ${products.length} 'test' products`));

Another example is creating resources in a specific project scope:

const params = { project: projectId };
const payload = { name: 'Test Thng' };

user
  .thng()
  .create(payload, { params })
  .then((thng) => console.log(`Created Thng ${thng.id} in project ${projectId}`));

Parameters can also be specified using chainable parameter setter methods:

user
  .product()
  .setFilter({ tags: 'test' })
  .setPerPage(100)
  .read()
  .then((products) => console.log(`Found ${products.length} 'test' products`));

Other parameter setters include setWithScopes(), setContext(), setPerPage(), setProject() and setFilter().

Plugins

This SDK can be extended with plugins that enhance existing functionality by modifying the capabilities of Scopes and Entities. This is done by supplying an object with at least an install() method, that is provided an api object (see src/use.js for details of this API).

For example, adding a getSummary() method to Thngs:

const SummaryPlugin = {
  // Required method
  install: (api) => {
    // Add new functionality to all Thng entities
    api.entities.Thng.prototype.getSummary = function () {
      return `${this.name} (${this.id})`;
    };
  },
};

The plugin is then installed using use():

const SummaryPlugin = require('summary-plugin');

evrythng.use(SummaryPlugin);

Then, the plugin's functionality can be used:

// Read one Thng
const [thng] = await user.thng().setPerPage(1).read();

// Use the newly installed method
console.log(thng.getSummary());
Test Thng (U6ssDxRBD8kQATawwGrEyaRm)

Documentation and Examples

For specific resource examples, see the relevant section of the API Reference, or look in the examples directory in this repository.

Build and Deploy

See ./jenkins/deploy.sh for instructions on deploying new versions.

changelog

v6.0.0 (08-12-2020)

Features

  • Setup: Add apiVersion:2 as default and add URL configuration based on apiVersion and region

  • Scopes: Add Operator and AccessToken scopes for apiVersion:2

  • Access Policies: Add accessPolicies() for access policies API to Operator and AccessToken scopes for apiVersion:2

  • Operator Accesses: Add operatorAccess() for operator accesses API to Operator and AccessToken scopes for apiVersion:2

  • Me: Add me() for me API to Operator and AccessToken scopes for apiVersion:2

  • Access Tokens: Add accessToken() for access tokens API to Operator and AccessToken scopes for apiVersion:2

v5.9.0 (1-7-2020)

Features

  • Files: Add files() resources to User scope for creating and reading by file ID.

v5.8.0 (3-2-2020)

Features

  • ActionApp: Allow createAction() to target a thng or product by including an ID in the data parameter.

  • ActionApp: All getAnonymousUser() to allow usage of the managed anonymous Application User.

Fixes

  • ActionApp: Fix bug preventing use of built-in action types.

v5.7.1 (14-1-2020)

Features

  • Pagination: Add streamPages() to all resources to allow asynchronously streaming pages of resources.

v5.6.0 (27-9-2019)

Features

  • Purchase Orders: Add purchaseOrder() for purchase orders API to Operator scope.

  • Shipment Notices: Add shipmentNotice() and shipmentNotice().container() for shipment notices API to Operator scope.

Fixes

  • Scopes: Prevent scopes from reading access twice when using init().

v5.5.0 (29-8-2019)

Features

  • ADI Orders: Added adiOrder() resources to Operator scope for creating and reading ADI Orders. Also includes event() for creating ADI Order events.

v5.4.0 (7-8-2019)

Changes

  • redirections:redirection() resource now allows nominating the shortDomain in that call, and no longer requires some templating ({shortId}/{productId}) as part of the URL submitted.
  • redirections: settings now includes defaultShortDomain to allow setting the default short domain used for redirection() requests.

Fixes

  • api: Better handle parts of the API that return non-standard empty response bodies.

v5.3.0 (29-7-2019)

Features

  • entities: Export Entity through the plugin api.
  • files: Add upload() method for files to upload file data.
  • upsert: upsert() can now be performed by name in addition to an identifier object where a resource supports filtering by name.

Fixes

  • param setters: Add missing setIds() param setter.
  • permissions: Support referring to permission by name, such as permission('global_read')

v5.1.0 (30-5-2019)

Features

  • plugins: Added the use() method in order to support plugins. See src/use.js for API details.

v5.0.0 (23-5-2019)

Breaking Changes

If you are updating from a previous version, please see the Migration Guide.

  • evrythng-extended.js: evrythng-extended.js is no longer required as a separate dependency.
  • Browser global: The EVT browser global is now evrythng.
  • Scope names: The App and TrustedApp scopes are now Application and TrustedApplication.
  • User scope: Manual creation of a User scope using a pre-existing API key now only requires the key as a parameter.
  • $init: The $init promise property has been formalised as the init() method, and behaves the same way.
  • Request options: The authorization parameter for api() is now apiKey.
  • Iterators: The EVT.Utils.forEachAsync() and iterator() resource method is now pages(), and is an async generator.

Features

  • Redirections: The thng() and product() resources now have a redirection() resource for managing redirections.
  • Accounts: Added a sharedAccount() resource with access() sub-resource for reading and updating accounts.
  • Domains: The sharedAccount() resource also includes shortDomain() and domain() resources for reading available short domains and domains.
  • Secret key: The application() resource now has a secretKey() resource for reading its Trusted Application API Key as an Operator.
  • Redirector: The Operator scope and application() resource now have a redirector() resource for reading and updating Redirector rules.
  • Resource aliases: The alias() method allows simple aliasing of existing resource types to better suit a use-case or environment, such as naming collections 'pallets'.
  • Parameter setters: Instead of creating a params object, chainable setters such as setPerPage() are available on most resources to easily build complex requests.
  • Resource methods: The rescope(), upsert(), and find() methods have been added to most resources to allow easier changing of project/user scopes, updating by key else creating, and finding by identifiers as common operations.

v4.7.2 (11-15-2017)

Bug fixes

-Places: Do not geolocate place with id

v4.7.1 (30-06-2017)

Features

-Policies: Allow single Policy access.

v4.7.0 (29-06-2017)

Features

-Policies: Add Policy resource to Roles.

v4.6.0 (09-06-2017)

Features

-Schemas: Add Schema resource in Operator scope.

v4.5.1 (30-05-2017)

Bug fixes

-Permissions: Add support for old Permission API.

v4.5.0 (25-04-2017)

Features

-Permissions: Add Permission resource to Roles.

v4.4.1 (25-04-2017)

Bug fixes

  • HTTP: Fix incorrect Content-Type header check in Node.

v4.4.0 (03-04-2017)

Features

-Roles: Add Role resource in Operator and User scope.

v4.3.0 (30-01-2017)

Features

  • Files: CRD access in the Operator scope.

v4.2.0 (10-01-2017)

Features

  • Scopes: Read data from any scope on creation via $init.

v4.1.0 (12-10-2016)

Features

  • Reactor scripts: Add nested reactor script status resource app.reactor.script().status().

v4.0.1 (11-10-2016)

Bug fixes

  • Auth: Allow to pass FB initialization settings
  • Auth: Read user details when login in application

v4.0.0 (04-10-2016)

Breaking changes

  • Reactor logs: Move app.reactorLog() resource within the app.reactor.log() namespace (only available in evrythng-extended.js).
  • Search: Global .search() has been removed to match API. Use filters instead.
  • Multimedia: Multimedia resource has been removed to match API.

Features

  • Reactor schedules: Add Reactor schedules resource in the app.reactor.schedule() namespace (only available in evrythng-extended.js).
  • Reactor scripts: Add Reactor scripts resource in the app.reactor.script() namespace (only available in evrythng-extended.js).

v3.7.0 (16-06-2016)

Features

  • Collections: Add nested collection resource operator.collection('id').collection().

v3.6.1 (09-06-2016)

Bug fixes

  • Iterator API: Use sortOrder=DESCENDING param by default.
  • Application: Reject application.$init promise if app does not exist.
  • AJAX Headers: Fix response headers not being handled correctly.

v3.6.0 (02-06-2016)

Features

  • Batches: CRUD access in the Operator scope.
  • Batch tasks: CR access in the Batch resource.

v3.5.0 (12-05-2016)

Features

  • Iterator API: Async generator iterator() added to every Resource, supporting looping through the new pagination links.
  • Utils: Added forEachAsync() utility to loop through async generator values.
  • Utils: Added spawn() utility to run through generator function.

Breaking changes

  • Count: count() method on the Resource has been removed.

Bug fixes

  • AJAX Headers: Header values were being lowercased.

v3.4.4 (26-04-2016)

Bug fixes

  • Request interceptors: Added Promise support for request interceptors.

v3.4.3 (26-01-2016)

Changes

  • Callback API: Make deprecation warning mutable.

v3.4.2 (22-12-2015)

Changes

  • Errors: Added code and moreInfo and removed message and type to/from EVT.js errors.
  • Callback API: Added deprecation when callbacks are executed.

v3.4.1 (14-12-2015)

Changes

  • Transport: Common transport module for Node.js and Browser.

v3.4.0 (02-12-2015)

Features

  • Projects: CRUD access in the Operator scope.
  • Applications: CRUD access in the Project resource.
  • Reactor Logs: RD access in the Operator scope.
  • Actions: allow to override global Geolocation setting per request.

v3.3.2 (27-10-2015)

Bug fixes

  • Resource path: newly created entities have wrong resource path [#37].

v3.3.1 (09-09-2015)

Bug fixes

  • Properties: normalize arguments with falsy values (e.g. 0, false) on property creation or update.

v3.3.0 (07-09-2015)

Features

  • Trusted App: updated permissions for TrustedApp scope.
  • Custom headers: allow to setup custom headers with headers object option.
  • Action Types: CRUD access like other entities.
  • Filters: escape special characters for filter param when using object notation.

Bug fixes

  • Properties: normalize arguments on creation, just like updates. Read properties with special characters.
  • Empty fields: empty fields not being sent to API request.
  • Encoding: nested params objects (e.g. filters) are only encoded once.

v3.2.0 (10-08-2015)

Features

  • Trusted App: scope to use with you Application Secret Key, mainly used in Reactor scripts (only available in evrythng-extended.js).

Breaking changes

  • plugins: EVT.use() to install plugin is now synchronous. Callback has been removed. Required dependencies now use $inject property instead of requires.

v3.1.2 (25-06-2015)

Features

  • documentation: clearer usage and installation steps. Consistent format from other libs.

v3.1.1 (19-06-2015)

Bug fixes

  • package.json: Github url with git:// protocol.

v3.1.0 (17-06-2015)

Bug fixes

  • xhr: responses without headers were being ignored.

Features

  • interceptors: setup request and response interceptors globally or as a one-off request settings.
  • plugins: ability to install/use plugins for additional functionality.

Breaking changes

  • synchronous requests: sync option removed for Node.js vs Browser consistency and to promote best practices.