drive.WebUrl, driveItem.WebUrl and the public share link WebUrl all
derive from the same config value (graph.spaces.webdav_base), but only
driveItem.WebUrl used the pre-parsed BaseGraphService.publicBaseURL.
The other two re-parsed the config on every call.
Add a webURLForResource method on BaseGraphService for the /f/<id> URLs
(used twice, with a *string return matching the libregraph DriveItem
field shape), and inline g.publicBaseURL for the single /s/<token>
share-link case. Convert cs3ResourceToDriveItem and formatDriveItems
from free functions into BaseGraphService methods so they pick up
logger and publicBaseURL from the receiver. This also aligns them with
the surrounding code: BaseGraphService already exposes ~15 similar
methods, so the two free functions were the odd ones out.
Net: all three WebUrls are now constructed from a single pre-parsed
URL, and the (g.logger, g.publicBaseURL) plumbing at 7 call sites
disappears.