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

osdi-client

v1.0.2

Published

Superagent based client library for interacting with any OSDI compliant server

Downloads

252

Readme

OSDI Client

Library for interacting with any OSDI compliant server (http://opensupporter.github.io/osdi-docs/).

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.

Usage

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

npm install --save osdi-client
const osdi = require('osdi-client')
osdiClient.client('https://sample-system.com/api/aep')
  .then(client => {
    // ready to use client
  })
  .catch(err => {
  })

Relies on superagent (https://github.com/visionmedia/superagent) for most of the heavy lifting, so get familiar with their API first.

osdi.client

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...

osdi.client('https://my-osdi-endpoint.com')
.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.

osdi.client({
  "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 */)

client.get

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

client.getPeople()
.end((err, res) => {
  if (err) {
    // handle error
  }

  // do something with res
})

or with .then and .catch as in

client.getPeople()
.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.

client.getPeople()
.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(party.name()) // 'Pizza Party'
party.name('Pizza\'s Birthday Party')
console.log(party.name()) // 'Pizza's Birthday Party'

party.save()
.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:

client.getPeople()
.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
    person.givenName('Greg')
    person.save()
    .end((err, result) => {
      // the guy's named Greg now
    })
  })
})

To make everyone in the database named Greg, simply

function nameGreg (response) {
  Promise.all(
    response.people.map(person => new Promise((resolve, reject) => {
      person.givenName('Greg')
      return person.save() // 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
      response.nextPage()
      .then(nameGreg)
    }
  })
}

Manually Editing a Resource

All of a resources data live at person.data or event.data 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 resource.save(). To make sure it gets included, use resource.markModified('field').

// BAD!!!!
person.data.givenName = 'Thomas'
person.save().then(/* stuff */)

// OK!!!
person.data.givenName = 'Thomas'
person.markModified('givenName')
person.save().then(/* stuff */)

// PREFERRED!!!
person.givenName('Thomas')
person.save().then(/* stuff */)

Tests

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