Nitrogen Pumpkin Mulch


    1.0.2 • Public • Published

    OSDI Client

    Library for interacting with any OSDI compliant server (

    Will parse the app entry point and returned metadata on subsequent api calls and create convenience methods for you.

    Note: I haven't finished populating the Resource classes with the correct property fields.


    Works in the browser and in node. Browersify / webpack friendly.

    npm install --save osdi-client
    const osdi = require('osdi-client')
      .then(client => {
        // ready to use client
      .catch(err => {

    Relies on superagent ( for most of the heavy lifting, so get familiar with their API first.


    The initialization method returns a promise, which is resolved with an client object or reject with whatever error.

    osdi.client accepts an the API's app entry point...

    .then(client => {
      // do stuff with the client here
    .catch(err => {
      // either the aep was formatted invalidly or there was a network error probably

    or you can give it the JSON data that lives at the app entry point directly, and save a network request.

      "motd": "Welcome to the OSDI API Entry Point!",
      "vendor_name" : "Foobar Incorporated",
      "product_name" : "Curly Braces OSDI Server",
      "osdi_version" : "1.0",
      "max_pagesize": 25,
      "namespace": "osdi_sample_system",
      // and on and on...
    .then(/* yada */)


    The client object generated by osdi.client will have all of the exposed resources created as get methods.

    So, for example, if the AEP (app entry point) has osdi:people and osdi:events, client will have client.getPeople() and client.getEvents().

    These methods will return a superagent request, which can be called with .end as in

    .end((err, res) => {
      if (err) {
        // handle error
      // do something with res

    or with .then and .catch as in

    .then(res => {
      // do something with res
    .catch(err => {
      // handle error

    And since superagent supporters promises, you can do

    async myFunc () {
      const people = await client.getPeople()
      // do something with people

    Since the get<Resource> methods return a superagent request, you can manually add headers with .set, modify query parameters, etc.

    .set('OSDI-API-TOKEN', secretToken)
    .end((err, res) => {
      // yadada

    Helper methods for queries and authentication are planned but not implemented yet.

    Resource Objects

    For whatever resources the app entry point exposes, a resource class will be available from client.resources. These classes have .save, .delete, and getter / setters for any attribute in the OSDI docs. .save and .delete also expose superagent requests.

    *** Note *** --- I have chosen to make all properties camel case, so family_name becomes familyName. This is all done behind the scenes. I did it because most Javascript uses camelCase, but if you think it's a bad decision (leads to unnecessary confusion) let me know.

    So for example, to create a new event...

    const party = new client.resources.Event({
      name: 'Pizza Party',
      title: 'Happy Birthday',
      description: 'Celebrating Pizza\'s Birthday'
    console.log( // 'Pizza Party''Pizza\'s Birthday Party')
    console.log( // 'Pizza's Birthday Party'

    .set('OSDI-API-TOKEN', secretToken)
    .end((err, res) => {
      // now the server knows about the party

    Parsing Responses with client.parse

    Calling client.parse on the response will serialize its metadata into function calls and wrap its embedded response data inside Resource classes. For example:

    .then(raw => {
      const res = client.parse(raw)
      // Now res has the following methods, if appropriate
      // each returns a superagent request
      res.nextPage().then(/* stuff */)
      res.prevPage().then(/* stuff */)
      // Whatever resource was requested is not available as a property
      res.people.forEach(person => {
        // and each of these are Person object's, with `.save`, `.delete`, and getter / setters
        .end((err, result) => {
          // the guy's named Greg now

    To make everyone in the database named Greg, simply

    function nameGreg (response) {
      Promise.all( => new Promise((resolve, reject) => {
          return // save returns a superagent object which is promise compatible
      ).then(gregs => {
        if (response.nextPage) { // nextPage will be a function if another page exists, undefined otherwise

    Manually Editing a Resource

    All of a resources data live at or or whatever. However, if you manually modify .data and then call .save, the Resource will not know the given field has been modified, and so it will not include it in the body of the request generated by To make sure it gets included, use resource.markModified('field').

    // BAD!!!! = 'Thomas'* stuff */)
    // OK!!! = 'Thomas'
    person.markModified('givenName')* stuff */)
    // PREFERRED!!!
    person.givenName('Thomas')* stuff */)


    Written with Mocha, Chai, and node-nock. npm test does the trick.


    npm i osdi-client

    DownloadsWeekly Downloads






    Unpacked Size

    39.6 kB

    Total Files


    Last publish


    • ben-pr-p