pnp / pnpjs

Fluent JavaScript API for SharePoint and Microsoft Graph REST APIs
https://pnp.github.io/pnpjs/
Other
742 stars 302 forks source link

copyByPath can return an unuseable object #3020

Closed dvTB closed 2 months ago

dvTB commented 2 months ago

Major Version

3.x

Minor Version Number

24

Target environment

All

Additional environment details

Using a node.js (v20) process communicating with SharePoint online.

Expected or Desired Behavior

Returned objects should always keep the correct request-object in background so further usage of these objects is possible. SharePoint has the habit to automatically rename files a bit, if some special characters are in the filename. pnp.js doesn't return all the data that is returned from sharepoint here, so an additional call to get the current filename (and the ItemID) is needed. Also to set metadata in the next phase of the logic.

Observed Behavior

When a file is copied by copyByPath and the target is in another sitecollection, the returned IFile-object is unusable for further quries. Resulting in this call when file. getItem("ID", "FileRef") is called: ttps://tenant.sharepoint.com/sites/sourceSite/_api/web/getFileByServerRelativePath(decodedUrl='%2Fsites%2FtargetSite%2FBib1%2FA%20TEST%201%20-%20copy%20353534.pdf')/listItemAllFields?%24select=ID%2CFileRef

I guess this is also a problem if the file is just copied into another website in the same sitecollection, because sharepoint REST calls normally only accept calls for the given web.

Steps to Reproduce

Use an object of IFile to copy something into another sitecollection. const copiedFile = await file.copyByPath(destinationUrl, false, { KeepBoth: true, });

const item = await copiedFile .getItem("ID", "FileRef") // <= exception because the File Object is still targeting the source-file sitecollection

juliemturner commented 2 months ago

It seems like we may have addressed this in the v4 release (although I personally wasn't the one who did). You might look at that as an option.

bcameron1231 commented 2 months ago

Unfortunately, the changes in V4 wouldn't affect this. In the copy, I'm fairly sure we do hold on to the original Queryable and we use that to rebase the result, which would cause a problem across a site collection. I think this may be a bug, I'll take a look into it.

dvTB commented 2 months ago

Please also keep in mind that this might also be the case if a file is copied into another website (same sitecollection), as the sharepoint api normaly only accepts requests for the current website.

bcameron1231 commented 2 months ago

Hi, I looked into this. When setting your destination url for the file, please use the Absolute URL of the file. This will make sure the returned IFile object is assigned to the right Site Collection. Please see code sample below.

  const destinationUrl = `https://company.sharepoint.com/sites/destinationSite/SiteAssets/new-file.txt`;
  var file = await sp.web.getFileByServerRelativePath("/sites/targetSite/Files/file2.txt").copyByPath(destinationUrl, false, {
      KeepBoth: false,
      ResetAuthorAndCreatedOnCopy: true,
      ShouldBypassSharedLocks: false,
  });

    //this will be the correct file at /sites/destinationSite/SiteAssets/new-file.txt
   const item = await file.getItem();
patrick-rodgers commented 2 months ago

Closing this issue as answered. If you have additional questions or we did not answer your question, please open a new issue, ref this issue, and provide any additional details available. Thank you!

github-actions[bot] commented 2 months ago

This issue is locked for inactivity or age. If you have a related issue please open a new issue and reference this one. Closed issues are not tracked.