From 4e9468b9f3511eca90c4824fad491199656c3892 Mon Sep 17 00:00:00 2001 From: Evan Skrukwa Date: Tue, 17 Jun 2025 10:48:07 -0400 Subject: [PATCH 1/2] refactor web url and info resolution --- src/utils/sharepoint.rest/common.ts | 36 ++++++++++++++++------------- src/utils/sharepoint.rest/web.ts | 6 ++--- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/utils/sharepoint.rest/common.ts b/src/utils/sharepoint.rest/common.ts index 989776f..6dc2825 100644 --- a/src/utils/sharepoint.rest/common.ts +++ b/src/utils/sharepoint.rest/common.ts @@ -7,7 +7,7 @@ import { FieldTypeAsString, IFieldInfoEX, IFieldTaxonomyInfo } from "../../types import { ISPRestError } from "../../types/sharepoint.utils.types"; import { ConsoleLogger } from "../consolelogger"; import { getCacheItem, setCacheItem } from "../localstoragecache"; -import { mediumLocalCache } from "../rest"; +import { GetJsonSync, longLocalCache, mediumLocalCache } from "../rest"; import { GetWebIdSync, GetWebInfoSync } from "./web"; const logger = ConsoleLogger.get("sharepoint.rest/common"); @@ -26,15 +26,18 @@ export function hasGlobalContext() { export function GetFileSiteUrl(fileUrl: string): string { let siteUrl: string; let urlParts = fileUrl.split('/'); - if (urlParts[urlParts.length - 1].indexOf('.') > 0)//file name - urlParts.pop();//file name - let key = "GetSiteUrl|" + urlParts.join("/").toLowerCase(); + let key = "GetSiteUrl|" + fileUrl.toLowerCase(); siteUrl = getCacheItem(key); if (isNullOrUndefined(siteUrl)) { - while (!isValidGuid(GetWebIdSync(urlParts.join('/')))) + while (urlParts.length > 0) { + const candidateUrl = makeServerRelativeUrl(normalizeUrl(urlParts.join("/"), true)) + const syncResult = GetJsonSync<{ d: { Id: string; }; }>(`${candidateUrl}_api/web/Id`, null, { ...longLocalCache }); + if (syncResult.success && isValidGuid(syncResult.result.d.Id)) { + break + } urlParts.pop(); - + } siteUrl = normalizeUrl(urlParts.join('/')); setCacheItem(key, siteUrl, mediumLocalCache.localStorageExpiration);//keep for 15 minutes } @@ -46,8 +49,16 @@ export function GetFileSiteUrl(fileUrl: string): string { * If you send a guid - it will look for a site with that ID in the current context site collection */ export function GetSiteUrl(siteUrlOrId?: string): string { - let siteUrl: string; - if (isNullOrUndefined(siteUrlOrId)) { + if (!isNullOrUndefined && isValidGuid(siteUrlOrId)) { + const webInfo = GetWebInfoSync(null, siteUrlOrId); + return makeServerRelativeUrl(normalizeUrl(webInfo.ServerRelativeUrl, true)); + } + return GetSiteUrlLocally(siteUrlOrId); +} + +/** gets a siteUrl locally (without making requests) (todo although currently GetFileSiteUrl does make requests...) */ +export function GetSiteUrlLocally(siteUrl?: string): string { + if (isNullOrUndefined(siteUrl)) { if (hasGlobalContext()) { siteUrl = _spPageContextInfo.webServerRelativeUrl; if (_spPageContextInfo.isAppWeb)//#1300 if in a classic app sub-site @@ -57,20 +68,13 @@ export function GetSiteUrl(siteUrlOrId?: string): string { siteUrl = GetFileSiteUrl(window.location.pathname); } } - else if (isValidGuid(siteUrlOrId)) { - //GetWebInfoSync calls GetSiteUrl recursively, but with null should not get in here - let webInfo = GetWebInfoSync(null, siteUrlOrId); - siteUrl = webInfo.ServerRelativeUrl; - } - else siteUrl = siteUrlOrId; - //must end with / otherwise root sites will return "" and we will think there is no site url. return makeServerRelativeUrl(normalizeUrl(siteUrl, true)); } /** gets a site url, returns its REST _api url */ export function GetRestBaseUrl(siteUrl: string): string { - siteUrl = GetSiteUrl(siteUrl); + siteUrl = GetSiteUrlLocally(siteUrl); return siteUrl + '_api'; } diff --git a/src/utils/sharepoint.rest/web.ts b/src/utils/sharepoint.rest/web.ts index 1543d8d..9b98759 100644 --- a/src/utils/sharepoint.rest/web.ts +++ b/src/utils/sharepoint.rest/web.ts @@ -14,7 +14,7 @@ import { AutoDiscoverTenantInfo } from "../auth/discovery"; import { ConsoleLogger } from "../consolelogger"; import { toIsoDateFormat } from "../date"; import { GetJson, GetJsonSync, extraLongLocalCache, longLocalCache, mediumLocalCache, noLocalCache, shortLocalCache, weeekLongLocalCache } from "../rest"; -import { CONTENT_TYPES_SELECT, CONTENT_TYPES_SELECT_WITH_FIELDS, GetRestBaseUrl, GetSiteUrl, LIST_EXPAND, LIST_SELECT, WEB_SELECT, hasGlobalContext } from "./common"; +import { CONTENT_TYPES_SELECT, CONTENT_TYPES_SELECT_WITH_FIELDS, GetRestBaseUrl, GetSiteUrl, GetSiteUrlLocally, LIST_EXPAND, LIST_SELECT, WEB_SELECT, hasGlobalContext } from "./common"; import { GetListFields, GetListFieldsSync, GetListRestUrl } from "./list"; import { SPTimeZoneIdToIANATimeZoneName } from "./timzone-map"; @@ -611,7 +611,7 @@ export async function GetWebInfo(siteUrl: string, webId?: string, refreshCache?: if (currentWebId !== webId) { let url = _getWebInfoByIdRequestUrl(siteUrl, webId); webInfoResponse = await GetJson(url, null, { - method: "POST", spWebUrl: GetSiteUrl(siteUrl), ...shortLocalCache, + method: "POST", spWebUrl: GetSiteUrlLocally(siteUrl), ...shortLocalCache, jsonMetadata: jsonTypes.nometadata, allowCache: refreshCache !== true }); @@ -641,7 +641,7 @@ export function GetWebInfoSync(siteUrl: string, webId?: string): IWebBasicInfo { if (currentWebId !== webId) { let url = _getWebInfoByIdRequestUrl(siteUrl, webId); let syncResult = GetJsonSync(url, null, { - method: "POST", spWebUrl: GetSiteUrl(siteUrl), ...shortLocalCache, + method: "POST", spWebUrl: GetSiteUrlLocally(siteUrl), ...shortLocalCache, jsonMetadata: jsonTypes.nometadata }); if (syncResult.success) { From 029d0659ffc2c0d11af5e6d338b51c279e6ea295 Mon Sep 17 00:00:00 2001 From: Evan Skrukwa Date: Tue, 17 Jun 2025 11:13:43 -0400 Subject: [PATCH 2/2] typo --- src/utils/sharepoint.rest/common.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/sharepoint.rest/common.ts b/src/utils/sharepoint.rest/common.ts index 6dc2825..90ab1da 100644 --- a/src/utils/sharepoint.rest/common.ts +++ b/src/utils/sharepoint.rest/common.ts @@ -49,7 +49,7 @@ export function GetFileSiteUrl(fileUrl: string): string { * If you send a guid - it will look for a site with that ID in the current context site collection */ export function GetSiteUrl(siteUrlOrId?: string): string { - if (!isNullOrUndefined && isValidGuid(siteUrlOrId)) { + if (!isNullOrUndefined(siteUrlOrId) && isValidGuid(siteUrlOrId)) { const webInfo = GetWebInfoSync(null, siteUrlOrId); return makeServerRelativeUrl(normalizeUrl(webInfo.ServerRelativeUrl, true)); }