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

sharezone

v0.2.0

Published

Sharepoint library with support for multiple authentication strategies

Downloads

5

Readme

Build Status

A Node.js SharePoint Client.

Usage Example

var sharepoint = require('sharepoint')({
  username : 'someusername',
  password : 'somepassword',
  // Authentication type - current valid values: ntlm, basic, online,onlinesaml
  type : 'ntlm',
  url : 'https://someSharepointHostname.com'
});
sharepoint.login(function(err) {
  if (err) {
    return console.error(err);
  }
  // Once logged in, we can list the "lists" within sharepoint
  sharepoint.lists.list(function(err, listRes) {
    var aList = listRes[0];
    // We can pick a particular list, and read it. This also gives us the list's Items[] and Fields[]
    sharepoint.lists.read(aList.Id, function(err, listRead) {
      console.log(singleResult);
    });
  });
});

Parameters

When initialising Sharepoint, there are a number of optional params which can be specified at init. Here are their defaults & descriptions

var sharepoint = require('sharepoint')({
  username : 'someusername',
  password : 'somepassword',
  // Authentication type - current valid values: ntlm, basic, online, onlinesaml
  type : 'ntlm',
  url : 'https://someSharepointHostname.com',
  // All of the following params are optional:
  context : 'myCustomerSite', // Set to create resources outside of the base site context, `web`
  verbose : false, // Set to true to stop filtering responses, instead returning everything
  proxy : undefined, // set to string hostname of proxy if running through one
  strictSSL : true, // set to false if connecting to SP instance with self-signed cert
  federatedAuthUrl : 'http://mysamlloginservice.com', // only set for auth type 'onlinesaml', the URL of the SAML service which issues assertions to forward to the SharePoint login URL
  rtFa: <token>,// an optional parameter to set rtFa token value - used if you've previously authenticated and stored the tokens (captured from the rtFA property after logging in)
  FedAuth:<token>, // an optional parameter to set FedAuth token value - used if you've previously authenticated and stored the tokens (captured from the FedAuth property after logging in)
  fieldValuesAsText : true, //Return Lookup Field Values as Text for Items
  filterFields : ["{\"field\": \"field1\", \"value\": \"value1\"}"], //Filter Items in List based on field value(s) $filter=
  selectFields : ['field1', 'field2'], //Only return List or Item data for fields specified $select=
  expandFields : ['field1', 'field2'] //"JOIN" another list based on a lookup value and return data $expand=
});

A Sharepoint Primer

Skip this if you already know enough about SharePoint.
Here's the basics I wanted to know about this product before I began integrating:

  • Sharepoint is a number of products:

    • SharePoint 2013 - the on premise version of Sharepoint which I've seen most often.
    • Sharepoint 365 - the online SharePoint product.
  • Everything is a List in SharePoint. Document Library? A list. The tasks app? Just a list. Discussion Board? You got it, it's a list. Site Pages? List. Turns out, Sharepoint reuses the base type List for a lot of things.

Methods

Lists

As mentioned above, SharePoint is driven by lists. The base SharePoint API allows you to CRUDL lists, but the read operation doesn't return Items[] or Fields[] - this is a separate API operation.

With da sharezone, list read operations also retrieve all Fields[] and Items[] on the list for convenience.

Lists List

Confusing, I know. Bear with me. Lists all objects of type list in sharepoints (and remember, almost everything in Sharepoint is a list!).

sharepoint.lists.list(function(err, listRes) {
  // listRes will be an array of lists [{Id : '1a2b3c', ...}, {Id : '2b3c4d'}, {Id : '5d6e7f'}]
});

You can now use any of the following functions to operate upon lists. Note that each lists object in the array will also have a convenience function which operates on itself for read, update & delete. These are also documented below.

Lists Create

Creating a result requires a title and a description.

sharepoint.lists.create({title : 'My new list', description : 'Some list description'}, function(err, createRes) {
  // createRes will be the newly created list as an object {Id : 'someListGUID', title : 'My new list', ...}
});

Lists Read

List Read can take a string as the first param (assumes list Id), or a params object specifying either a guid or title.

The list operation already tells us quite a bit about that list, but this read call also returns Fields[] and Items[]. This is different to how the SharePoint API behaves, and is offered as a convenience.

// Get a list by ID - you can find this under the 'Id' property.
sharepoint.lists.read('someListGUID', function(err, listReadResult) {
  // listReadResult will be an object {Id : 'someListGUID', Title : 'SomeListTitle', Items : [{}, {}], Fields : [{}, {}]  ...}
});

// Get a list by name
sharepoint.lists.read({title : 'some list name'}, function(err, listReadResult) {
  // listReadResult will be an object {Id : 'someListGUID', Title : 'some list name', ...}
});

// You can also call a read() operation from an object returned from the list operation for convenience like this
sharepoint.lists.list(function(err, listRes) {
  var aList = listRes[0];
  aList.read(function(err, aListReadResult) {
    //
  });
});

Lists Update

Updating requires an ID and a title. Optionally, you can just specify all this in one object.

// Update specifying the Id separately
return sharepoint.lists.update('someListGuid', {Title : 'MyNewTitle'}, function(err, updateResult) {
  // updateResult will be the object you passed in, but not the full list. To get the fully updated object, a subsequent read is needed.
});

// Updating specifying the Id in one param
return sharepoint.lists.update({Id : 'someListGuid', Title : 'MyNewTitle'}, function(err, updateResult) {
});

// You can also call a update() operation from an object returned from the list operation for convenience like this
sharepoint.lists.list(function(err, listRes) {
  var aList = listRes[0];
  aList.update({Title : ''}, function(err) {
    //
  });
});

Lists Delete

Delete requires a list Id. Deletion by title is not possible.

sharepoint.lists.del('someListId', function(err) {
  // Err will indicate if somethign went wrong - there's no second param
});

// You can also call a delete() operation from an object returned from the list
// operation for convenience like this
sharepoint.lists.list(function(err, listRes) {
  var aList = listRes[0];
  aList.update({Title : ''}, function(err) {
    //
  });
});

List Items

Lists in sharepoint have a collection of items. These are usually another API call away, but as discussed earlier, sharezone retrieves these upon performing a read() call.

ListItems List

To retrieve the items contained within a list,

sharepoint.listItems.list('someListGUID', function(err, itemsUnderThisList) {
  //
});

Of course, we can also just perform a list read:

sharepoint.listItems.read('someListGUID', function(err, listReadResult) {
  // we now have the items under listReadResult.Items
});

ListItem Create

We can create new ListItems within a list using the create function. The responsibility is on the user to ensure all required fields are included prior to creating a listItem, and no extraneous fields are included. SharePoint throws meaningful & useful errors (..for once) if you include incorrect fields here, so it's easy to debug.

sharepoint.listItems.create('someListGUID', {
  Title : 'My new list item',
  Remember: 'To include all fields'
}, function(err, listCreateResult) {
  //
});

We can also just call .create() on the Items property of a list which we've read.

sharepoint.lists.read('someListGUID', function(err, listReadResult) {
  // Now that we've read a list, we can create an item under it by running:
  listReadResult.Items.create({Title : 'My new item'}, function() {
    //
  });
  // We could also use listReadResult.createItem() to the same effect
});

ListItem Read

As part of reading a ListItem, we also retrieve it's File property, if any exists. This is helpful, because many lists include a file attachment (e.g. Document Libraries). If no file exists, this will simply be undefined.

sharepoint.listItems.read('someListGUID', 'someListItemId', function(err, singleListItem) {

});

Of course, we can also just call .read() on a listItem, after we read its containing list.

sharepoint.lists.read('someListGUID', function(err, listReadResult) {
  var anItemInThisList = listReadResult.Items[0];
  anItemInThisList.read(function(err, listItem) {
    //
  });
});

ListItem Update

To update a ListItem, we use the update() function.

var listItemData {
  // Value of the item's ID field
  itemId: ListItemID,
  __metadata: {
    // the item's type, aka `ListItemEntityTypeFullName` of the `List` to which the item belongs
    type: 'SP.Data.MyListItem'
  },
  // Item Field to update : Data to update the Field with
  Title: 'Jim Wuz Here'
}
sharepoint.listItems.update('someListGUID', listItemData, function(res));

ListItem Delete

To delete a ListItem, we can use the del() function.

sharepoint.listItems.del('someListGUID', 'someListItemId', function(err) {

});

Of course, we can also just call .del() on a listItem, after we read it's containing list.

sharepoint.lists.read('someListGUID', function(err, listReadResult) {
  var anItemInThisList = listReadResult.Items[0];
  anItemInThisList.delete(function(err) {
    //
  });
});

Why another Sharepoint Client?

Yet another SharePoint Client. This one:

  • Has test coverage
  • Isn't written in CoffeeScript
  • Supports multiple authentication schemas - currently:
    • NTLM
    • Basic
    • Online (Sharepoint 365/Online login flow)
    • Online with SAML SSO (Sharepoint 365 to Federated SAML SSO flow)
  • Accepts pull requests :-)

Tests

Tests are written in Mocha. Unit tests simply require the integration tests, and nock the API they integrate with - thus reducing the amount of test code we need to write.

Running Unit tests

This includes jshint, and the mocha unit test suite.

# install grunt globally
npm install grunt-cli -g

# run the tests
grunt test

Running Integration Tests

# Setup environment variables with your SP creds:
export SP_USERNAME=YOUR_USERNAME
export SP_PASSWORD=YOUR_PASSWORD
export SP_HOST=https://your_sp_hostname.com
export SP_AUTH_TYPE=(ntlm|basic|online|onlinesaml)
#Then run the tests:
grunt integration