Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phillipharding/f4196983a57198f994f7dc2b7bef1986 to your computer and use it in GitHub Desktop.
Save phillipharding/f4196983a57198f994f7dc2b7bef1986 to your computer and use it in GitHub Desktop.
Create/Ensure a SharePoint folder path with nested folders using PnPJS
/*
Hit 'ctrl + d' or 'cmd + d' to run the code, view console for results
*/
import { IWeb, sp, Web } from "@pnp/sp/presets/all";
import { HttpRequestError } from "./@pnp/odata";
const TranslatePnPError = async (opText: string, e) => {
if (e?.isHttpRequestError) {
const json = await (<HttpRequestError>e).response.json();
const errorObject = typeof json["odata.error"] === "object" ? {...json["odata.error"]} : {...e};
const message = typeof json["odata.error"] === "object" ? errorObject.message.value : errorObject.message;
return {
opName: opText || "",
errorCode: e.status || (<HttpRequestError>e).response.status,
errorText: (<HttpRequestError>e).response.statusText || e.statusText,
message: message || "Unknown HTTP Error",
isHttpRequestError: true,
errorObject: errorObject
};
} else {
return {
opName: opText || "",
errorCode: e.status,
errorText: e.statusText,
message: e.message || "Unknown",
isHttpRequestError: false,
errorObject: null
};
}
};
const EnsureFolderPath = async (web: IWeb, baseFolderServerRelativeUrl: string, folderPath: string): Promise<boolean> => {
try {
const basePaths = baseFolderServerRelativeUrl.trim().toLowerCase().split("/").filter( f => (f || "").length > 0);
const relativeFolderPath = folderPath.split("/")
.filter( f => (f || "").length > 0)
.filter( (p: string) => {
return !basePaths.includes(p.trim().toLowerCase());
})
.join("/");
console.log(`EnsureFolderPath(${baseFolderServerRelativeUrl}) ::> ${relativeFolderPath}`);
/* try get base folder first */
try {
await web.getFolderByServerRelativeUrl(baseFolderServerRelativeUrl)();
} catch(e) {
const error = await TranslatePnPError(`Get Base Folder: ${baseFolderServerRelativeUrl}`, e);
console.error(`Base Folder Not Found: `, error);
throw error;
}
const folderPaths = relativeFolderPath.split("/").filter( f => (f || "").length > 0);
let parentFolder = `${baseFolderServerRelativeUrl}`;
/* create subfolders */
for (let folderName of folderPaths) {
const currentFolderPath = `${parentFolder}/${folderName}`;
try {
/* find it first */
await web.getFolderByServerRelativeUrl(currentFolderPath)();
} catch (e) {
const findError = await TranslatePnPError(`Get Folder: ${currentFolderPath}`, e);
console.log(`NOT FOUND: ${currentFolderPath}`, findError);
if ((findError.errorCode !== 404) || (!findError.errorText.match(/not found/gi) && !findError.message.match(/file not found/gi)) ) {
/* its not a NOT FOUND error */
throw findError;
}
/* create it */
try {
const spFolder = await web.getFolderByServerRelativeUrl(parentFolder).folders.add(folderName);
console.log(`CREATED: ${currentFolderPath}`, spFolder);
} catch (e) {
const createError = await TranslatePnPError(`Create Folder: ${currentFolderPath}`, e);
console.log(`ERROR CREATING: ${currentFolderPath}`, createError);
throw createError;
}
}
parentFolder = `${parentFolder}/${folderName}`;
}
return true;
} catch (e) {
console.error(`EnsureFolderPath: `, e);
throw e;
}
};
(async () => {
console.clear();
const web = Web("https://platinumdogsconsulting.sharepoint.com/sites/EELTest");
const webInfo = await web.select("Title", "ServerRelativeUrl")();
console.log("Web Title: ", webInfo.Title);
console.log("Web ServerRelativeUrl: ", webInfo.ServerRelativeUrl);
await EnsureFolderPath(web, '/sites/EELTest/Shared Documents', '/sites/EELTest/Shared Documents/Extracts/Scheduled/2021/11-November/LMS_ee48ff4586fa49ee84f5a6119356d185');
await EnsureFolderPath(web, '/sites/EELTest/Shared Documents', '/sites/EELTest/Shared Documents/Extracts/Manual/2021/11-November/LMS_ee48ff4586fa49ee84f5a6119356d185');
await EnsureFolderPath(web, '/sites/EELTest/Shared Documents', '/sites/EELTest/Shared Documents/Dumps');
await EnsureFolderPath(web, '/sites/EELTest/Shared Documents', '/sites/EELTest/Shared Documents');
})().catch(console.log);
@jimmywim
Copy link

jimmywim commented Nov 9, 2023

Updated for @pnpjs v3:

import { IWeb } from "@pnp/sp/presets/all";
import { HttpRequestError } from "@pnp/queryable";

import "@pnp/sp/search";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/files";
import "@pnp/sp/folders";


const TranslatePnPError = async (opText: string, e) => {
  if (e?.isHttpRequestError) {
    const json = await (<HttpRequestError>e).response.json();
    const errorObject = typeof json["odata.error"] === "object" ? {...json["odata.error"]} : {...e};
    const message = typeof json["odata.error"] === "object" ? errorObject.message.value : errorObject.message;
    return {
      opName: opText || "",
      errorCode: e.status || (<HttpRequestError>e).response.status, 
      errorText: (<HttpRequestError>e).response.statusText || e.statusText, 
      message: message || "Unknown HTTP Error", 
      isHttpRequestError: true, 
      errorObject: errorObject
    };
  } else {
    return {
      opName: opText || "",
      errorCode: e.status,
      errorText: e.statusText,
      message: e.message || "Unknown", 
      isHttpRequestError: false,
      errorObject: null
    };
  }
};
export const EnsureFolderPath = async (web: IWeb, baseFolderServerRelativeUrl: string, folderPath: string): Promise<boolean> => {
  try {
    const basePaths = baseFolderServerRelativeUrl.trim().toLowerCase().split("/").filter( f => (f || "").length > 0);
    const relativeFolderPath = folderPath.split("/")
      .filter( f => (f || "").length > 0)
      .filter( (p: string) => {
        return !basePaths.includes(p.trim().toLowerCase());
      })
      .join("/");

    console.log(`EnsureFolderPath(${baseFolderServerRelativeUrl}) ::> ${relativeFolderPath}`);

    /* try get base folder first */
    try {
      await web.getFolderByServerRelativePath(baseFolderServerRelativeUrl)();
    } catch(e) {
      const error = await TranslatePnPError(`Get Base Folder: ${baseFolderServerRelativeUrl}`, e);
      console.error(`Base Folder Not Found: `, error);
      throw error;
    }

    const folderPaths = relativeFolderPath.split("/").filter( f => (f || "").length > 0);
    let parentFolder = `${baseFolderServerRelativeUrl}`;
    
    /* create subfolders */
    for (let folderName of folderPaths) {
      const currentFolderPath = `${parentFolder}/${folderName}`;
      try {
        /* find it first */
        await web.getFolderByServerRelativePath(currentFolderPath)();
      } catch (e) {
        const findError = await TranslatePnPError(`Get Folder: ${currentFolderPath}`, e);
        console.log(`NOT FOUND: ${currentFolderPath}`, findError);
        if ((findError.errorCode !== 404) || (!findError.errorText.match(/not found/gi) && !findError.message.match(/file not found/gi)) ) {
          /* its not a NOT FOUND error */
          throw findError;
        }
        /* create it */
        try {
          const spFolder = await web.getFolderByServerRelativePath(parentFolder).folders.addUsingPath(folderName);
          console.log(`CREATED: ${currentFolderPath}`, spFolder);
        } catch (e) {
          const createError = await TranslatePnPError(`Create Folder: ${currentFolderPath}`, e);
          console.log(`ERROR CREATING: ${currentFolderPath}`, createError);
          throw createError;
        }
      }
      parentFolder = `${parentFolder}/${folderName}`;
    }
    return true;
  } catch (e) {
    console.error(`EnsureFolderPath: `, e);
    throw e;
  }
};

@phillipharding
Copy link
Author

Cheers @jimmywim 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment