PnP
732 TopicsSPFX 1.21.1 in monorepo - utility module could not be exported
I am trying to migrate multiple projects to monorepo. I need to migrate some common utilities functions in a common module. There is an export warning that the module has no exports, while it does has. Running npm run spfx1:build works fine. But when I do npm run spfx1:serve it throws a warning export 'DemoUtilities' (imported as 'DemoUtilities') was not found in 'utilities-library/utils' (module has no exports) Opening the a SharePoint page online, it errors with missing exports. Can you point me to possible solutions? Here is a very simple OOB SPFX solution structure: utilities-library - src -- utils.ts - index.ts - package.json - tsconfig.json spfx1 - config - sharepoint - src -- skipped for brevity - gulpfile.js - package.json - tsconfig.json package.json tsconfig.base.json Specifics for per files utilities-library -> package.json { "name": "utilities-library", "version": "1.0.0", "main": "lib/index.js", "types": "lib/index.d.ts", "scripts": { "start": "node index.js", "test": "echo \"test\"" }, "type": "module", "workspaces": [ "true" ], "devDependencies": { "typescript": "^5.3.5" } } utilities-library ->tsconfig.json { "compilerOptions": { "composite": true, "declaration": true, "outDir": "lib" }, "include": ["**/*.ts"] } utilities-library ->index.ts export { DemoUtilites } from './src/utils'; utilities-library -> utils.ts import { ISPFXContext, spfi, SPFx } from "@pnp/sp"; import "@pnp/sp/webs"; import "@pnp/sp/lists"; export const DemoUtilites = { checkListExists: async ( listTitle: string, context: ISPFXContext ): Promise<boolean> => { const sp = spfi().using(SPFx(context)); return new Promise<boolean>((resolve) => { sp.web.lists .getByTitle(listTitle)() .then(() => { resolve(true); }) .catch((error) => { if (!(error?.status === 404)) { console.log(`Error checking list ${listTitle}`, error); } resolve(false); }); }); } } spfx1 -> gulpfile.js 'use strict'; const build = require('@microsoft/sp-build-web'); const path = require("path"); build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`); build.configureWebpack.mergeConfig({ additionalConfiguration: (generatedConfig) => { generatedConfig.resolve = generatedConfig.resolve || {}; generatedConfig.resolve.alias = { ...(generatedConfig.resolve.alias || {}), 'utilities-library': path.resolve(__dirname, '../utilities-library/lib'), 'utilities-library/utils': path.resolve(__dirname, '../utilities-library/lib/utils') }; return generatedConfig; } }); var getTasks = build.rig.getTasks; build.rig.getTasks = function () { var result = getTasks.call(build.rig); result.set('serve', result.get('serve-deprecated')); return result; }; build.initialize(require('gulp')); spfx1 -> package.json { ... "dependencies": { "@microsoft/decorators": "1.21.1", "@microsoft/sp-core-library": "1.21.1", "@microsoft/sp-dialog": "1.21.1", "@microsoft/sp-listview-extensibility": "1.21.1", "@pnp/sp": "^4.12.0", "utilities-library": "^1.0.0", "office-ui-fabric-react": "^7.204.1", "react": "17.0.1", "react-dom": "17.0.1", "tslib": "2.3.1" }, ... } spfx1 -> tsconfig.json { "extends": "../tsconfig.base.json", "compilerOptions": { "rootDir": "src", "outDir": "lib" }, "include": ["src/**/*.ts", "src/**/*.tsx"], "references": [ { "path": "../utilities-library" } ] } root -> package.json { "name": "monorepo-test", "workspaces": [ "spfx1", "utilities-library" ], "scripts": { "spfx1:build": "gulp build -f ./spfx1/gulpfile.js --workspace spfx1", "spfx1:clean": "gulp clean -f ./spfx1/gulpfile.js --workspace spfx1", "spfx1:serve": "gulp serve -f ./spfx1/gulpfile.js --workspace spfx1 --nobrowser", "spfx1:bundle": "gulp bundle -f ./spfx1/gulpfile.js --workspace spfx1", "spfx1:pkg": "gulp package-solution -f ./spfx1/gulpfile.js --workspace spfx1", "spfx1:prod": "gulp build -f ./spfx1/gulpfile.js --workspace spfx1 --ship & gulp bundle -f ./spfx1/gulpfile.js --workspace spfx1 --ship & gulp package-solution -f ./spfx1/gulpfile.js --workspace spfx1 --ship", "utilities-library:build": "tsc --project utilities-library/tsconfig.json", "utilities-library:watch": "npm run utilities-library:build -- --watch", "clean:node": "rm -rf **/node_modules" }, "devDependencies": { "npm-run-all": "^4.1.5" } } root -> tsconfig.base.json { "extends": "./node_modules/@microsoft/rush-stack-compiler-5.3/includes/tsconfig-web.json", "compilerOptions": { "target": "es5", "forceConsistentCasingInFileNames": true, "module": "esnext", "moduleResolution": "node", "jsx": "react", "declaration": true, "sourceMap": true, "experimentalDecorators": true, "skipLibCheck": true, "outDir": "lib", "inlineSources": false, "noImplicitAny": true, "rootDir": ".", "baseUrl": ".", // Important for path mapping "paths": { "utilities-library/*": [ "utilities-library/lib/*" ] }, "typeRoots": [ "./node_modules/@types", "./node_modules/@microsoft" ], "types": [ "webpack-env" ], "lib": [ "es5", "dom", "es2015.collection", "es2015.promise" ] }, "include": [ "src/**/*.ts", "src/**/*.tsx" ] }146Views0likes2CommentsFunction of "GET IT" button in Sharepoint app?
Hello, I have a question related to Sharepoint deployment. Context: I have two Sharepoint sites. Both have the same webpart application but different version. But they both display the lastest version of the webpart. Questions: - What the function of the "GET IT" button in details of the application if both running different version and still have same webpart? - How can I deploy different version to each site because I plan to have two sites DEV and PRO? Thank in advance.Solved48Views0likes1CommentSharepoint Online: fastest way to retrieve folder count in a document library
Hi all I'm really looking for what the title says. Right now I'm doing Get-PnPFolderItem -ItemType Folder (using Pnp.Powershell but can try other options) but with more than a few 10s of folders, this is REALLY slow. The thing is, I just need a count (recursively), not all info as I'm getting with Get-PnPFolderItem. Any ideas?Solved120Views0likes1CommentImporting JSON as a list in SharePoint Online via pnp
I'm trying to import a JSON list file to my Sharepoint online website. But it seems impossible to import it directly. Does anyone know a possibility via pnp because I saw a method on pnp named "fromJson" but I don't know how to use it to import my files to my SharePoint website. Thanks in advance!59Views0likes0CommentsGetting all the pages of a site in the template
I am new in SharePoint and trying to get the template of a site and all the pages of it using the cmdlet: Get-PnPSiteTemplate -Out .\template.xml I am not getting more than the homepage. I need to get all the pages in the template to provision later another sites directly using the cmdlet: Invoke-PnPSiteTemplate -Path template.xml If you know if it is not possible or how to do it I would be really thankful!Solved3.2KViews0likes2Comments401 unauthorised for ExecuteQuery in sharepoint CSOM
Hi, I am trying to connect the sharepoint site with client id and secret but getting 401 unauthroised error while hitting the executequery() method. While doing app registrations both Microsoft graph and share point API permissions with full site control has been given including trusted the app through appinv.aspx. Still getting 401 unauthorised error. Since ACS is retiring, do we need to follow any other permissions for share point level site access. The same execute query is working fine for client id, certificate combination. But not working for client id and secret. static void Main(string[] args) { var authManager = new AuthenticationManager("***************************", "C:\\Program Files\\OpenSSL-Win64\\bin\\certificate.pfx", "*******", "********.onmicrosoft.com"); using (var cc = authManager.GetContext("https://****.sharepoint.com/sites/****")) { cc.Load(cc.Web, p => p.Title); cc.ExecuteQuery(); Console.WriteLine(cc.Web.Title); ListCollection listCollection = cc.Web.Lists; cc.ExecuteQuery(); // this is working fine }; // Replace with your SharePoint Online details string siteUrl = "****************************"; string tenantId = "***************************"; string clientId = "********************************"; string clientSecret = "******************************"; // App secret try { using (var context = GetClientContextWithOAuth(siteUrl, tenantId, clientId, clientSecret)) { // Example: Retrieve web title Web web = context.Web; context.Load(web, w => w.Title); context.ExecuteQuery(); // this is throwing 401 unauthorized error Console.WriteLine("Connected to: " + web.Title); } } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } } private static ClientContext GetClientContextWithOAuth(string siteUrl, string tenantId, string clientId, string clientSecret) { // Azure AD OAuth 2.0 endpoint string authority = $"https://login.microsoftonline.com/*******************"; // Use MSAL to acquire an access token var app = ConfidentialClientApplicationBuilder.Create(clientId) .WithClientSecret(clientSecret) .WithAuthority(new Uri(authority)) .Build(); var authResult = app.AcquireTokenForClient(new[] { $"{siteUrl}/.default" }).ExecuteAsync().Result; if (authResult == null) { throw new Exception("Failed to acquire the access token."); } // Use the access token to authenticate the ClientContext var context = new ClientContext(siteUrl); context.ExecutingWebRequest += (sender, e) => { e.WebRequestExecutor.WebRequest.Headers["Authorization"] = "Bearer " + authResult.AccessToken; }; return context; }129Views0likes0CommentsHow to Get the Correct Client ID for Graph API Authentication in SPFx Without Forcing Login?
Hello everyone, I'm trying to connect my SPFx web part to the Microsoft Graph API in the most modern and seamless way possible, avoiding any additional login prompts for the user. Here's the setup I'm currently using: _graph = graphfi().using(graphSPFx(context as ISPFXContext)); It's crucial for me to retrieve all the Graph API credentials directly from the SharePoint context to ensure a seamless experience for users. However, I'm encountering a 400 error when trying to acquire the token: AADSTS500011: The resource principal named 806f609a-6160-4235-ab06-91c8fe86ccee was not found in the tenant named ***. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant... The issue here is that the clientId mentioned (806f609a-6160-4235-ab06-91c8fe86ccee) does not exist in our tenant's Azure AD, and it never has. From my research, this seems like some kind of fallback client ID from Microsoft. The only way I can get it to work is by explicitly adding the correct clientId manually like this: _graph = graphfi().using(graphSPFx(context as ISPFXContext)).using(MSAL({ authParams: { scopes: [...] }, configuration: { auth: { clientId: "CORRECT_CLIENT_ID", // copied from AD authority: "https://login.microsoftonline.com/{tenantId}" }, cache: {...} } })); However, this approach causes a redirect or popup prompt, often requiring users to use multi-factor authentication on their mobile devices. My goal is to avoid this entirely. Questions: How can I retrieve the correct clientId directly from the SharePoint context? The context itself doesn't seem to expose what client ID is being used to authenticate to the Graph API. Is there any way to handle this without modifying the context or forcing a re-login? Why does SharePoint seem to be using this "mysterious" fallback client ID that doesn't exist in the tenant? I've looked at multiple tutorials, but most of them are outdated by several years (some over 8 years old). Even following those tutorials results in the same error when testing in the Workbench or after deployment. Does anyone know a way to address this issue without combing through outdated documentation? I’d appreciate any guidance or insights! Thank you in advance! Best regards, Mario208Views0likes1CommentManaged metadata showing up randomly in lists (might be PnP Provisioning related)
Dear people, I have SharePoint sites with a lot of lists each containing a couple of managed metadata columns. The sites are defined in a template and get rolled out via PnP provisioning. I did that many times before and never had this: The lists show a weird behavior: some items get randomly the value of a specific managed metadata (it's always the same). None of the columns have set a default value. All lists have only list content types - no site content types. The lists where the metadata shows up don't even have a column where this metadata is set. I was suspecting the -1 setting in the default value in the columns to connect to the Hidden Taxonomy List so I removed all default values. But the issue persists. Has anyone ever experienced this? Thank y'all!51Views0likes0CommentsSharePoint Authentication using PnP Framework
Hi guys, Looking for some advice. Does anyone have an idea of how can we connect to SharePoint using Client Id - Client Secret authentication in Web API using PnP Framework tool? Right now, we use "SharePoint PnP Core Online" tool but this tool is now deprecated. Any help will be appreciated. Thank You.14KViews0likes4Comments