Client Side Development With SharePoint Using NodeJS And PnP

Introduction

Nowadays, client side development with SharePoint is growing bigger and bigger with lot of APIs emerging against SharePoint data. @PnP (PnPJS) is a new javascript API from SharePoint Patterns and Practices team.

PnPJS is a fluent JavaScript API for consuming SharePoint and Office 365 REST APIs in a type-safe way. You can use it with SharePoint Framework, Nodejs, or JavaScript projects. This open source initiative complements existing SDKs provided by Microsoft offering developers another way to consume information from SharePoint and Office 365.
-PnP ( https://github.com/pnp/pnp

By using this new API, we can develop the applications like,
  • SharePoint Framework,
  • Nodejs applications
  • Javascript applications
Here we are going to unleash the steps to develop the nodejs application using PnPJS api against SharePoint data.

PreRequisites

Below are the pre requisites component required for accessing the SharePoint data from Nodejs application.

Tools & Commands
  • NodeJS
  • NPM
  • Gulp-cli
  • Any Editor – Visual Studio Code (recommended)
  • Client ID & Secret details from SharePoint
NPM Common Packages
  • Typescript
  • Gulp
  • Gulp-typescript
NPM PnP Packages
  • @pnp/logging
  • @pnp/common
  • @pnp/odata
  • @pnp/sp
  • @pnp/nodejs
Environment Setup

We require the below setup before start developing the application by installing the tools and running the global npm packages. First we have to install the nodejs along with npm and then add the common packages globally in the local machine by using the below npm command.

npm install -g typescript gulp-cli 

Install Visual Studio Code used to edit and debug the source code

Generate Client Id and Secret from SharePoint

We are retrieving the SharePoint details outside of SharePoint site and so, we need authorization to access it. For that, we must treat the node js application as a SharePoint Add-In to use Client Id and Secret information in nodejs to access the SharePoint data.

Register Add-In

The below steps are used to register the new add-in in SharePoint site,
  • Navigate and login to SharePoint site (online or on-premise). I have used the SharePoint Online for example.
  • Then navigate to the Register Add-In page by entering the url as
    https://<sitename>.sharepoint.com/_layouts/15/appregnew.aspx

  • On App Information section, click Generate button next to the Client Id and Client Secret textboxes to generate the respective values.
  • Enter Add-In Title in Title textbox
  • Enter AppDomain as localhost
  • Enter RedirectUri as https://localhost
Grant Permissions to Add-In

Once the Add-In is registered, we have to set the permissions for that add-in to access the SharePoint data. We will set the Read permission level to the web scope, so that we will be able to read the web information.
  • Navigate to the SharePoint site
  • Then enter the URL https://<sitename>.sharepoint.com/_layouts/15/appinv.aspx in the browser. This will redirect to Grant permission page.
  • Enter the Client ID (which we have generated earlier), in AppId textbox and click Lookup button. That will populate the value to other textboxes in Title, App Domain and Redirect Url

  • Now enter the below permission request in XML format.
    1. <AppPermissionRequests AllowAppOnlyPolicy="true">  
    2.    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/web" Right="Read" />  
    3. </AppPermissionRequests>   
  • Then click Create button. This will redirect to you page, where we have to trust the add-in to read items from website.

    Note
    If we want to access site collection or tenant level, we have to add the xml accordingly

Development

Now, we have the environment setup and add-in details are in place. In the below example, we will write a nodejs application to retrieve the SharePoint web id, title and description.

Open the Windows powershell and create a directory for our project.
md spnodeapp
cd spnodeapp

Initialize the project by running the below npm command
npm init  

and provide the below information, when command prompts you to enter. 

name: spnodeapp
version: 1.0.0
description: Nodejs application to access SharePoint
entry point: app.js
author: <your name>

for other properties, press Enter and go next.



Create three folders in the project by running the below command and open the project in visual studio code,

md src
md dist
md config
code .



Now run the below npm commands in powershell to add the required dependencies for the project

npm install typescript gulp gulp-typescript --save-dev
npm install @pnp/logging @pnp/common @pnp/odata @pnp/sp @pnp/nodejs --save

All dependency packages are added under node_modules folder.

Settings.js 

Create settings.js file under config folder and add the below code snippet to configure the authentication details by specifying client, secret details with SharePoint site URL,

//Settings.js
  1. var settings = {  
  2.     sp: {  
  3.         id: "< Client Id >",  
  4.         secret: "< Client Secret >",  
  5.         url: "< Site Url >",  
  6.     }  
  7. }  
  8. module.exports = settings;  
In configurations are used by the pnp js code to access SharePoint data based on add-in authentication. Replace the appropriate information under id, secret and url which we created under Register Add-In section.

webs.ts 

Create webs.ts file under src folder and add the below snippet to retrieve the web information

//webs.ts
  1. import {  
  2.     sp  
  3. } from "@pnp/sp";  
  4. export default class webs {  
  5.     constructor() {}  
  6.     public getwebinfo(): void {  
  7.         sp.web.select("Id""Title""Description").get().then(w => {  
  8.             console.log("Web Id: " + w.Id);  
  9.             console.log("Web Title: " + w.Title);  
  10.             console.log("Web Description: " + w.Description);  
  11.         }).catch(e => {  
  12.             console.log(e);  
  13.         });  
  14.     }  
  15. }    
Import { sp } from “@pnp/sp” imports the methods from PnPJS to use in the code. Getwebinfo method contains the pnpjs code to retrieve the Id, Title, Description from the web (url configured in settings.js).

Now, we have configuration information to connect SharePoint site and PnPJs code to retrieve the data. But we have to create a file to link both files and enable authorization to authenticate pnpjs code.

app.ts 

Create app.ts file under src folder and add the below snippet

//app.ts
  1. declare  
  2. var require: (s: string) => any;  
  3. import {  
  4.     sp  
  5. } from "@pnp/sp";  
  6. import {  
  7.     SPFetchClient  
  8. } from "@pnp/nodejs";  
  9. import webs from "./webs";  
  10. const settings = require("../config/settings.js");  
  11. sp.setup({  
  12.     sp: {  
  13.         fetchClientFactory: () => {  
  14.             return new SPFetchClient(settings.sp.url, settings.sp.id, settings.sp.secret);  
  15.         },  
  16.     },  
  17. });  
  18. let w = new webs();  
  19. w.getwebinfo();  
  • Line 1: declare the require variable used to ensure the file is loaded before running the code
  • Line 3 & 4: Refer the dependency package sp and SPFetchClient. The methods from those package will use later to connect SharePoint.
  • Line 5: Refers the webs.ts file
  • Line 6: Ensure setting.js is file loaded before running next line
  • Line 7: sp.setup used to enable the authorization to connect SharePoint site. This must be called once in a program.
  • Line 15: Declare webs object from webs.ts
  • Line 16: Call the getwebinfo method to run the pnpjs code
Program for retrieving the web details is ready. Now we have to prepare the file for compile and run. In the project root, create tsconfig.json and add the below snippet

//tsconfig.json 
  1. {  
  2.     "files": ["src/app.ts""src/webs.ts"],  
  3.     "compilerOptions": {  
  4.         "noImplicitAny"true,  
  5.         "target""es5"  
  6.     }  
For compiling the code, create gulpfile.js under project root folder and paste the below snippet

//gulpfile.js 
  1. var gulp = require("gulp");  
  2. var ts = require("gulp-typescript");  
  3. var tsProject = ts.createProject("tsconfig.json");  
  4. gulp.task("default"function() {  
  5.     return tsProject.src().pipe(tsProject()).js.pipe(gulp.dest("dist"))  
  6. });  
The project structure looks like below,

 

Enter the below gulp and node command to compile and run the code to retrieve the web information,

gulp; node dist/app.js

The command line will run the commands one after another. Gulp task command “gulp” will compile and convert the typescript file to javascript under dist folder. Node command “node dist/app.js” will run the converted javascript file in console.

Output

 

Known Error

To resolve the error which we received for types.d.ts file not found under adalfetchclient.d.ts. Comment the below line from node_modules/@pnp/nodejs/src/net/adalfetchclient.d.ts

/// <reference path="../../../../../packages/nodejs/src/net/types.d.ts" />

After commenting and running the command gulp; node dist/app.js will render the below output in console,

 

Conclusion

So far, we have learned how to use pnpjs library in nodejs application to access the SharePoint data. The source code is available in github too from the link.