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

litmos-sdk

v2.0.1

Published

Node.js SDK for the Litmos Learning Management System

Downloads

307

Readme

Litmos SDK

Node.js SDK for the Litmos Learning Management System

Litmos' API documentation can be found here: https://support.litmos.com/hc/en-us/articles/227734667-Overview-Developer-API

Additional articles can be found here: https://support.litmos.com/hc/en-us/sections/206185047-Developer-API

Disclaimer

This package is not maintained by or associated with "SAP Litmos" and is provided as-is

Usage

This SDK is meant to reflect the actual REST API as closely as possible so that the Litmos API docs themselves can provide guidance on how to use this SDK

First, import and create an instance of the Litmos class with required and optional settings. See litmos-opts.js for a full list of possible options

const Litmos = require('litmos-sdk');
const env = require('./.env.json');

const litmosOpts = {
  apiKey: env.LITMOS_API_KEY,
  source: env.LITMOS_SOURCE
};
const litmos = new Litmos(litmosOpts);

Once instantiated, method / object chaining is used to access the desired endpoint. This method chain should match the form of the API Endpoint as follows:

GET users/
// Becomes...
litmos.api.users.get()

GET users/{user-id}
// Becomes...
litmos.api.users.id({user-id}).get()

POST users/{user-id}/learningpaths
// Becomes...
litmos.api.users.id({user-id}).learningpaths.post({Learning path data})

All method chains must end with a request method. Valid methods are:

get()     // Performs a GET request on the preceding endpoint
delete()  // Performs a DELETE request on the preceding endpoint
post()    // Performs a POST request on the preceding endpoint. Takes a body to post
put()     // Performs a PUT request on the preceding endpoint. Takes a body to put

URL query parameters can also be supplied to all request methods. These parameters should be defined as key-value pairs in a supplied object, as such:

const params = {
  since: '2019-05-14',
  limit: 20
}
litmos.api.results.modules.get(params);

Async

All request methods are asynchronous - they will return a Promise that is resolved with processed response data from Litmos, or reject with an error. The await keyword should be used when processing data:

// All of these requests will happen one after the other
// Wait for the GET request to succeed before saving the response and continuing
const allUsers = await litmos.api.users.get();

// Wait for the GET request
const allLearningPaths = await litmos.api.learningpaths.get();

// Wait for the POST request
const postRes = await litmos.api.users.id('user-id').learningpaths.post({Id: 'lp-id'});

Pagination

Litmos will only provide a maximum of 1000 elements from any request, to get more elements pagination must be used. The system will automatically determine if pagination is required, and keep paging through responses until all elements are received. This functionality can be disabled by provided a "limit" parameter to the request

// There are 4231 users
const allUsers = await litmos.api.users.get();
console.log(allUsers.length); // Outputs "4231"

const tenUsers = await litmos.api.users.get({limit: 10});
console.log(tenUsers.length); // Outputs "10"

POST / PUT Requests

When performing a POST or PUT request, the provided data should be a JavaScript object, these object will automatically be wrapped in the required endpoint identifiers before being sent to the appropriate endpoint. For example:

According to the Litmos documentation, the following xml would be used to assign a learning path to a user:

<LearningPaths>
  <LearningPath>
    <Id>[LearningPathId1]</Id>
  </LearningPath>
  <LearningPath>
    <Id>[LearningPathId2]</Id>
  </LearningPath>
</LearningPaths>

This XML is equivalent to this JSON:

{
  "LearningPaths": [
    {
      "LearningPath": {
        "Id": "LearningPathId1"
      }
    },
    {
      "LearningPath": {
        "Id": "LearningPathId2"
      }
    }
  ]
}

However, when using the SDK to update a learning path, the system already knows what should wrap the data, so the following form would be used:

const newLps = [
  { Id: 'LearningPathId1' },
  { Id: 'LearningPathId2' }
];
await litmos.api.users.id('user-id').learningpaths.push(newLps);

Helpers

Some operations are especially complicated - in these cases helpers are available that simplify things

Creating New Users

The requirements for creating new users (litmos.users.post(data)) are very precise, and a single misconfigured element can result in a server error. For this reason the litmos.helpers.generateUser() method exists to assist with generation of correctly formatted user data. Ex:

const userOpts = {
  UserName: '[email protected]',
  FirstName: 'First',
  LastName: 'Last',
  DisableMessages: true
};
const newUser = litmos.helpers.generateUserObject(userOpts);
const response = await litmos.api.users.post(newUser);

Development Principles

The following principles should be followed when developing this sdk:

  • Be aware of dependency usage, and use as few dependencies as possible
  • Should mimic the Litmos API closely, while still following js best practices and standards
  • Asynchronous operations should be implemented using Native Promises
  • All traffic must be transmitted over https
  • Should use the XML endpoints, and support automatic conversion of js objects to xml
    • The Litmos API only consistently works with XML, JSON support is spotty at best
  • Should be fully documented with JSDocs to support intellisense

Notes on Litmos API Oddities

The Litmos API is not the most consistent API in the world. Documentation is spotty and implementation is inconsistent. Here are some pointers that should help when navigating the API

Two Different ID Systems

Almost every object in Litmos has two different ids associated with it, the originalId which is used for all frontend operations, and the backend id which is used for all backend API operations. The only way to match originalId values to id values is to get a complete list of objects, and check each one for the originalId. This must be carefully watched for

XML vs JSON

The Litmos API documentation claims that both XML and JSON is supported for data transfer. However, this is not the case for all litmos endpoints. Some of the older endpoints do not actually support the JSON data format. As such, only the XML endpoints should ever actually be used when making requests

Object Key Order

When sending requests via XML, the order of object in the XML document does matter in some cases. This should be kept in mind if encountering bugs despite the presence of all required fields

More results than expected

According to the API documentation, the maximum number of results that can be returned in a single request is 1000. However, sometimes the API will actually return slightly more than 1000 results, which can lead to problems if unexpected