npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

waterwheel

v1.3.7

Published

A generic JavaScript helper library to query and manipulate Drupal 8 via core REST

Downloads

19

Readme

Waterwheel - Drupal SDK

Waterwheel

A generic JavaScript helper library to query and manipulate Drupal 8 via core REST

Build Status Coverage Status


Setup

Install development dependencies.

npm i

Run tests and check coverage.

npm t

Build a browser version.

npm run build

Dependencies

Ensure that you have set up cross-origin resource sharing on your Drupal site to enable Waterwheel to perform necessary tasks. Instructions for Apache or Nginx.

Some functionality in Waterwheel.js is dependent on the OpenAPI module. Please install and enable this module in your Drupal site before attempting to use the functionality offered in this library.

Documentation

Using waterwheel in either a server or browser environment.

Server

const Waterwheel = require('waterwheel');
const waterwheel = new Waterwheel({
  base: 'http://drupal.localhost',
  oauth: {
    grant_type: 'GRANT-TYPE',
    client_id: 'CLIENT-ID',
    client_secret: 'CLIENT-SECRET',
    username: 'USERNAME',
    password: 'PASSWORD'
  }
});

Browser

// Include the 'release' version of Waterwheel prior to creating a new instance.
// <script type="text/javascript" src="waterwheel.js"></script>

const waterwheel = new window.Waterwheel({
  base: 'http://drupal.localhost',
  oauth: {
    grant_type: 'GRANT-TYPE',
    client_id: 'CLIENT-ID',
    client_secret: 'CLIENT-SECRET',
    username: 'USERNAME',
    password: 'PASSWORD'
  }
});

// With resources
const resources = require('./resources.json');
const waterwheel = new Waterwheel({
  base: 'http://drupal.localhost',
  resources: resources,
  oauth: {
    grant_type: 'GRANT-TYPE',
    client_id: 'CLIENT-ID',
    client_secret: 'CLIENT-SECRET',
    username: 'USERNAME',
    password: 'PASSWORD'
  }
});

Waterwheel when instantiated accepts a single object,

  • base: The base path for your Drupal instance. All request paths will be built from this base.
  • resources: A JSON object that represents the resources available to waterwheel.
  • oauth: An object containing information required for fetching and refreshing OAuth Bearer tokens. The Simple OAuth module is recommended for this.
    • grant_type: The type of OAuth 2 grant. Currently password is the only supported value.
    • client_id: The ID of your client.
    • client_secret: The secret of your client.
    • username: The user's username.
    • password: The user's password.
  • timeout: How long an HTTP request should idle for before being canceled.
  • accessCheck: indicates whether authentication should be used. Possible values are true and false.
  • jsonapiPrefix: If you have overridden the JSON API prefix, specify it here and Waterwheel will use this over the default of jsonapi.
  • validation: A boolean that defaults to true. If set to false, every request will ignore any existing OAuth information, allowing you to make requests without any authentication. If you have an open API, than the OAuth module is not needed.

Supplying the resources object is equivalent to calling .populateResources() but does not incur an HTTP request, and alleviates the need to call .populateResources() prior to making any requests. You can fetch this object by calling waterwheel.fetchResources().

Populate waterwheel resources

If you are supplying a resources object when waterwheel is instantiated, you do not need to use .populateResources() to fetch the resources prior to making any subsequent API calls. Waterwheel will fetch your Swagger (OpenAPI) document and attempt to automatically parse and create resources for you. Waterwheel.js currently expects the OpenAPI module to be installed and enabled, however, the intent is to remove that dependency, by adding the necessary functionality to Drupal core, making that separate module ​_obsolete_​.

waterwheel.populateResources('http://test.dev/swagger.json')
  .then(() => {
    // ...
  });

.populateResources() accepts one argument

  • resourcesLocation: The full path to your Swagger (OpenAPI) documentation.

Get resources within waterwheel

waterwheel.getAvailableResources()
  .then(res => {
    /*
    [
      'node:article',
      'node:page',
      'user'
    ]
    */
  });

Entities that have no bundles are accessible at the top level, waterwheel.api.comment, however bundles are accessible from within their entity, waterwheel.api.node.article.

Methods for resources

Each method is directly mapped to the methods key attached to the resource.

GET

waterwheel.api['user'].get(1)
  .then(res => {
    // Drupal JSON Object
  })
  .catch(err => {
    // err
  });

.get() accepts two arguments

  • identifier: The identifier of the entity you are requesting, nid, vid, uid, etc.
  • format: The format of response you are requesting. Currently this is optional, and internally defaults to JSON.

PATCH

waterwheel.api['user'].patch(1, {})
  .then(res => {
    // res
  })
  .catch(err => {
    // err
  });

.patch() accepts three arguments

  • identifier: The identifier for the entity you are attempting to modify, nid, vid, uid, etc.
  • body: An object that is formatted in a way that Drupal will be able to parse. This object is passed directly to Drupal.
  • format: The format of the object you are passing. Currently this is optional, and internally defaults to JSON.

POST

waterwheel.api['user'].post({})
  .then(res => {
    // res
  })
  .catch(err => {
    // err
  });

.post() accepts two arguments

  • body: An object that formatted in a way that Drupal will be able to parse. This object should contain all the information needed to create an entity. This object is passed directly to Drupal.
  • format: The format of the object you are passing. Currently this is optional, and internally defaults to application/json.

DELETE

waterwheel.api['user'].delete(1)
  .then(res => {
    // res
  })
  .catch(err => {
    // err
  });

.delete() accepts one argument

  • identifier: The identifier for the entity you are attempting to delete, nid, vid, uid, etc.

Set field values

waterwheel.api['node:page'].setFields(201, {
  title: {
    value: 'Hello World'
  },
  body: {
    value: 'ok, a new body',
    summary: 'ok, a new summary'
  }
})
  .then(res => {
    // Data sent to Drupal
  })
  .catch(err => {
    // err
  });

.setField() accepts 3 arguments

  • identifier: The id of the entity you are setting field values on
  • fields: Fields and values to be set on the entity. These should match the fields for the bundle.

Get field metadata for an entity/bundle

waterwheel.populateResources()
  .then(() => waterwheel.api['node:page'].getFieldData())
  .then(res => {
    // Field metadata
  })
  .catch(err => {
    // err
  });

.getFieldData() accepts no arguments. This returns the object from Waterwheel-Drupal that contains information about each field in the entity/bundle. For a list of fields, to be used in .setField(), something like Object.keys(res.fields) will work.

Get Embedded Resources

waterwheel.api['node:page'].get(1, 'hal_json')
  .then(res => waterwheel.fetchEmbedded(res))
  .then(res => {
    // res
  })
  .catch(err => {
    // err
  });

waterwheel.api['node:page'].get(1, 'hal_json')
  .then(res => waterwheel.fetchEmbedded(res, ['my_field']))
  .then(res => {
    // res
  })
  .catch(err => {
    // err
  });

.fetchEmbedded() accepts 2 arguments

  • entityJSON: This should be a HAL+JSON structured object containing an _embedded key at the root.
  • includedFields: Optionally provide a single field as a string, or an array of strings to filter the embedded request by.

When requesting embedded resources duplicates are removed to prevent extra HTTP requests. An array is returned with your original response and any embedded resources. If any of the subsequent requests fail, the promise is rejected.

JSON API

waterwheel contains provisional support for requesting data using the json:api format. Currently only GET, POST and DELETE requests are supported.

const Waterwheel = require('waterwheel');
const waterwheel = new Waterwheel('http://foo.dev', null, {});

The jsonapi.get() method accepts 3 arguments,

  • resource: The bundle and the entity you want to request.
  • params: Any arguments that your request requires. These are translated to query string arguments prior to sending the request.
  • id: The UUID of a single entity to fetch. This can be overloaded to include the name of a related entity.

The jsonapi.post() method accepts 2 arguments,

  • resource: The bundle and the entity you want to create.
  • body: The data to be sent to Drupal. Review the JSON API documentation for specifics on payload structure for posting an individual entity.

The following examples outline some of the basic features of using JSON API.

Collections/Lists

waterwheel.jsonapi.get('node/article', {})
.then(res => {
  // res
});

Request A Resource

waterwheel.jsonapi.get('node/article', {}, 'cc1b95c7-1758-4833-89f2-7053ae8e7906')
.then(res => {
  // res
});

Request A Related Resource

waterwheel.jsonapi.get('node/article', {}, 'cc1b95c7-1758-4833-89f2-7053ae8e7906/uid')
.then(res => {
  // res
});

Basic Filter

waterwheel.jsonapi.get('node/article', {
  filter: {
    uuid: {
      value: '563196f5-4432-4964-9aeb-e4d326cb1330'
    }
  }
})
.then(res => {
  // res
});

Filter With Operators

waterwheel.jsonapi.get('node/article', {filter: {
  myFilter: {
    condition: {
      value: '8',
      field: 'nid',
      operator: '<'
    }
  }
}})
.then(res => {
  // res
});

Post

const postData = {
  'data': {
    'type':'node--article',
    'attributes': {
      'langcode': 'en',
      'title': 'api created page',
      'status': '1',
      'promote': '0',
      'sticky': '0',
      'default_langcode': '1',
      'path': null,
      'body': {
        'value': 'page created from the api.'
      }
    }
  }
};

waterwheel.jsonapi.post('node/article', postData)
  .then(res => {
    // Created page.
  });

Delete

waterwheel.jsonapi.delete('node/article', 'cc1b95c7-1758-4833-89f2-7053ae8e7906')
  .then(() => {
    // Delete successful
  });