@spfx-extensions/package 1.0.0 → 1.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/8d1029da-85e6-48cc-aaaf-37a5bbc0b9be.manifest.json +2 -2
  2. package/dist/d6ca1fc2-0591-4c6d-8a25-cae3262c017b.manifest.json +2 -2
  3. package/dist/{debug/ClientSideAssets/spfx-extension-application-customizer_02e75437509d6228ebfb.js → spfx-extension-application-customizer_deec56e911443a8e38f9.js} +1 -1
  4. package/dist/spfx-extension-core.js +2202 -1
  5. package/dist/spfx-extension-coreconfigurator.js +39509 -96
  6. package/dist/spfx-extension-loader_a2f8425b774226f5f084.js +3 -0
  7. package/dist/spfx-extension-wrapper.js +130 -1
  8. package/dist/{debug/ClientSideAssets/spfx-extensionloader-web-part_b51ed89cf71889d67683.js → spfx-extensionloader-web-part_cc4f89190581659bbfff.js} +1 -1
  9. package/package.json +2 -2
  10. package/dist/debug/83e13c11-682e-4eaa-9ae0-74617ca28f96/ClientSideInstance.xml +0 -9
  11. package/dist/debug/83e13c11-682e-4eaa-9ae0-74617ca28f96/Extension_8d1029da-85e6-48cc-aaaf-37a5bbc0b9be.xml +0 -1
  12. package/dist/debug/83e13c11-682e-4eaa-9ae0-74617ca28f96/WebPart_d6ca1fc2-0591-4c6d-8a25-cae3262c017b.xml +0 -1
  13. package/dist/debug/83e13c11-682e-4eaa-9ae0-74617ca28f96/elements.xml +0 -9
  14. package/dist/debug/AppManifest.xml +0 -1
  15. package/dist/debug/ClientSideAssets/3be36e80-4431-4b52-99c5-0a339b4e696e_color.png +0 -0
  16. package/dist/debug/ClientSideAssets/3be36e80-4431-4b52-99c5-0a339b4e696e_outline.png +0 -0
  17. package/dist/debug/ClientSideAssets/spfx-extension-core.js +0 -1
  18. package/dist/debug/ClientSideAssets/spfx-extension-coreconfigurator.js +0 -169
  19. package/dist/debug/ClientSideAssets/spfx-extension-loader_009c64efcf40eaeca598.js +0 -3
  20. package/dist/debug/ClientSideAssets/spfx-extension-wrapper.js +0 -1
  21. package/dist/debug/ClientSideAssets.xml +0 -1
  22. package/dist/debug/ClientSideAssets.xml.config.xml +0 -1
  23. package/dist/debug/[Content_Types].xml +0 -1
  24. package/dist/debug/_rels/.rels +0 -1
  25. package/dist/debug/_rels/AppManifest.xml.rels +0 -1
  26. package/dist/debug/_rels/ClientSideAssets.xml.rels +0 -1
  27. package/dist/debug/_rels/feature_83e13c11-682e-4eaa-9ae0-74617ca28f96.xml.rels +0 -1
  28. package/dist/debug/feature_83e13c11-682e-4eaa-9ae0-74617ca28f96.xml +0 -1
  29. package/dist/debug/feature_83e13c11-682e-4eaa-9ae0-74617ca28f96.xml.config.xml +0 -1
  30. package/dist/deploy/sp-fx-extensions.sppkg +0 -0
  31. package/dist/spfx-extension-application-customizer_02e75437509d6228ebfb.js +0 -1
  32. package/dist/spfx-extension-loader_009c64efcf40eaeca598.js +0 -3
  33. package/dist/spfx-extensionloader-web-part_b51ed89cf71889d67683.js +0 -3
@@ -1 +1,2202 @@
1
- var l1=Object.create;var{getPrototypeOf:a1,defineProperty:Hx,getOwnPropertyNames:r1}=Object;var e1=Object.prototype.hasOwnProperty;var Xw=(x,w,y)=>{y=x!=null?l1(a1(x)):{};let $=w||!x||!x.__esModule?Hx(y,"default",{value:x,enumerable:!0}):y;for(let Q of r1(x))if(!e1.call($,Q))Hx($,Q,{get:()=>x[Q],enumerable:!0});return $};var _w=(x,w)=>()=>(w||x((w={exports:{}}).exports,w),w.exports);var Rw=(x,w)=>{for(var y in w)Hx(x,y,{get:w[y],enumerable:!0,configurable:!0,set:($)=>w[y]=()=>$})};var Fw=(x,w)=>()=>(x&&(w=x(x=0)),w);var qx="d6ca1fc2-0591-4c6d-8a25-cae3262c017b",A="45e75137-13c5-4bb2-a2b3-8ab6382682ee",px="SPFxExtensionsConfigurator",t="SitePages/SPFxExtensionsConfigurator.aspx",m="manifest.txt",X="collectionconfig.txt",kx="Loading...",v="SPFxExtensionsConfiguration",U="SPFxExtensionsWhiteList",Lw="SPFxExtensions",g="/SPFxExtensions/",_="SPFxExtensionsData",P="[SPFxExtensionCore]",Dx={appDefinitionMap:[],appRelativeEntryPointUrls:[],isESM:!0},nw={enabledEverywhere:!1,excludedHubIds:[],excludedIds:[],includedHubIds:[],includedIds:[]},Gx={enabledAppCollections:[],urlMap:[]},s="00000000-0000-0000-0000-000000000000";function B(x,w,y=x){return($)=>{let Q=""+$,Z=Q.indexOf(w,x.length);return~Z?x+x9(Q,w,y,Z)+w:x+Q+w}}function x9(x,w,y,$){let Q="",Z=0;do Q+=x.substring(Z,$)+y,Z=$+w.length,$=x.indexOf(w,Z);while(~$);return Q+x.substring(Z)}var hw=B("\x1B[0m","\x1B[0m"),Ew=B("\x1B[1m","\x1B[22m","\x1B[22m\x1B[1m"),Aw=B("\x1B[2m","\x1B[22m","\x1B[22m\x1B[2m"),dw=B("\x1B[3m","\x1B[23m"),Sw=B("\x1B[4m","\x1B[24m"),Mw=B("\x1B[7m","\x1B[27m"),vw=B("\x1B[8m","\x1B[28m"),Uw=B("\x1B[9m","\x1B[29m"),gw=B("\x1B[30m","\x1B[39m"),fw=B("\x1B[31m","\x1B[39m"),Cw=B("\x1B[32m","\x1B[39m"),Nw=B("\x1B[33m","\x1B[39m"),ow=B("\x1B[34m","\x1B[39m"),Iw=B("\x1B[35m","\x1B[39m"),uw=B("\x1B[36m","\x1B[39m"),Tw=B("\x1B[37m","\x1B[39m"),cw=B("\x1B[90m","\x1B[39m"),pw=B("\x1B[40m","\x1B[49m"),tw=B("\x1B[41m","\x1B[49m"),sw=B("\x1B[42m","\x1B[49m"),iw=B("\x1B[43m","\x1B[49m"),lw=B("\x1B[44m","\x1B[49m"),aw=B("\x1B[45m","\x1B[49m"),rw=B("\x1B[46m","\x1B[49m"),ew=B("\x1B[47m","\x1B[49m"),x3=B("\x1B[90m","\x1B[39m"),w3=B("\x1B[91m","\x1B[39m"),i=B("\x1B[92m","\x1B[39m"),y3=B("\x1B[93m","\x1B[39m"),$3=B("\x1B[94m","\x1B[39m"),Q3=B("\x1B[95m","\x1B[39m"),Z3=B("\x1B[96m","\x1B[39m"),b3=B("\x1B[97m","\x1B[39m"),V3=B("\x1B[100m","\x1B[49m"),z3=B("\x1B[101m","\x1B[49m"),B3=B("\x1B[102m","\x1B[49m"),Y3=B("\x1B[103m","\x1B[49m"),W3=B("\x1B[104m","\x1B[49m"),j3=B("\x1B[105m","\x1B[49m"),K3=B("\x1B[106m","\x1B[49m"),J3=B("\x1B[107m","\x1B[49m");function V(...x){console.error(i(P),(/*@__PURE__*/new Date()).toISOString(),...x)}function O(...x){console.warn(i(P),(/*@__PURE__*/new Date()).toISOString(),...x)}function j(...x){console.info(i(P),(/*@__PURE__*/new Date()).toISOString(),...x)}function K(...x){}function Ox(x,w,y){V("Error while executing onInstanceRequested for app",x.id,"with name",x.name,y?`Additional Data: ${y}`:"",w)}function f(){return O("The app instance event was called before app instance was initialized."),()=>{}}var Xx=window.crypto.randomUUID();function l(){return Xx}function tx(){return Xx=window.crypto.randomUUID(),Xx}function _x(x){return x.replace("{","").replace("}","")}function O3(x){return JSON.parse(JSON.stringify(x))}function w9(x,w,y){let $=x.instances.findIndex((Q)=>Q.key===w);if($>-1){let Q=x.instances.splice($,1);if(Q.length<1)return;let Z=Q[0];Z.executeListeners("onConfigurationClose",void 0),Z.allEventListeners.splice(0,Z.allEventListeners.length),y?.()}}async function sx(x){let w=window.__SPFxExtensions.Apps.filter((y)=>!y.isWebPartApp&&!y.keepOnContextChange&&y.id!==A);for(let y of w){K(y,"---Unmounting on context change");for(let $ of y.instances.filter((Q)=>Q.contextId!==x))$.unmount()}}function a(x,w){if(w.hasBeenRequested)return;try{w.hasBeenRequested=!0,x.onInstanceRequested(w).then((y)=>{w.unmount=()=>{w9(x,w.key,y)},w.instanceLoadPromiseResolver()}).catch((y)=>{Ox(x,y)})}catch(y){Ox(x,y)}}function y9(x){K("Executing appAdded event for",x.id),window.__SPFxExtensions.AppEventListeners.filter((w)=>w.eventName==="appAdded").forEach((w)=>{try{w.handler(x)}catch(y){V("Error executing appAdded event",y)}})}function Rx(x){let w=window.__SPFxExtensions.Apps.find((y)=>y.id===x);if(!w)K("Registering new app",x),w={id:x,name:kx,description:kx,isWebPartApp:!1,keepOnContextChange:!1,autoExecute:!1,maxInstances:1/0,hideAppSelectorWhenAppLoaded:!1,hideConfiguratorButton:!1,registrationCompleted:!1,instances:[],async onInstanceRequested(){return f}},window.__SPFxExtensions.Apps.push(w);return w}function ix(){if(!window.__SPFxExtensions.Apps)window.__SPFxExtensions.Apps=[];if(!window.__SPFxExtensions.RegisterApp)window.__SPFxExtensions.RegisterApp=async(x)=>{let w=Rx(x.id);if(w.registrationCompleted)return w;return w.registrationCompleted=!0,w.name=x.name,w.description=x.description,w.isWebPartApp=x.isWebPartApp,w.keepOnContextChange=x.keepOnContextChange??!1,w.autoExecute=x.autoExecute??!1,w.maxInstances=x.maxInstances??1/0,w.hideAppSelectorWhenAppLoaded=x.hideAppSelectorWhenAppLoaded??!1,w.hideConfiguratorButton=x.hideConfiguratorButton??!1,w.icon=x.icon,w.onInstanceRequested=x.onInstanceRequested,y9(w),w.instances.forEach((y)=>{a(w,y)}),w};if(!window.__SPFxExtensions.UnregisterApp)window.__SPFxExtensions.UnregisterApp=async(x)=>{let w=window.__SPFxExtensions.Apps.findIndex(($)=>$.id===x);if(w<0)return;let y=window.__SPFxExtensions.Apps.splice(w,1);if(y.length<1)return;return K("Unregistering app",y[0].id,y[0].name),y[0].instances.forEach(($)=>{$.unmount()}),y[0]}}function $9(x){let w=(Q)=>{let Z=x.allEventListeners.findIndex((b)=>b.key===Q.key);if(Z>-1)K("Removing event listener",Q),x.allEventListeners.splice(Z,1)},y=(Q,Z)=>{let b={key:window.crypto.randomUUID(),eventName:Q,handler:Z};return x.allEventListeners.push(b),()=>{w(b)}},$=(Q,Z)=>{for(let b of x.allEventListeners){if(b.eventName!=Q)continue;if(b.handler)b.handler(Z)}};x.addEventListener=y,x.executeListeners=$}function Q9(x,w){K("Executing instanceAdded event for app",x.id,"instance",w.key),window.__SPFxExtensions.AppEventListeners.filter((y)=>y.eventName==="instanceAdded").forEach((y)=>{try{y.handler({app:x,instance:w})}catch($){V("Error executing instanceAdded event",$)}})}function Z9(x){let{promise:w,resolve:y}=Promise.withResolvers(),$={...x,key:window.crypto.randomUUID(),contextId:l(),hasBeenRequested:!1,unmount:f,allEventListeners:[],addEventListener:f,executeListeners:f,instanceLoadPromise:w,instanceLoadPromiseResolver:y};return $9($),$}function lx(){if(!window.__SPFxExtensions.InstantiateApp)window.__SPFxExtensions.InstantiateApp=async(x,w)=>{let y=Rx(x);K("Creating app instance for app",x);let $=Z9(w);if(y.instances.push($),Q9(y,$),y.registrationCompleted)a(y,$);return $}}async function C(x,w=0){let $=(/*@__PURE__*/new TextEncoder()).encode(x),Q=await window.crypto.subtle.digest("SHA-1",$),b=Array.from(new Uint8Array(Q)).map((W)=>W.toString(16).padStart(2,"0")).join("");return w>0?b.substring(0,w):b}var Lx=(x,w)=>w.some((y)=>x instanceof y),ax,rx;function b9(){return ax||(ax=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])}function V9(){return rx||(rx=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])}var nx=/*@__PURE__*/new WeakMap,Fx=/*@__PURE__*/new WeakMap,r=/*@__PURE__*/new WeakMap;function z9(x){let w=new Promise((y,$)=>{let Q=()=>{x.removeEventListener("success",Z),x.removeEventListener("error",b)},Z=()=>{y(d(x.result)),Q()},b=()=>{$(x.error),Q()};x.addEventListener("success",Z),x.addEventListener("error",b)});return r.set(w,x),w}function B9(x){if(nx.has(x))return;let w=new Promise((y,$)=>{let Q=()=>{x.removeEventListener("complete",Z),x.removeEventListener("error",b),x.removeEventListener("abort",b)},Z=()=>{y(),Q()},b=()=>{$(x.error||new DOMException("AbortError","AbortError")),Q()};x.addEventListener("complete",Z),x.addEventListener("error",b),x.addEventListener("abort",b)});nx.set(x,w)}var mx={get(x,w,y){if(x instanceof IDBTransaction){if(w==="done")return nx.get(x);if(w==="store")return y.objectStoreNames[1]?void 0:y.objectStore(y.objectStoreNames[0])}return d(x[w])},set(x,w,y){return x[w]=y,!0},has(x,w){if(x instanceof IDBTransaction&&(w==="done"||w==="store"))return!0;return w in x}};function y1(x){mx=x(mx)}function Y9(x){if(V9().includes(x))return function(...w){return x.apply(hx(this),w),d(this.request)};return function(...w){return d(x.apply(hx(this),w))}}function W9(x){if(typeof x==="function")return Y9(x);if(x instanceof IDBTransaction)B9(x);if(Lx(x,b9()))return new Proxy(x,mx);return x}function d(x){if(x instanceof IDBRequest)return z9(x);if(Fx.has(x))return Fx.get(x);let w=W9(x);if(w!==x)Fx.set(x,w),r.set(w,x);return w}var hx=(x)=>r.get(x);function $1(x,w,{blocked:y,upgrade:$,blocking:Q,terminated:Z}={}){let b=indexedDB.open(x,w),W=d(b);if($)b.addEventListener("upgradeneeded",(z)=>{$(d(b.result),z.oldVersion,z.newVersion,d(b.transaction),z)});if(y)b.addEventListener("blocked",(z)=>y(z.oldVersion,z.newVersion,z));return W.then((z)=>{if(Z)z.addEventListener("close",()=>Z());if(Q)z.addEventListener("versionchange",(Y)=>Q(Y.oldVersion,Y.newVersion,Y))}).catch(()=>{}),W}function Q1(x,{blocked:w}={}){let y=indexedDB.deleteDatabase(x);if(w)y.addEventListener("blocked",($)=>w($.oldVersion,$));return d(y).then(()=>{return})}var j9=["get","getKey","getAll","getAllKeys","count"],K9=["put","add","delete","clear"],Px=/*@__PURE__*/new Map;function ex(x,w){if(!(x instanceof IDBDatabase&&!(w in x)&&typeof w==="string"))return;if(Px.get(w))return Px.get(w);let y=w.replace(/FromIndex$/,""),$=w!==y,Q=K9.includes(y);if(!(y in($?IDBIndex:IDBObjectStore).prototype)||!(Q||j9.includes(y)))return;let Z=async function(b,...W){let z=this.transaction(b,Q?"readwrite":"readonly"),Y=z.store;if($)Y=Y.index(W.shift());return(await Promise.all([Y[y](...W),Q&&z.done]))[0]};return Px.set(w,Z),Z}y1((x)=>({...x,get:(w,y,$)=>ex(w,y)||x.get(w,y,$),has:(w,y)=>!!ex(w,y)||x.has(w,y)}));var J9=["continue","continuePrimaryKey","advance"],x1={},Ex=/*@__PURE__*/new WeakMap,Z1=/*@__PURE__*/new WeakMap,H9={get(x,w){if(!J9.includes(w))return x[w];let y=x1[w];if(!y)y=x1[w]=function(...$){Ex.set(this,Z1.get(this)[w](...$))};return y}};async function*q9(...x){let w=this;if(!(w instanceof IDBCursor))w=await w.openCursor(...x);if(!w)return;w=w;let y=new Proxy(w,H9);Z1.set(y,w),r.set(y,hx(w));while(w)yield y,w=await(Ex.get(y)||w.continue()),Ex.delete(y)}function w1(x,w){return w===Symbol.asyncIterator&&Lx(x,[IDBIndex,IDBObjectStore,IDBCursor])||w==="iterate"&&Lx(x,[IDBIndex,IDBObjectStore])}y1((x)=>({...x,get(w,y,$){if(w1(w,y))return q9;return x.get(w,y,$)},has(w,y){return w1(w,y)||x.has(w,y)}}));var h={SPFXEXT:"SPFXEXT_",SPFXEXT_CORE:"SPFXEXT"};function k9(){return Object.keys(localStorage).some((x)=>x.indexOf(h.SPFXEXT)>-1&&Number(localStorage[x])>0)}function b1(x){return x.hostname.toLowerCase()==="localhost"}function V1(x){return Number(localStorage.getItem(`${h.SPFXEXT}${x}`))>0}var L=k9();var J={AppFolderManifestCache:"AppFolderManifestCache",AppCollectionManifestCache:"AppCollectionManifestCache",AllowedApps:"AllowedApps",HubSiteData:"HubSiteData",SPFxExtensionConfig:"SPFxExtensionConfig"},z1=`${h.SPFXEXT}COREDB`,B1=$1(z1,1,{blocking(x,w,y){G.close(),alert("A new version of this page is ready. Please reload the page.")},async upgrade(x,w,y,$,Q){if(w===0)x.createObjectStore(J.AppFolderManifestCache,{keyPath:"url"}),x.createObjectStore(J.AppCollectionManifestCache,{keyPath:"url"}),x.createObjectStore(J.AllowedApps,{keyPath:"Id"}),x.createObjectStore(J.HubSiteData,{keyPath:"SiteId"}),x.createObjectStore(J.SPFxExtensionConfig,{keyPath:"Title"})}});B1.catch((x)=>{throw V("Error opening database for Core, please contact your administrator."),Q1(z1).then(()=>{window.location.reload()}),x});var G=await B1;function N(x){let w=/*@__PURE__*/new Date;return w.setMinutes(w.getMinutes()+x),{expires:w.toISOString()}}async function o(x,w){let y=await G.getAll(x),$=/*@__PURE__*/new Date,Q=y.filter((b)=>{let W=new Date(b.expires);return $>=W}),Z=Q.length;if(Z>0){let b=G.transaction(x,"readwrite"),W=b.objectStore(x);Q.forEach((z)=>W.delete(z[w])),await b.done,O(`Evicted ${Z} items from ${x} cache.`)}return Z}async function Ax(){return await o(J.SPFxExtensionConfig,"Title"),G.getAll(J.SPFxExtensionConfig)}async function S(x){return await o(J.SPFxExtensionConfig,"Title"),G.get(J.SPFxExtensionConfig,x)}async function n(x,w=60){await G.put(J.SPFxExtensionConfig,{...x,...N(w)})}function Y1(x,w){let y=G.transaction(J.SPFxExtensionConfig,"readwrite"),$=y.objectStore(J.SPFxExtensionConfig);return x.forEach((Q)=>$.put({...Q,...N(w)})),y.done}async function W1(){return G.getAll(J.AllowedApps)}async function dx(x){return G.get(J.AppFolderManifestCache,x)}async function Sx(x){return G.get(J.AppCollectionManifestCache,x)}async function j1(x){return G.get(J.HubSiteData,x)}async function K1(x,w=60){await G.put(J.HubSiteData,{...x,...N(w)})}async function D9(x,w=60){await G.put(J.AppCollectionManifestCache,{...x,...N(w)})}async function G9(x,w=60){await G.put(J.AppFolderManifestCache,{...x,...N(w)})}async function J1(x,w=5){let y=N(w),$=G.transaction(J.AllowedApps,"readwrite"),Q=$.objectStore(J.AllowedApps);return x.forEach((Z)=>Q.put({...y,...Z})),$.done}function O9(x){return G.delete(J.AppCollectionManifestCache,x)}function X9(x){return G.delete(J.AppFolderManifestCache,x)}async function _9(){return o(J.AppCollectionManifestCache,"url")}async function R9(){return o(J.AppFolderManifestCache,"url")}async function H1(){return o(J.AllowedApps,"Id")}async function q1(){return o(J.HubSiteData,"SiteId")}async function e(x){if(x){let w=await dx(x.url);if(w){if(w.hash!==x.hash)await X9(x.url),O(`Evicted ${m} ${w.url} from cache. Because of hash mismatch.`)}}return R9()}async function xx(x){if(x){let w=await Sx(x.url);if(w){if(w.hash!==x.hash)await O9(x.url),O(`Evicted ${X} ${w.url} from cache. Because of hash mismatch.`)}}return _9()}async function k1(x){if(await e(),L)return;return dx(x)}async function D1(x,w){await e(x);let y=await dx(x.url);if(y&&y.hash===x.hash&&!L)return;await G9(x,w)}async function G1(x,w){await xx(x);let y=await Sx(x.url);if(y&&y.hash===x.hash&&!L)return;await D9(x,w)}async function O1(x){if(await xx(),L)return;return Sx(x)}async function X1(x){let w=await fetch(`${x}/_api/contextinfo`,{method:"POST",headers:{Accept:"application/json;odata=verbose","Content-Type":"application/json"}});if(w.status===200)return(await w.json()).d.GetContextWebInformation.FormDigestValue;else V("Error while getting digest",w.status);return""}var Mx=(x)=>{},wx;async function T(x=""){if(wx)return wx;wx=new Promise((w)=>{Mx=w});try{let $=(await(await fetch(`${x}/_api/SP_TenantSettings_Current`,{headers:{Accept:"application/json;odata=verbose"}})).json()).d.CorporateCatalogUrl;Mx($)}catch(w){V("Error while getting app catalog url. Trying default /sites/appcatalog",w);let y=`${window.location.origin}/sites/appcatalog`;Mx(y)}return wx}async function F9(x=""){let w=await S("AppCatalogUrl");if(w?.Data)return w.Data;let y=await T(x);return await n({Title:"AppCatalogUrl",Data:y,date:"",expires:""},240),y}async function E(x=""){let y=`${await T()}${x?`/${x}`:""}`;return X1(y)}var P9=await F9(),H=`${P9}/${_}`;var R1={Status:"Status",RootCDNLocation:"RootCDNLocation",InterceptHistory:"InterceptHistory",EnableAppWhiteList:"EnableAppWhiteList",AppCatalogUrl:"AppCatalogUrl",AppCatalogWebs:"AppCatalogWebs",ConfiguratorPageData:"ConfiguratorPageData",AppWhiteList:"AppWhiteList",Version:"2025-04-25T11:07:28.675Z"},_1=[{Title:"Status",Data:"Installed"},{Title:"InterceptHistory",Data:"true"},{Title:"EnableAppWhiteList",Data:"false"},{Title:"RootCDNLocation",Data:`/sites/appcatalog/${_}`}];function F1(x){let w=_1.find((y)=>y.Title==="RootCDNLocation");if(w)w.Data=x;return _1}var L9=Object.keys(R1).length,$x=await E(_),yx;async function n9(){let x=`${H}/_api/web/lists/GetByTitle('${v}')/fields`;try{let w=await fetch(x,{headers:{Accept:"application/json;odata=verbose"}});if(w.status===200){let $=(await w.json()).d.results,Q=$.map((b)=>b.InternalName),Z=$.find((b)=>b.InternalName==="Title");if(!Z){V("Title field not found.");return}if(!Z.EnforceUniqueValues)if((await fetch(`${H}/_api/web/lists/GetByTitle('${v}')/fields('${Z.Id}')`,{method:"POST",headers:{Accept:"application/json;odata=verbose","Content-Type":"application/json;odata=verbose","X-RequestDigest":$x,"X-HTTP-Method":"MERGE","If-Match":"*"},body:JSON.stringify({__metadata:{type:"SP.Field"},Indexed:!0,EnforceUniqueValues:!0})})).status===204)j("Title field updated successfully.");else V("Unable to update Title field.");if(!Q.includes("Data"))if((await fetch(x,{method:"POST",headers:{Accept:"application/json;odata=verbose","Content-Type":"application/json;odata=verbose","X-RequestDigest":$x},body:JSON.stringify({__metadata:{type:"SP.Field"},Title:"Data",FieldTypeKind:2,Required:!0})})).status===201)j("Data field added successfully.");else V("Unable to add Data field.")}}catch(w){V("Error while ensuring configuration list data fields.",w)}}async function m9(){let x=!1;try{if(x=(await fetch(`${H}/_api/web/lists/GetByTitle('${v}')`)).status===404,x)if(j("Creating configuration list."),(await fetch(`${H}/_api/web/lists`,{method:"POST",headers:{Accept:"application/json;odata=verbose","Content-Type":"application/json;odata=verbose","X-RequestDigest":$x},body:JSON.stringify({__metadata:{type:"SP.List"},BaseTemplate:100,Title:"SPFxExtensionsConfiguration",Description:"Configuration list for SPFxExtensions"})})).status===201)j("Configuration list created successfully.");else V("Unable to create configuration list.");await n9()}catch(w){V("Error while ensuring configuration list.",w)}return x}async function P1(){let x=`${H}/_api/web/lists/GetByTitle('${v}')/items?$select=Title,Data`,y=await fetch(x,{...{headers:{Accept:"application/json;odata=verbose"}}});if(y.status!==200)return V("Unable to fetch configuration list items."),[];return(await y.json()).d.results}async function h9(){for(let x of F1(H))if((await fetch(`${H}/_api/web/lists/GetByTitle('${v}')/items`,{method:"POST",headers:{Accept:"application/json;odata=verbose","Content-Type":"application/json;odata=verbose","X-RequestDigest":$x},body:JSON.stringify({__metadata:{type:"SP.Data.SPFxExtensionsConfigurationListItem"},...x})})).status===201)j(`Item ${x.Title} added successfully.`);else V(`Unable to add item ${x.Title}.`)}function L1(x=!1){if(x)return P1();if(yx)return yx;return yx=E9(),yx}async function E9(){let x=await Ax();if(x.length<L9){if(await m9())await h9();let y=await P1();await Y1(y,240),x=await Ax()}return x}async function A9(x){let w=await T(),y=await E(),$=await fetch(`${w}/_api/web/webs/add`,{method:"POST",headers:{Accept:"application/json;odata=nometadata","Content-Type":"application/json","X-RequestDigest":y},body:JSON.stringify({parameters:{Description:"Site that stores SPFxExtensions Data and global apps",Language:1033,Title:"SPFxExtensions Data",Url:x,UseSamePermissionsAsParentSite:!0,WebTemplate:"STS"}})});if(!$.ok)throw new Error(`Failed to create SPFxExtensionsData web in ${w}`);return await $.json()}async function d9(){let x=await T(),w=await E(),y=await fetch(`${x}/_api/web/webs`,{method:"GET",headers:{Accept:"application/json;odata=nometadata","X-RequestDigest":w}});if(!y.ok)throw new Error(`Failed to fetch data from ${x}/_api/web/webs`);return(await y.json()).value}async function S9(){return(await S("AppCatalogWebs"))?.Data??[]}var Qx;async function n1(){if(Qx)return Qx;return Qx=M9(),Qx}async function M9(){let x=await S9();if(!x.some((y)=>y.ServerRelativeUrl.endsWith(_))){let y=await d9();if(!y.some((Q)=>Q.ServerRelativeUrl.endsWith(_))){let Q=await A9(_);y.push(Q),await n({Title:"AppCatalogWebs",Data:y,date:"",expires:""},240)}return y}return x}var vx="f3ab710f-2c08-422e-a7ad-5d93eb51e7a3",v9=await E(_),Zx={accept:"application/json"},Ux={"X-RequestDigest":v9},U9={"Content-Type":"application/json"};async function g9(){return(await(await fetch(`${H}/_api/sitepages/pages`,{headers:{...Zx,...Ux,...U9},body:JSON.stringify({PageLayoutType:"SingleWebPartAppPage",PromotedState:0}),method:"POST"})).json()).Id}async function gx(){let x=await fetch(`${H}/_api/sitepages/pages/GetByUrl('${t}')`,{headers:{...Zx},method:"GET"});if(x.status===404)return;return await x.json()}var f9=[{dataVersion:"1.4",description:"Title Region Description",id:"cbe7b0a9-3504-44dd-a3a3-0e5cacd07788",instanceId:"cbe7b0a9-3504-44dd-a3a3-0e5cacd07788",properties:{authorByline:[],authors:[],layoutType:"FullWidthImage",showPublishDate:!1,showTopicHeader:!1,textAlignment:"Left",title:"SPFx Extensions Configurator",topicHeader:"",enableGradientEffect:!0},reservedHeight:280,serverProcessedContent:{htmlStrings:{},searchablePlainTexts:{},imageSources:{},links:{}},title:"Title area"}],C9=[{addedFromPersistedData:!1,controlType:3,displayMode:2,emphasis:{},id:vx,position:{controlIndex:1,layoutIndex:1,sectionFactor:12,sectionIndex:1,zoneIndex:1},reservedHeight:500,reservedWidth:500,webPartData:{dataVersion:"1.0",description:"Allows you to add a custom developed app",id:qx,instanceId:vx,properties:{description:"Select an app to load from the dropdown below",selectedApp:A,SPFxExtensionAppConfiguration:void 0},title:"SPFx Extension Loader"},webPartId:qx},{controlType:0,pageSettingsSlice:{isDefaultDescription:!0,isDefaultThumbnail:!0}}],N9={CanvasContent1:`${JSON.stringify(C9)}`,LayoutWebpartsContent:`${JSON.stringify(f9)}`,Title:px};async function m1(x){await fetch(`${H}/_api/sitepages/pages(${x})/savepage`,{headers:{"Content-Type":"application/json",...Zx,...Ux},body:JSON.stringify(N9),method:"POST"}),await fetch(`${H}/_api/sitepages/pages(${x})/publish`,{headers:{...Zx,...Ux},method:"POST"})}async function o9(){let x=await g9();return await m1(x),gx()}async function I9(){let x=await S("ConfiguratorPageData");if(x?.Data)return x.Data;let w=await gx();if(w)await n({Title:"ConfiguratorPageData",Data:w,date:"",expires:""},480);return w}async function h1(){let x=await I9();if(!x)return o9();if(x.CanvasContent1.indexOf(vx)===-1){await m1(x.Id);let w=await gx();return await n({Title:"ConfiguratorPageData",Data:w,date:"",expires:""},480),w}return x}var E1=await E(_);async function u9(){let x=`${H}/_api/web/lists/GetByTitle('${U}')/fields`;try{let w=await fetch(x,{headers:{Accept:"application/json;odata=verbose"}});if(w.status===200){if(!(await w.json()).d.results.map((Z)=>Z.InternalName).some((Z)=>Z==="EntryPointUrl"))await T9(x,"EntryPointUrl","Full URL to the Entrypoint JS file, if * is specified all entries will be allowed.",!0)}}catch(w){V("Error while ensuring list fields.",w)}}async function T9(x,w,y,$){if((await fetch(x,{method:"POST",headers:{Accept:"application/json;odata=verbose","Content-Type":"application/json;odata=verbose","X-RequestDigest":E1},body:JSON.stringify({__metadata:{type:"SP.Field"},Title:w,FieldTypeKind:3,Required:$,Description:y})})).status===201)j(w,"field added successfully.");else V(w,"Unable to add field.")}async function c9(){try{let x=await fetch(`${H}/_api/web/lists/GetByTitle('${U}')?$select=*`,{method:"GET",headers:{Accept:"application/json;odata=verbose"}});if(x.status===404){j("Creating app white list.");let y=await fetch(`${H}/_api/web/lists`,{method:"POST",headers:{Accept:"application/json;odata=verbose","Content-Type":"application/json;odata=verbose","X-RequestDigest":E1},body:JSON.stringify({__metadata:{type:"SP.List"},BaseTemplate:100,Title:U,Description:"App whitelist for SPFxExtensions"})});if(y.status===201)return j("App whitelist created successfully."),y.json();else{V("Unable to create app whitelist.");return}}return await u9(),x.json()}catch(x){V("Error while ensuring app whitelist.",x)}return}async function A1(){let x=await S("AppWhiteList");if(x?.Data)return x.Data;let w=await c9();if(w)await n({Title:"AppWhiteList",Data:w,date:"",expires:""},480);return w}var bx;async function fx(){if(bx)return bx;return bx=p9(),bx}async function p9(){await n1(),await A1(),await h1(),window.__SPFxExtensions.Utils.ConfiguratorPageUrl=`${H}/${t}`}async function M(x=!1){return await fx(),L1(x)}async function d1(){return`${`${(await M()).find(($)=>$.Title==="RootCDNLocation")?.Data??`${H}`}${g}`}${X}`}async function S1(){let x=await M(),w=["spfxextensions","ff36e5d0-f7c7-421d-9e21-0a422626209a"];if(x.find((y)=>y.Title==="Version")?.Data!=="2025-04-25T11:07:28.675Z"){x=await M(!0),n({Title:"Version",Data:"2025-04-25T11:07:28.675Z",date:"",expires:""},240);let y=await caches.keys(),$=!1;for(let Q of y){let Z=await caches.open(Q),b=await Z.keys(),W=[];for(let z of b){let Y=z.url.toLowerCase();if(w.some((F)=>Y.indexOf(F)>-1))K("Deleting cache key",z),$=!0,W.push(Z.delete(z,{ignoreMethod:!0,ignoreSearch:!0}))}await Promise.allSettled(W)}if($)window.location.reload()}}function m0(){return C(`${Date.now()}`,13)}var t9=s9();async function s9(){try{let x=await H1(),w=await W1();if(w.length>0&&!x)return w;if(w.length>0)j("Cache mismatch, loading allowed apps data...");let y=await M1();return await J1(y,5),y}catch(x){return V("Unable to load allowed apps data...",x),[]}}async function M1(x=!1){if((await M(x)).find(($)=>$.Title==="EnableAppWhiteList")?.Data!=="true")return[{Id:1,Title:"All apps allowed",EntryPointUrl:"*",date:(/*@__PURE__*/new Date()).toISOString(),expires:(/*@__PURE__*/new Date()).toISOString()}];return i9()}async function i9(){let x=`${H}/_api/web/lists/getByTitle('${U}')/Items?$select=Id,Title,EntryPointUrl&$top=1000`;return await l9(x)}async function l9(x){let w=x,y=[];while(w){let Q=await(await fetch(w,{method:"GET",headers:{Accept:"application/json;odata=verbose"}})).json();if(Q.error)throw new Error(JSON.stringify(Q.error));y.push(...Q.d.results),w=Q.d.__next}return y}function a9(x,w){if(w.some((Q)=>Q.EntryPointUrl==="*"))return!0;let $=(x.origin+x.pathname).toLowerCase();return w.some((Q)=>{try{let Z=new URL(Q.EntryPointUrl),b=Z.origin+Z.pathname;return $===b.toLowerCase()}catch(Z){return V("Error while parsing allowed entry URL",Q.EntryPointUrl,Z),!1}})}async function v1(x,w,y=!1){if(b1(x))return!0;let $=y?await M1(y):await t9;if(!a9(x,$))return O("File",x,`is not allowed to be executed. Please add it to whitelist @ ${H}.`),O(`If you are a developer you can enable this app by adding localStorage item ${h.SPFXEXT}${w} with a number value corresponding to development port of the localhost server.`),!1;return!0}async function g0(){if(window.moduleLoaderPromise)return(await window.moduleLoaderPromise)?.context;console.error("Unable to retrieve Modern SP Context...")}async function U1(){if(window.moduleLoaderPromise){let x=await window.moduleLoaderPromise;if(x?.context?.pageContext)return{contextType:"SPOModernContext",context:x.context.pageContext};throw"It seems this is a modern page, however it was not possible to retrieve SP Context..."}if(window._spPageContextInfo)return{contextType:"ClassicContext",context:window._spPageContextInfo};throw"It was not possible to retrieve SP Context either through modern or through classic means..."}var k=await U1();function g1(){return k.contextType==="SPOModernContext"?k.context.web.id.toString():_x(k.context.webId)}function Cx(){return(k.contextType==="SPOModernContext"?k.context.web.absoluteUrl:k.context.webAbsoluteUrl).replace(/\/$/,"")}function Vx(){return k.contextType==="SPOModernContext"?k.context.site.id.toString():_x(k.context.siteId)}function c(){return k.contextType==="SPOModernContext"?k.context.site.absoluteUrl:k.context.siteAbsoluteUrl}function zx(){return(k.contextType==="SPOModernContext"?k.context.legacyPageContext.hubSiteId?.toString():k.context.hubSiteId)??s}function f1(){return k.contextType==="SPOModernContext"?k.context.legacyPageContext.isHubSite:k.context.isHubSite}function r9(x){if(!Array.isArray(x.enabledAppCollections))throw`${P} ${X} enabledAppCollections should be an array`;if(!Array.isArray(x.urlMap))throw`${P} ${X} urlMap should be an array`}async function Bx(x,w,y,$,Q=!1,Z=60){let b=Gx,W=x.toLowerCase();if(!Q&&!L){let q=await O1(W);if(q)return q.isHubFetch=$,q}let z=`${W}?v=${Date.now()}`;try{K(`Fetching ${X} from`,z);let I=await(await fetch(z)).text();b=JSON.parse(I)}catch(q){O(`Unable to fetch ${X} from`,z,q)}try{r9(b)}catch(q){V(`Error while parsing ${X} from`,z,q),b=Gx}let Y=await C(JSON.stringify(b)),R={manifest:b,...{name:w,url:W,type:y,hash:Y}};return await G1(R,L?1:Z),R.isHubFetch=$,R}async function Yx(x,w,y,$=!1){let Q=[],Z=await d1();Q.push(Bx(Z,"apps","root",!0,$));let b=x+g;if(Q.push(Bx(`${b}${X}`,"apps","site",!1,$)),y){let q=y+g;Q.push(Bx(`${q}${X}`,"apps","site",!0,$))}let z=`${w+g}${X}`,Y=x.toLowerCase()===w.toLowerCase(),F=z.toLowerCase()===Z.toLowerCase();if(!Y&&!F)Q.push(Bx(z,"apps","web",!1,$));return await Promise.all(Q)}function e9(x){if(Array.isArray(x)||typeof x!=="object")throw`${P} App manifest has to be an object.`;if(!x.appRelativeEntryPointUrls)throw V("Manifest does not have appRelativeEntryPointUrl property.",x),`${P} Manifest does not have appRelativeEntryPointUrl property.`;if(!x.appDefinitionMap)throw V("Manifest does not have enabledApps property.",x),`${P} Manifest does not have enabledApps property.`}async function xw(x,w,y,$,Q=!1,Z=60){let b={...Dx},W=x.toLowerCase();if(!Q&&!L){let q=await k1(W);if(q)return q.isHubFetch=$,q}let z=`${W}?v=${Date.now()}`;try{K(`Fetching ${m} from`,z);let I=await(await fetch(z)).text();b=JSON.parse(I)}catch(q){O(`Unable to fetch ${m} from`,z,q)}try{e9(b)}catch(q){V(`Error while parsing ${m} from`,z,q),b={...Dx}}let Y=await C(JSON.stringify(b)),R={manifest:b,...{name:w,url:W,type:y,hash:Y}};return await D1(R,L?1:Z),R.isHubFetch=$,R}function ww(x,w){let y=`${x}${w}/${m}`,$=`${h.SPFXEXT}${w}`,Q=Number(localStorage.getItem($));if(Q>0){let Z=`https://localhost:${Q}/${m}`;return j(`<${w}> App is in debug mode, loading from`,Z),Z}return y}function Nx(x,w=!1){if(x.length===0)return[];let y=[];for(let $ of x){let Q=$.url.toLowerCase().replace(X.toLowerCase(),"");for(let Z of $.manifest.enabledAppCollections){let b=ww(Q,Z);y.push(xw(b,Z,$.type,$.isHubFetch??!1,w))}}return y}function Wx(x,w=!1){let y=x.filter((Y)=>Y.type==="root"),$=Nx(y,w),Q=x.filter((Y)=>Y.type==="site"),Z=Nx(Q,w),b=x.filter((Y)=>Y.type==="web"),W=Nx(b,w);return[...$,...Z,...W]}var Ix=!1,jx=[];async function yw(x,w,y){if(!y.isESM){let $=y.appDefinitionMap.find((Z)=>Z.appId===w);if(!$){let Z=`Could not find app configuration item for non-ESM app ${w}`;return V(Z),[]}if(!C1($))return j(`App ${w} is not enabled in current context. Skipping...`),[];try{O("Non-ESM module detected. Make sure to call window.__SPFxExtensions.RegisterApp and window.__SPFxExtensions.InstantiateApp in code.",x),await import(x)}catch(Z){let b=`Error while importing or executing ${x} ${Z}`;return V(b),[]}return[]}else try{let Q=(await import(x)).default;if(!Q)return V(`No default export found in ${x}, only ESM modules are supported.`),[];return Zw(Q,y,x)}catch($){return V("Error while importing or executing",x,$),[]}}async function ox(x){let w=[],y=x.url.replace(m,"");K("Parsing",x.type,"manifest:",x.manifest);for(let $ of x.manifest.appRelativeEntryPointUrls){let Q=$.replace(/\.\.\/?/g,"./").replace(/^\.\//,""),Z=`${y}${Q}`.toLowerCase();K("EntryPoint JS: ",Z);let b=new URL(Z);if(x.manifest.cacheString&&x.manifest.enableCaching){let R=V1(x.name)?`${(/*@__PURE__*/new Date()).getTime()}`:x.manifest.cacheString;b.searchParams.set("v",`${R}`)}if(!await v1(b,x.name))continue;let z=`${b.origin}${b.pathname}`,Y=`${b}`;if(jx.includes(z)){j("EntryPoint already loaded:",Y);continue}jx.push(z),w.push(yw(Y,$,x.manifest))}return w}async function ux(x,w,y,$,Q=!1){if(Q)$w($);if(Ix)return;Ix=!0;let Z=await Yx(x,w,y),b=Wx(Z);window.__SPFxExtensions.Utils.appManifestPromises=b,window.__SPFxExtensions.Utils.spAppInitializationPromiseResolver();let z=(await Promise.allSettled(b)).filter((D)=>D.status==="fulfilled"),Y=[],F=z.filter((D)=>D.value.type==="root"),R=z.filter((D)=>D.value.type==="site"),q=z.filter((D)=>D.value.type==="web");for(let D of F){let u=await ox(D.value);Y.push(...u)}K("Root apps loaded.");for(let D of R){let u=await ox(D.value);Y.push(...u)}K("Site apps loaded.");for(let D of q){let u=await ox(D.value);Y.push(...u)}K("SiteWeb apps loaded.");let I=(await Promise.allSettled(Y)).filter((D)=>D.status==="fulfilled").flatMap((D)=>D.value);await Qw(I),window.__SPFxExtensions.AllAppAssetsLoadedResolver(),j("SPFx Extensions Core Components Loaded.")}function $w(x){Ix=!1,jx.splice(0,jx.length),sx(x);let{promise:w,resolve:y}=Promise.withResolvers();window.__SPFxExtensions.AllAppAssetsLoadedPromise=w,window.__SPFxExtensions.AllAppAssetsLoadedResolver=y}async function Qw(x){for(let w of window.__SPFxExtensions.Apps)if(!x.find(($)=>$.id===w.id)&&w.id!==A){if(await window.__SPFxExtensions.UnregisterApp(w.id))O(`Unregistered App ${w.id} (${w.name}) as it does not belong in this context`)}}async function Zw(x,w,y){if(!Array.isArray(x))V("Default export of entry point should be an array of App definitions. TODO: add documentation url",y);let $=[];for(let Q of x){if(!Q.id){V("App definition does not have an id. Make sure that returned array is in proper format. TODO: add documentation url",y,Q);continue}let Z=w.appDefinitionMap.find((Y)=>Y.appId.toLowerCase()===Q.id.toLowerCase()),b=`App with id ${Q.id} (${Q.name}) is not enabled for current web. Skipping...`;if(!Z){j(b);continue}if(!C1(Z)){j(b);continue}let z=await window.__SPFxExtensions.RegisterApp(Q);if($.push(Q),!Q.isWebPartApp&&Q.autoExecute){if(z.instances.length<(Q.maxInstances??1/0))window.__SPFxExtensions.InstantiateApp(Q.id,{})}}return $}function C1(x){let w=g1().toLowerCase(),y=Vx().toLowerCase(),$=zx().toLowerCase();return x.config.enabledEverywhere?x.config.excludedIds.indexOf(w)===-1&&x.config.excludedIds.indexOf(y)===-1&&x.config.excludedHubIds.indexOf($)===-1:!0}var N1=!1;function I1(){if(window.moduleLoaderPromise&&!N1)N1=!0,window.moduleLoaderPromise.then((x)=>{let w=x.context.pageContext.initialize;x.context.pageContext.initialize=function(y,$){let Q=x.context.pageContext._initializationData;w.call(this,y,$);let Z={initializationData:y,legacyContext:$};if(Q.web.id===y.web.id){o1("contextRefresh",Z);return}o1("contextChange",Z)}})}function o1(x,w){let y=new CustomEvent(x,{detail:w});window.dispatchEvent(y),window.__SPFxExtensions.Apps.forEach(($)=>{$.instances.forEach((Q)=>{Q.executeListeners(x,w)})})}function u1(){if(!window.__SPFxExtensions.AppEventListeners)window.__SPFxExtensions.AppEventListeners=[];if(!window.__SPFxExtensions.AddAppEventListener)window.__SPFxExtensions.AddAppEventListener=(x,w)=>{let y={key:window.crypto.randomUUID(),eventName:x,handler:w};return window.__SPFxExtensions.AppEventListeners.push(y),y};if(!window.__SPFxExtensions.RemoveAppEventListener)window.__SPFxExtensions.RemoveAppEventListener=(x)=>{let w=window.__SPFxExtensions.AppEventListeners.findIndex((y)=>y.key===x.key);if(w>-1)window.__SPFxExtensions.AppEventListeners.splice(w,1)}}var bw=window.history.pushState,Vw=window.history.replaceState,zw=window.history.back,Bw=window.history.forward,Yw=window.history.go;function Ww(){let x=window.history.state,w=window.location.href;return{currentState:x,previousUrl:w}}function p(x,w){let y={...Ww(),...w},$=new CustomEvent(x,{detail:y});window.dispatchEvent($)}function jw(){function x(w,y,$){bw.call(this,w,y,$),p("historyPush",{newState:w,newUrl:$})}window.history.pushState=x}function Kw(){function x(w,y,$){Vw.call(this,w,y,$),p("historyReplace",{newState:w,newUrl:$})}window.history.replaceState=x}function Jw(){function x(){zw.call(this),p("historyBack",{})}window.history.back=x}function Hw(){function x(){Bw.call(this),p("historyForward",{})}window.history.forward=x}function qw(){function x(w){Yw.call(this,w),p("historyGo",{delta:w})}window.history.go=x}var T1=!1;function c1(){if(T1)return;T1=!0,Kw(),jw(),Hw(),Jw(),qw()}async function Tx(){if(f1())return"";let x=zx(),w=Vx();if(!x||x===s||x===w)return"";await q1();let y=await j1(x);if(!y){let $=c();j("Getting Hub data for HubSiteId:",x);try{let Z=await(await fetch(`${$}/_api/hubsites/GetById?hubSiteId='${x}'`,{headers:{accept:"application/json;odata=nometadata"}})).json();return await K1(Z),Z.SiteUrl}catch(Q){return V("Error fetching hub site data.",Q),""}}return y.SiteUrl}var p1="CORE_MANIFEST_CHECK",s1=Number(localStorage.getItem(h.SPFXEXT_CORE))>0?1e5:60000,Kx=0;function cx(x,w,y,$=!1){if($)window.clearInterval(Kx),Kx=0;if(Kx>0)return;Kx=window.setInterval(t1,s1,x,w,y),t1(x,w,y)}async function t1(x,w,y){try{let Q=localStorage.getItem(p1);if(Q){let W=new Date(Q),Y=(/*@__PURE__*/new Date()).getTime()-W.getTime(),F=s1-2000;if(Y<F){K("Manifest check already performed recently, skipping.",`${Y} < ${F}`);return}}j("Checking for manifest updates across all locations..."),await Promise.all([xx(),e()]);let Z=await Yx(x,w,y,!0),b=Wx(Z,!0);await Promise.allSettled(b)}catch(Q){V("Error checking for manifest updates",Q)}let $=(/*@__PURE__*/new Date()).toISOString();K("Setting next manifest check to",$),localStorage.setItem(p1,$)}var Jx;async function kw(){if(Jx)return Jx;return Jx=Dw(),Jx}async function Dw(){if(await fx(),(await M()).find((Q)=>Q.Title==="InterceptHistory")?.Data==="true")c1();I1(),u1(),ix(),lx();let{promise:y,resolve:$}=Promise.withResolvers();if(!window.__SPFxExtensions.AllAppAssetsLoadedPromise)window.__SPFxExtensions.AllAppAssetsLoadedPromise=y,window.__SPFxExtensions.AllAppAssetsLoadedResolver=$}async function i1(){await S1(),await kw(),window.__SPFxExtensions.__CorePromiseResolver?.();let x=c(),w=Cx(),y=await Tx();await ux(x,w,y,l()),window.addEventListener("contextChange",async()=>{j("Context changed, reloading apps...");let $=c(),Q=Cx(),Z=await Tx(),b=tx();await ux($,Q,Z,b,!0),cx($,Q,Z,!0)}),cx(x,w,y),j("SPFx Extensions Core Has Been initialized.")}var Gw={id:A,description:"Allows configuring custom apps",isWebPartApp:!1,hideAppSelectorWhenAppLoaded:!0,hideConfiguratorButton:!0,name:"SPFx Extensions Configurator",async onInstanceRequested(x){let w=import.meta.url.indexOf("localhost")>-1;if(w)K("Core is in debug mode");let y=w?import.meta.resolve(`./__spfxCoreConfigurator.js?v=${Date.now()}`):window.__SPFxExtensions.__ConfiguratorUrl;try{return(await import(y)).launch(x)}catch($){if(V("Error launching configurator app",$),x.domElement)x.domElement.innerHTML=`<div style="text-align: center; padding: 20px; color: red;">Error launching configurator app. ${$}</div>`;return()=>{}}}};async function Ow(){j("Initializing Core Services Built:","2025-04-25T11:07:28.675Z"),await i1();try{await window.__SPFxExtensions.RegisterApp(Gw)}catch(w){V("Error registering configurator app",w)}}Ow();
1
+ var __create = Object.create;
2
+ var __getProtoOf = Object.getPrototypeOf;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __toESM = (mod, isNodeMode, target) => {
7
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
8
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
9
+ for (let key of __getOwnPropNames(mod))
10
+ if (!__hasOwnProp.call(to, key))
11
+ __defProp(to, key, {
12
+ get: () => mod[key],
13
+ enumerable: true
14
+ });
15
+ return to;
16
+ };
17
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
18
+ var __export = (target, all) => {
19
+ for (var name in all)
20
+ __defProp(target, name, {
21
+ get: all[name],
22
+ enumerable: true,
23
+ configurable: true,
24
+ set: (newValue) => all[name] = () => newValue
25
+ });
26
+ };
27
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
28
+
29
+ // src/utilities/constants.ts
30
+ var SPFX_WEBPART_ID = "d6ca1fc2-0591-4c6d-8a25-cae3262c017b";
31
+ var CONFIGURATOR_APP_ID = "45e75137-13c5-4bb2-a2b3-8ab6382682ee";
32
+ var CONFIGURATOR_PAGE_NAME = "SPFxExtensionsConfigurator";
33
+ var CONFIGURATOR_PAGE_URL = `SitePages/${CONFIGURATOR_PAGE_NAME}.aspx`;
34
+ var MANIFEST_NAME = "manifest.txt";
35
+ var APPCOLLECTION_MANIFEST_NAME = "collectionconfig.txt";
36
+ var APP_LOADING = "Loading...";
37
+ var CONFIGURATION_LIST_NAME = "SPFxExtensionsConfiguration";
38
+ var ALLOWEDAPPSLIST_NAME = "SPFxExtensionsWhiteList";
39
+ var SPFX_EXTENSIONS_FOLDER = "SPFxExtensions";
40
+ var WELL_KNOWN_MANIFEST_LOCATION = `/${SPFX_EXTENSIONS_FOLDER}/`;
41
+ var SPFX_EXTENSIONS_DATA_SITE = "SPFxExtensionsData";
42
+ var SPFxExtensionCore = "[SPFxExtensionCore]";
43
+ var EMPTY_APP_MANIFEST = {
44
+ appDefinitionMap: [],
45
+ appRelativeEntryPointUrls: [],
46
+ isESM: true
47
+ };
48
+ var EMPTY_APP_DEF_ITEM_CONFIG = {
49
+ enabledEverywhere: false,
50
+ excludedHubIds: [],
51
+ excludedIds: [],
52
+ includedHubIds: [],
53
+ includedIds: []
54
+ };
55
+ var EMPTY_COLLECTION_MANIFEST = {
56
+ enabledAppCollections: [],
57
+ urlMap: []
58
+ };
59
+ var EMPTY_GUID = "00000000-0000-0000-0000-000000000000";
60
+
61
+ // src/core/utility/colors.ts
62
+ function formatter(open, close, replace = open) {
63
+ return (input) => {
64
+ const string = "" + input, index = string.indexOf(close, open.length);
65
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
66
+ };
67
+ }
68
+ function replaceClose(string, close, replace, index) {
69
+ let result = "", cursor = 0;
70
+ do {
71
+ result += string.substring(cursor, index) + replace;
72
+ cursor = index + close.length;
73
+ index = string.indexOf(close, cursor);
74
+ } while (~index);
75
+ return result + string.substring(cursor);
76
+ }
77
+ var reset = formatter("\x1B[0m", "\x1B[0m");
78
+ var bold = formatter("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m");
79
+ var dim = formatter("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m");
80
+ var italic = formatter("\x1B[3m", "\x1B[23m");
81
+ var underline = formatter("\x1B[4m", "\x1B[24m");
82
+ var inverse = formatter("\x1B[7m", "\x1B[27m");
83
+ var hidden = formatter("\x1B[8m", "\x1B[28m");
84
+ var strikethrough = formatter("\x1B[9m", "\x1B[29m");
85
+ var black = formatter("\x1B[30m", "\x1B[39m");
86
+ var red = formatter("\x1B[31m", "\x1B[39m");
87
+ var green = formatter("\x1B[32m", "\x1B[39m");
88
+ var yellow = formatter("\x1B[33m", "\x1B[39m");
89
+ var blue = formatter("\x1B[34m", "\x1B[39m");
90
+ var magenta = formatter("\x1B[35m", "\x1B[39m");
91
+ var cyan = formatter("\x1B[36m", "\x1B[39m");
92
+ var white = formatter("\x1B[37m", "\x1B[39m");
93
+ var gray = formatter("\x1B[90m", "\x1B[39m");
94
+ var bgBlack = formatter("\x1B[40m", "\x1B[49m");
95
+ var bgRed = formatter("\x1B[41m", "\x1B[49m");
96
+ var bgGreen = formatter("\x1B[42m", "\x1B[49m");
97
+ var bgYellow = formatter("\x1B[43m", "\x1B[49m");
98
+ var bgBlue = formatter("\x1B[44m", "\x1B[49m");
99
+ var bgMagenta = formatter("\x1B[45m", "\x1B[49m");
100
+ var bgCyan = formatter("\x1B[46m", "\x1B[49m");
101
+ var bgWhite = formatter("\x1B[47m", "\x1B[49m");
102
+ var blackBright = formatter("\x1B[90m", "\x1B[39m");
103
+ var redBright = formatter("\x1B[91m", "\x1B[39m");
104
+ var greenBright = formatter("\x1B[92m", "\x1B[39m");
105
+ var yellowBright = formatter("\x1B[93m", "\x1B[39m");
106
+ var blueBright = formatter("\x1B[94m", "\x1B[39m");
107
+ var magentaBright = formatter("\x1B[95m", "\x1B[39m");
108
+ var cyanBright = formatter("\x1B[96m", "\x1B[39m");
109
+ var whiteBright = formatter("\x1B[97m", "\x1B[39m");
110
+ var bgBlackBright = formatter("\x1B[100m", "\x1B[49m");
111
+ var bgRedBright = formatter("\x1B[101m", "\x1B[49m");
112
+ var bgGreenBright = formatter("\x1B[102m", "\x1B[49m");
113
+ var bgYellowBright = formatter("\x1B[103m", "\x1B[49m");
114
+ var bgBlueBright = formatter("\x1B[104m", "\x1B[49m");
115
+ var bgMagentaBright = formatter("\x1B[105m", "\x1B[49m");
116
+ var bgCyanBright = formatter("\x1B[106m", "\x1B[49m");
117
+ var bgWhiteBright = formatter("\x1B[107m", "\x1B[49m");
118
+
119
+ // src/core/services/loggingService.ts
120
+ function logGenericCoreError(...args) {
121
+ console.error(greenBright(SPFxExtensionCore), new Date().toISOString(), ...args);
122
+ }
123
+ function logGenericCoreWarning(...args) {
124
+ console.warn(greenBright(SPFxExtensionCore), new Date().toISOString(), ...args);
125
+ }
126
+ function logGenericCoreInfo(...args) {
127
+ console.info(greenBright(SPFxExtensionCore), new Date().toISOString(), ...args);
128
+ }
129
+ function logGenericCoreDebug(...args) {}
130
+ function logInstanceRequestedError(app, e, additionalData) {
131
+ logGenericCoreError("Error while executing onInstanceRequested for app", app.id, "with name", app.name, additionalData ? `Additional Data: ${additionalData}` : "", e);
132
+ }
133
+
134
+ // src/utilities/helpers.ts
135
+ function emptyDummy() {
136
+ logGenericCoreWarning("The app instance event was called before app instance was initialized.");
137
+ return () => {};
138
+ }
139
+ var currentContext = window.crypto.randomUUID();
140
+ function getCurrentContextId() {
141
+ return currentContext;
142
+ }
143
+ function getNewContext() {
144
+ currentContext = window.crypto.randomUUID();
145
+ return currentContext;
146
+ }
147
+ function extractGUIDFromString(str) {
148
+ return str.replace("{", "").replace("}", "");
149
+ }
150
+ function cloneObject(obj) {
151
+ return JSON.parse(JSON.stringify(obj));
152
+ }
153
+
154
+ // src/core/services/appServices.ts
155
+ function unmountAppInstance(appDef, instanceKey, userCleanupFunc) {
156
+ const idx = appDef.instances.findIndex((i) => i.key === instanceKey);
157
+ if (idx > -1) {
158
+ const splicedInstance = appDef.instances.splice(idx, 1);
159
+ if (splicedInstance.length < 1)
160
+ return;
161
+ const instance = splicedInstance[0];
162
+ instance.executeListeners("onConfigurationClose", undefined);
163
+ instance.allEventListeners.splice(0, instance.allEventListeners.length);
164
+ userCleanupFunc?.();
165
+ }
166
+ }
167
+ async function unmountInstancesOnContextChange(contextId) {
168
+ const instancesToUnmount = window.__SPFxExtensions.Apps.filter((a) => !a.isWebPartApp && !a.keepOnContextChange && a.id !== CONFIGURATOR_APP_ID);
169
+ for (const alreadyRegisteredApp of instancesToUnmount) {
170
+ logGenericCoreDebug(alreadyRegisteredApp, `---Unmounting on context change`);
171
+ for (const appInstance of alreadyRegisteredApp.instances.filter((i) => i.contextId !== contextId)) {
172
+ appInstance.unmount();
173
+ }
174
+ }
175
+ }
176
+ function loadAppInstance(foundApp, appInstance) {
177
+ if (appInstance.hasBeenRequested)
178
+ return;
179
+ try {
180
+ appInstance.hasBeenRequested = true;
181
+ foundApp.onInstanceRequested(appInstance).then((userCleanupFunc) => {
182
+ appInstance.unmount = () => {
183
+ unmountAppInstance(foundApp, appInstance.key, userCleanupFunc);
184
+ };
185
+ appInstance.instanceLoadPromiseResolver();
186
+ }).catch((e) => {
187
+ logInstanceRequestedError(foundApp, e);
188
+ });
189
+ } catch (e) {
190
+ logInstanceRequestedError(foundApp, e);
191
+ }
192
+ }
193
+
194
+ // src/core/services/appDefinitionService.ts
195
+ function executeAppAddedEvents(appDef) {
196
+ logGenericCoreDebug(`Executing appAdded event for`, appDef.id);
197
+ window.__SPFxExtensions.AppEventListeners.filter((l) => l.eventName === "appAdded").forEach((listener) => {
198
+ try {
199
+ listener.handler(appDef);
200
+ } catch (e) {
201
+ logGenericCoreError("Error executing appAdded event", e);
202
+ }
203
+ });
204
+ }
205
+ function ensureApp(appId) {
206
+ let foundApp = window.__SPFxExtensions.Apps.find((a) => a.id === appId);
207
+ if (!foundApp) {
208
+ logGenericCoreDebug(`Registering new app`, appId);
209
+ foundApp = {
210
+ id: appId,
211
+ name: APP_LOADING,
212
+ description: APP_LOADING,
213
+ isWebPartApp: false,
214
+ keepOnContextChange: false,
215
+ autoExecute: false,
216
+ maxInstances: Infinity,
217
+ hideAppSelectorWhenAppLoaded: false,
218
+ hideConfiguratorButton: false,
219
+ registrationCompleted: false,
220
+ instances: [],
221
+ async onInstanceRequested() {
222
+ return emptyDummy;
223
+ }
224
+ };
225
+ window.__SPFxExtensions.Apps.push(foundApp);
226
+ }
227
+ return foundApp;
228
+ }
229
+ function registerAppService() {
230
+ if (!window.__SPFxExtensions.Apps) {
231
+ window.__SPFxExtensions.Apps = [];
232
+ }
233
+ if (!window.__SPFxExtensions.RegisterApp) {
234
+ window.__SPFxExtensions.RegisterApp = async (newAppDefinition) => {
235
+ const appDefinition = ensureApp(newAppDefinition.id);
236
+ if (appDefinition.registrationCompleted) {
237
+ return appDefinition;
238
+ }
239
+ appDefinition.registrationCompleted = true;
240
+ appDefinition.name = newAppDefinition.name;
241
+ appDefinition.description = newAppDefinition.description;
242
+ appDefinition.isWebPartApp = newAppDefinition.isWebPartApp;
243
+ appDefinition.keepOnContextChange = newAppDefinition.keepOnContextChange ?? false;
244
+ appDefinition.autoExecute = newAppDefinition.autoExecute ?? false;
245
+ appDefinition.maxInstances = newAppDefinition.maxInstances ?? Infinity;
246
+ appDefinition.hideAppSelectorWhenAppLoaded = newAppDefinition.hideAppSelectorWhenAppLoaded ?? false;
247
+ appDefinition.hideConfiguratorButton = newAppDefinition.hideConfiguratorButton ?? false;
248
+ appDefinition.icon = newAppDefinition.icon;
249
+ appDefinition.onInstanceRequested = newAppDefinition.onInstanceRequested;
250
+ executeAppAddedEvents(appDefinition);
251
+ appDefinition.instances.forEach((appInstance) => {
252
+ loadAppInstance(appDefinition, appInstance);
253
+ });
254
+ return appDefinition;
255
+ };
256
+ }
257
+ if (!window.__SPFxExtensions.UnregisterApp) {
258
+ window.__SPFxExtensions.UnregisterApp = async (appId) => {
259
+ const appDefinitionIdx = window.__SPFxExtensions.Apps.findIndex((a) => a.id === appId);
260
+ if (appDefinitionIdx < 0) {
261
+ return;
262
+ }
263
+ const appDefinition = window.__SPFxExtensions.Apps.splice(appDefinitionIdx, 1);
264
+ if (appDefinition.length < 1) {
265
+ return;
266
+ }
267
+ logGenericCoreDebug(`Unregistering app`, appDefinition[0].id, appDefinition[0].name);
268
+ appDefinition[0].instances.forEach((appInstance) => {
269
+ appInstance.unmount();
270
+ });
271
+ return appDefinition[0];
272
+ };
273
+ }
274
+ }
275
+
276
+ // src/core/services/appInstanceService.ts
277
+ function registerEventHandlers(appInstance) {
278
+ const removeInstanceEventListener = (eventListener) => {
279
+ const idx = appInstance.allEventListeners.findIndex((el) => el.key === eventListener.key);
280
+ if (idx > -1) {
281
+ logGenericCoreDebug("Removing event listener", eventListener);
282
+ appInstance.allEventListeners.splice(idx, 1);
283
+ }
284
+ };
285
+ const addInstanceEventListener = (eventName, callback) => {
286
+ const eventListener = {
287
+ key: window.crypto.randomUUID(),
288
+ eventName,
289
+ handler: callback
290
+ };
291
+ appInstance.allEventListeners.push(eventListener);
292
+ return () => {
293
+ removeInstanceEventListener(eventListener);
294
+ };
295
+ };
296
+ const executeInstanceListeners = (eventName, eventData) => {
297
+ for (const eventListener of appInstance.allEventListeners) {
298
+ if (eventListener.eventName != eventName)
299
+ continue;
300
+ if (eventListener.handler)
301
+ eventListener.handler(eventData);
302
+ }
303
+ };
304
+ appInstance.addEventListener = addInstanceEventListener;
305
+ appInstance.executeListeners = executeInstanceListeners;
306
+ }
307
+ function executeInstanceAddedListeners(appDefinition, appInstance) {
308
+ logGenericCoreDebug(`Executing instanceAdded event for app`, appDefinition.id, "instance", appInstance.key);
309
+ window.__SPFxExtensions.AppEventListeners.filter((l) => l.eventName === "instanceAdded").forEach((listener) => {
310
+ try {
311
+ listener.handler({ app: appDefinition, instance: appInstance });
312
+ } catch (e) {
313
+ logGenericCoreError("Error executing instanceAdded event", e);
314
+ }
315
+ });
316
+ }
317
+ function createAppInstance(runTimeConfig) {
318
+ const { promise: instanceLoadPromise, resolve: instanceLoadPromiseResolver } = Promise.withResolvers();
319
+ const appInstance = {
320
+ ...runTimeConfig,
321
+ key: window.crypto.randomUUID(),
322
+ contextId: getCurrentContextId(),
323
+ hasBeenRequested: false,
324
+ unmount: emptyDummy,
325
+ allEventListeners: [],
326
+ addEventListener: emptyDummy,
327
+ executeListeners: emptyDummy,
328
+ instanceLoadPromise,
329
+ instanceLoadPromiseResolver
330
+ };
331
+ registerEventHandlers(appInstance);
332
+ return appInstance;
333
+ }
334
+ function registerAppInstanceService() {
335
+ if (!window.__SPFxExtensions.InstantiateApp) {
336
+ window.__SPFxExtensions.InstantiateApp = async (appId, runTimeConfig) => {
337
+ const foundApp = ensureApp(appId);
338
+ logGenericCoreDebug(`Creating app instance for app`, appId);
339
+ const appInstance = createAppInstance(runTimeConfig);
340
+ foundApp.instances.push(appInstance);
341
+ executeInstanceAddedListeners(foundApp, appInstance);
342
+ if (foundApp.registrationCompleted) {
343
+ loadAppInstance(foundApp, appInstance);
344
+ }
345
+ return appInstance;
346
+ };
347
+ }
348
+ }
349
+
350
+ // src/utilities/digest.ts
351
+ async function getContentDigest(content, limit = 0) {
352
+ const encoder = new TextEncoder;
353
+ const data = encoder.encode(content);
354
+ const hash = await window.crypto.subtle.digest("SHA-1", data);
355
+ const hashArray = Array.from(new Uint8Array(hash));
356
+ const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
357
+ return limit > 0 ? hashHex.substring(0, limit) : hashHex;
358
+ }
359
+
360
+ // node_modules/idb/build/index.js
361
+ var instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);
362
+ var idbProxyableTypes;
363
+ var cursorAdvanceMethods;
364
+ function getIdbProxyableTypes() {
365
+ return idbProxyableTypes || (idbProxyableTypes = [
366
+ IDBDatabase,
367
+ IDBObjectStore,
368
+ IDBIndex,
369
+ IDBCursor,
370
+ IDBTransaction
371
+ ]);
372
+ }
373
+ function getCursorAdvanceMethods() {
374
+ return cursorAdvanceMethods || (cursorAdvanceMethods = [
375
+ IDBCursor.prototype.advance,
376
+ IDBCursor.prototype.continue,
377
+ IDBCursor.prototype.continuePrimaryKey
378
+ ]);
379
+ }
380
+ var transactionDoneMap = new WeakMap;
381
+ var transformCache = new WeakMap;
382
+ var reverseTransformCache = new WeakMap;
383
+ function promisifyRequest(request) {
384
+ const promise = new Promise((resolve, reject) => {
385
+ const unlisten = () => {
386
+ request.removeEventListener("success", success);
387
+ request.removeEventListener("error", error);
388
+ };
389
+ const success = () => {
390
+ resolve(wrap(request.result));
391
+ unlisten();
392
+ };
393
+ const error = () => {
394
+ reject(request.error);
395
+ unlisten();
396
+ };
397
+ request.addEventListener("success", success);
398
+ request.addEventListener("error", error);
399
+ });
400
+ reverseTransformCache.set(promise, request);
401
+ return promise;
402
+ }
403
+ function cacheDonePromiseForTransaction(tx) {
404
+ if (transactionDoneMap.has(tx))
405
+ return;
406
+ const done = new Promise((resolve, reject) => {
407
+ const unlisten = () => {
408
+ tx.removeEventListener("complete", complete);
409
+ tx.removeEventListener("error", error);
410
+ tx.removeEventListener("abort", error);
411
+ };
412
+ const complete = () => {
413
+ resolve();
414
+ unlisten();
415
+ };
416
+ const error = () => {
417
+ reject(tx.error || new DOMException("AbortError", "AbortError"));
418
+ unlisten();
419
+ };
420
+ tx.addEventListener("complete", complete);
421
+ tx.addEventListener("error", error);
422
+ tx.addEventListener("abort", error);
423
+ });
424
+ transactionDoneMap.set(tx, done);
425
+ }
426
+ var idbProxyTraps = {
427
+ get(target, prop, receiver) {
428
+ if (target instanceof IDBTransaction) {
429
+ if (prop === "done")
430
+ return transactionDoneMap.get(target);
431
+ if (prop === "store") {
432
+ return receiver.objectStoreNames[1] ? undefined : receiver.objectStore(receiver.objectStoreNames[0]);
433
+ }
434
+ }
435
+ return wrap(target[prop]);
436
+ },
437
+ set(target, prop, value) {
438
+ target[prop] = value;
439
+ return true;
440
+ },
441
+ has(target, prop) {
442
+ if (target instanceof IDBTransaction && (prop === "done" || prop === "store")) {
443
+ return true;
444
+ }
445
+ return prop in target;
446
+ }
447
+ };
448
+ function replaceTraps(callback) {
449
+ idbProxyTraps = callback(idbProxyTraps);
450
+ }
451
+ function wrapFunction(func) {
452
+ if (getCursorAdvanceMethods().includes(func)) {
453
+ return function(...args) {
454
+ func.apply(unwrap(this), args);
455
+ return wrap(this.request);
456
+ };
457
+ }
458
+ return function(...args) {
459
+ return wrap(func.apply(unwrap(this), args));
460
+ };
461
+ }
462
+ function transformCachableValue(value) {
463
+ if (typeof value === "function")
464
+ return wrapFunction(value);
465
+ if (value instanceof IDBTransaction)
466
+ cacheDonePromiseForTransaction(value);
467
+ if (instanceOfAny(value, getIdbProxyableTypes()))
468
+ return new Proxy(value, idbProxyTraps);
469
+ return value;
470
+ }
471
+ function wrap(value) {
472
+ if (value instanceof IDBRequest)
473
+ return promisifyRequest(value);
474
+ if (transformCache.has(value))
475
+ return transformCache.get(value);
476
+ const newValue = transformCachableValue(value);
477
+ if (newValue !== value) {
478
+ transformCache.set(value, newValue);
479
+ reverseTransformCache.set(newValue, value);
480
+ }
481
+ return newValue;
482
+ }
483
+ var unwrap = (value) => reverseTransformCache.get(value);
484
+ function openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) {
485
+ const request = indexedDB.open(name, version);
486
+ const openPromise = wrap(request);
487
+ if (upgrade) {
488
+ request.addEventListener("upgradeneeded", (event) => {
489
+ upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);
490
+ });
491
+ }
492
+ if (blocked) {
493
+ request.addEventListener("blocked", (event) => blocked(event.oldVersion, event.newVersion, event));
494
+ }
495
+ openPromise.then((db) => {
496
+ if (terminated)
497
+ db.addEventListener("close", () => terminated());
498
+ if (blocking) {
499
+ db.addEventListener("versionchange", (event) => blocking(event.oldVersion, event.newVersion, event));
500
+ }
501
+ }).catch(() => {});
502
+ return openPromise;
503
+ }
504
+ function deleteDB(name, { blocked } = {}) {
505
+ const request = indexedDB.deleteDatabase(name);
506
+ if (blocked) {
507
+ request.addEventListener("blocked", (event) => blocked(event.oldVersion, event));
508
+ }
509
+ return wrap(request).then(() => {
510
+ return;
511
+ });
512
+ }
513
+ var readMethods = ["get", "getKey", "getAll", "getAllKeys", "count"];
514
+ var writeMethods = ["put", "add", "delete", "clear"];
515
+ var cachedMethods = new Map;
516
+ function getMethod(target, prop) {
517
+ if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === "string")) {
518
+ return;
519
+ }
520
+ if (cachedMethods.get(prop))
521
+ return cachedMethods.get(prop);
522
+ const targetFuncName = prop.replace(/FromIndex$/, "");
523
+ const useIndex = prop !== targetFuncName;
524
+ const isWrite = writeMethods.includes(targetFuncName);
525
+ if (!(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) {
526
+ return;
527
+ }
528
+ const method = async function(storeName, ...args) {
529
+ const tx = this.transaction(storeName, isWrite ? "readwrite" : "readonly");
530
+ let target2 = tx.store;
531
+ if (useIndex)
532
+ target2 = target2.index(args.shift());
533
+ return (await Promise.all([
534
+ target2[targetFuncName](...args),
535
+ isWrite && tx.done
536
+ ]))[0];
537
+ };
538
+ cachedMethods.set(prop, method);
539
+ return method;
540
+ }
541
+ replaceTraps((oldTraps) => ({
542
+ ...oldTraps,
543
+ get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
544
+ has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)
545
+ }));
546
+ var advanceMethodProps = ["continue", "continuePrimaryKey", "advance"];
547
+ var methodMap = {};
548
+ var advanceResults = new WeakMap;
549
+ var ittrProxiedCursorToOriginalProxy = new WeakMap;
550
+ var cursorIteratorTraps = {
551
+ get(target, prop) {
552
+ if (!advanceMethodProps.includes(prop))
553
+ return target[prop];
554
+ let cachedFunc = methodMap[prop];
555
+ if (!cachedFunc) {
556
+ cachedFunc = methodMap[prop] = function(...args) {
557
+ advanceResults.set(this, ittrProxiedCursorToOriginalProxy.get(this)[prop](...args));
558
+ };
559
+ }
560
+ return cachedFunc;
561
+ }
562
+ };
563
+ async function* iterate(...args) {
564
+ let cursor = this;
565
+ if (!(cursor instanceof IDBCursor)) {
566
+ cursor = await cursor.openCursor(...args);
567
+ }
568
+ if (!cursor)
569
+ return;
570
+ cursor = cursor;
571
+ const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
572
+ ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
573
+ reverseTransformCache.set(proxiedCursor, unwrap(cursor));
574
+ while (cursor) {
575
+ yield proxiedCursor;
576
+ cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
577
+ advanceResults.delete(proxiedCursor);
578
+ }
579
+ }
580
+ function isIteratorProp(target, prop) {
581
+ return prop === Symbol.asyncIterator && instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor]) || prop === "iterate" && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
582
+ }
583
+ replaceTraps((oldTraps) => ({
584
+ ...oldTraps,
585
+ get(target, prop, receiver) {
586
+ if (isIteratorProp(target, prop))
587
+ return iterate;
588
+ return oldTraps.get(target, prop, receiver);
589
+ },
590
+ has(target, prop) {
591
+ return isIteratorProp(target, prop) || oldTraps.has(target, prop);
592
+ }
593
+ }));
594
+
595
+ // src/utilities/debug.ts
596
+ var DEBUG_KEYS = {
597
+ SPFXEXT: "SPFXEXT_",
598
+ SPFXEXT_CORE: "SPFXEXT"
599
+ };
600
+ function inDebug() {
601
+ return Object.keys(localStorage).some((k) => k.indexOf(DEBUG_KEYS.SPFXEXT) > -1 && Number(localStorage[k]) > 0);
602
+ }
603
+ function isFileInDebug(fullUrl) {
604
+ return fullUrl.hostname.toLowerCase() === "localhost";
605
+ }
606
+ function isAppInDebug(appName) {
607
+ return Number(localStorage.getItem(`${DEBUG_KEYS.SPFXEXT}${appName}`)) > 0;
608
+ }
609
+ var isInDebug = inDebug();
610
+
611
+ // src/core/services/coreIdbService.ts
612
+ var StoreNames = {
613
+ AppFolderManifestCache: "AppFolderManifestCache",
614
+ AppCollectionManifestCache: "AppCollectionManifestCache",
615
+ AllowedApps: "AllowedApps",
616
+ HubSiteData: "HubSiteData",
617
+ SPFxExtensionConfig: "SPFxExtensionConfig"
618
+ };
619
+ var DBNAME = `${DEBUG_KEYS.SPFXEXT}COREDB`;
620
+ var openDBPromise = openDB(DBNAME, 1, {
621
+ blocking(_currentVersion, _blockedVersion, _event) {
622
+ spfxExtensionsCoreDB.close();
623
+ alert("A new version of this page is ready. Please reload the page.");
624
+ },
625
+ async upgrade(database, oldVersion, _newVersion, _transaction, _event) {
626
+ if (oldVersion === 0) {
627
+ database.createObjectStore(StoreNames.AppFolderManifestCache, { keyPath: "url" });
628
+ database.createObjectStore(StoreNames.AppCollectionManifestCache, {
629
+ keyPath: "url"
630
+ });
631
+ database.createObjectStore(StoreNames.AllowedApps, { keyPath: "Id" });
632
+ database.createObjectStore(StoreNames.HubSiteData, { keyPath: "SiteId" });
633
+ database.createObjectStore(StoreNames.SPFxExtensionConfig, { keyPath: "Title" });
634
+ }
635
+ }
636
+ });
637
+ openDBPromise.catch((err) => {
638
+ logGenericCoreError("Error opening database for Core, please contact your administrator.");
639
+ deleteDB(DBNAME).then(() => {
640
+ window.location.reload();
641
+ });
642
+ throw err;
643
+ });
644
+ var spfxExtensionsCoreDB = await openDBPromise;
645
+ function getCacheItemBase(cacheTimeMinutes) {
646
+ const dateNow = new Date;
647
+ dateNow.setMinutes(dateNow.getMinutes() + cacheTimeMinutes);
648
+ const expires = dateNow.toISOString();
649
+ return {
650
+ expires
651
+ };
652
+ }
653
+ async function evictItemsFromStore(storeName, key) {
654
+ const cachedItems = await spfxExtensionsCoreDB.getAll(storeName);
655
+ const nowTime = new Date;
656
+ const cacheToRemove = cachedItems.filter((ci) => {
657
+ const itemExpires = new Date(ci.expires);
658
+ return nowTime >= itemExpires;
659
+ });
660
+ const toEvict = cacheToRemove.length;
661
+ if (toEvict > 0) {
662
+ const tx = spfxExtensionsCoreDB.transaction(storeName, "readwrite");
663
+ const txStore = tx.objectStore(storeName);
664
+ cacheToRemove.forEach((u) => txStore.delete(u[key]));
665
+ await tx.done;
666
+ logGenericCoreWarning(`Evicted ${toEvict} items from ${storeName} cache.`);
667
+ }
668
+ return toEvict;
669
+ }
670
+ async function getAllExtensionConfigFromDB() {
671
+ await evictItemsFromStore(StoreNames.SPFxExtensionConfig, "Title");
672
+ return spfxExtensionsCoreDB.getAll(StoreNames.SPFxExtensionConfig);
673
+ }
674
+ async function getExtensionConfigFromDB(title) {
675
+ await evictItemsFromStore(StoreNames.SPFxExtensionConfig, "Title");
676
+ return spfxExtensionsCoreDB.get(StoreNames.SPFxExtensionConfig, title);
677
+ }
678
+ async function addOrUpdateExtensionConfig(item, cacheTimeMinutes = 60) {
679
+ await spfxExtensionsCoreDB.put(StoreNames.SPFxExtensionConfig, {
680
+ ...item,
681
+ ...getCacheItemBase(cacheTimeMinutes)
682
+ });
683
+ }
684
+ function addOrUpdateExtensionConfigs(items, cacheTimeMinutes) {
685
+ const tx = spfxExtensionsCoreDB.transaction(StoreNames.SPFxExtensionConfig, "readwrite");
686
+ const txStore = tx.objectStore(StoreNames.SPFxExtensionConfig);
687
+ items.forEach((u) => txStore.put({ ...u, ...getCacheItemBase(cacheTimeMinutes) }));
688
+ return tx.done;
689
+ }
690
+ async function getAllAllowedAppsFromDB() {
691
+ return spfxExtensionsCoreDB.getAll(StoreNames.AllowedApps);
692
+ }
693
+ async function getManifestTXTCacheItem(url) {
694
+ return spfxExtensionsCoreDB.get(StoreNames.AppFolderManifestCache, url);
695
+ }
696
+ async function getAppsTXTCacheItem(url) {
697
+ return spfxExtensionsCoreDB.get(StoreNames.AppCollectionManifestCache, url);
698
+ }
699
+ async function getHubData(id) {
700
+ return spfxExtensionsCoreDB.get(StoreNames.HubSiteData, id);
701
+ }
702
+ async function addOrUpdateHubDataToCache(item, cacheTimeMinutes = 60) {
703
+ await spfxExtensionsCoreDB.put(StoreNames.HubSiteData, {
704
+ ...item,
705
+ ...getCacheItemBase(cacheTimeMinutes)
706
+ });
707
+ }
708
+ async function addOrUpdateAppsTXTToCache(item, cacheTimeMinutes = 60) {
709
+ await spfxExtensionsCoreDB.put(StoreNames.AppCollectionManifestCache, {
710
+ ...item,
711
+ ...getCacheItemBase(cacheTimeMinutes)
712
+ });
713
+ }
714
+ async function addOrUpdateManifestTXTToCache(item, cacheTimeMinutes = 60) {
715
+ await spfxExtensionsCoreDB.put(StoreNames.AppFolderManifestCache, {
716
+ ...item,
717
+ ...getCacheItemBase(cacheTimeMinutes)
718
+ });
719
+ }
720
+ async function addOrUpdateAllowedAppsToCache(items, cacheTimeMinutes = 5) {
721
+ const baseCache = getCacheItemBase(cacheTimeMinutes);
722
+ const tx = spfxExtensionsCoreDB.transaction(StoreNames.AllowedApps, "readwrite");
723
+ const txStore = tx.objectStore(StoreNames.AllowedApps);
724
+ items.forEach((item) => txStore.put({ ...baseCache, ...item }));
725
+ return tx.done;
726
+ }
727
+ function removeAppCollectionManifestFromCache(url) {
728
+ return spfxExtensionsCoreDB.delete(StoreNames.AppCollectionManifestCache, url);
729
+ }
730
+ function removeAppFolderManifestFromCache(url) {
731
+ return spfxExtensionsCoreDB.delete(StoreNames.AppFolderManifestCache, url);
732
+ }
733
+ async function evictAppCollectionCache() {
734
+ return evictItemsFromStore(StoreNames.AppCollectionManifestCache, "url");
735
+ }
736
+ async function evictManifestFolderCache() {
737
+ return evictItemsFromStore(StoreNames.AppFolderManifestCache, "url");
738
+ }
739
+ async function evictAllowedAppsCache() {
740
+ return evictItemsFromStore(StoreNames.AllowedApps, "Id");
741
+ }
742
+ async function evictHubDataCache() {
743
+ return evictItemsFromStore(StoreNames.HubSiteData, "SiteId");
744
+ }
745
+ async function evictManifestTXTCache(item) {
746
+ if (item) {
747
+ const matchingItem = await getManifestTXTCacheItem(item.url);
748
+ if (matchingItem) {
749
+ if (matchingItem.hash !== item.hash) {
750
+ await removeAppFolderManifestFromCache(item.url);
751
+ logGenericCoreWarning(`Evicted ${MANIFEST_NAME} ${matchingItem.url} from cache. Because of hash mismatch.`);
752
+ }
753
+ }
754
+ }
755
+ return evictManifestFolderCache();
756
+ }
757
+ async function evictAppsTXTCache(item) {
758
+ if (item) {
759
+ const matchingItem = await getAppsTXTCacheItem(item.url);
760
+ if (matchingItem) {
761
+ if (matchingItem.hash !== item.hash) {
762
+ await removeAppCollectionManifestFromCache(item.url);
763
+ logGenericCoreWarning(`Evicted ${APPCOLLECTION_MANIFEST_NAME} ${matchingItem.url} from cache. Because of hash mismatch.`);
764
+ }
765
+ }
766
+ }
767
+ return evictAppCollectionCache();
768
+ }
769
+ async function getManifestTXTFromCache(url) {
770
+ await evictManifestTXTCache();
771
+ if (isInDebug) {
772
+ return;
773
+ }
774
+ return getManifestTXTCacheItem(url);
775
+ }
776
+ async function setOrUpdateManifestTXT(retResult, cacheTimeMinutes) {
777
+ await evictManifestTXTCache(retResult);
778
+ const foundItem = await getManifestTXTCacheItem(retResult.url);
779
+ if (foundItem && foundItem.hash === retResult.hash && !isInDebug) {
780
+ return;
781
+ }
782
+ await addOrUpdateManifestTXTToCache(retResult, cacheTimeMinutes);
783
+ }
784
+ async function setOrUpdateAppCollectionTXT(retResult, cacheTimeMinutes) {
785
+ await evictAppsTXTCache(retResult);
786
+ const foundItem = await getAppsTXTCacheItem(retResult.url);
787
+ if (foundItem && foundItem.hash === retResult.hash && !isInDebug) {
788
+ return;
789
+ }
790
+ await addOrUpdateAppsTXTToCache(retResult, cacheTimeMinutes);
791
+ }
792
+ async function getAppCollectionTXTFromCache(url) {
793
+ await evictAppsTXTCache();
794
+ if (isInDebug) {
795
+ return;
796
+ }
797
+ return getAppsTXTCacheItem(url);
798
+ }
799
+
800
+ // src/core/services/digestService.ts
801
+ async function getDigest(webUrl) {
802
+ const req = await fetch(`${webUrl}/_api/contextinfo`, {
803
+ method: "POST",
804
+ headers: {
805
+ Accept: "application/json;odata=verbose",
806
+ "Content-Type": "application/json"
807
+ }
808
+ });
809
+ if (req.status === 200) {
810
+ const data = await req.json();
811
+ return data.d.GetContextWebInformation.FormDigestValue;
812
+ } else {
813
+ logGenericCoreError("Error while getting digest", req.status);
814
+ }
815
+ return "";
816
+ }
817
+
818
+ // src/core/services/appCatalogService.ts
819
+ var appCatalogPromiseResolver = (_data) => {};
820
+ var appCatalogUrlPromise;
821
+ async function getAppCatalogUrlFromAPI(baseUrl = "") {
822
+ if (appCatalogUrlPromise) {
823
+ return appCatalogUrlPromise;
824
+ }
825
+ appCatalogUrlPromise = new Promise((resolve) => {
826
+ appCatalogPromiseResolver = resolve;
827
+ });
828
+ try {
829
+ const apiResponse = await fetch(`${baseUrl}/_api/SP_TenantSettings_Current`, {
830
+ headers: {
831
+ Accept: "application/json;odata=verbose"
832
+ }
833
+ });
834
+ const responseData = await apiResponse.json();
835
+ const url = responseData.d.CorporateCatalogUrl;
836
+ appCatalogPromiseResolver(url);
837
+ } catch (err) {
838
+ logGenericCoreError("Error while getting app catalog url. Trying default /sites/appcatalog", err);
839
+ const fallBackUrl = `${window.location.origin}/sites/appcatalog`;
840
+ appCatalogPromiseResolver(fallBackUrl);
841
+ }
842
+ return appCatalogUrlPromise;
843
+ }
844
+ async function getAppCatalogUrlCached(baseUrl = "") {
845
+ const appCatalog = await getExtensionConfigFromDB("AppCatalogUrl");
846
+ if (appCatalog?.Data) {
847
+ return appCatalog.Data;
848
+ }
849
+ const url = await getAppCatalogUrlFromAPI(baseUrl);
850
+ await addOrUpdateExtensionConfig({ Title: "AppCatalogUrl", Data: url, date: "", expires: "" }, 240);
851
+ return url;
852
+ }
853
+ async function getAppCatalogDigest(catalogSubWeb = "") {
854
+ const appCatalogUrl = await getAppCatalogUrlFromAPI();
855
+ const url = `${appCatalogUrl}${catalogSubWeb ? `/${catalogSubWeb}` : ``}`;
856
+ return getDigest(url);
857
+ }
858
+ var APP_CATALOG_URL = await getAppCatalogUrlCached();
859
+ var SPFX_EXTENSIONS_SITE_URL = `${APP_CATALOG_URL}/${SPFX_EXTENSIONS_DATA_SITE}`;
860
+
861
+ // src/core/utility/defaultConfig.ts
862
+ var ConfigurationNames = {
863
+ Status: "Status",
864
+ RootCDNLocation: "RootCDNLocation",
865
+ InterceptHistory: "InterceptHistory",
866
+ EnableAppWhiteList: "EnableAppWhiteList",
867
+ AppCatalogUrl: "AppCatalogUrl",
868
+ AppCatalogWebs: "AppCatalogWebs",
869
+ ConfiguratorPageData: "ConfiguratorPageData",
870
+ AppWhiteList: "AppWhiteList",
871
+ Version: "2025-04-26T18:12:40.559Z"
872
+ };
873
+ var CoreDefaultConfiguration = [
874
+ {
875
+ Title: "Status",
876
+ Data: "Installed"
877
+ },
878
+ {
879
+ Title: "InterceptHistory",
880
+ Data: "true"
881
+ },
882
+ {
883
+ Title: "EnableAppWhiteList",
884
+ Data: "false"
885
+ },
886
+ {
887
+ Title: "RootCDNLocation",
888
+ Data: `/sites/appcatalog/${SPFX_EXTENSIONS_DATA_SITE}`
889
+ }
890
+ ];
891
+ function getCoreDefaultConfiguration(cdnLocationUrl) {
892
+ const cdnLoc = CoreDefaultConfiguration.find((c) => c.Title === "RootCDNLocation");
893
+ if (cdnLoc) {
894
+ cdnLoc.Data = cdnLocationUrl;
895
+ }
896
+ return CoreDefaultConfiguration;
897
+ }
898
+
899
+ // src/core/services/configurationListService.ts
900
+ var MINIMAL_CONFIG_COUNT = Object.keys(ConfigurationNames).length;
901
+ var appCatalogDigest = await getAppCatalogDigest(SPFX_EXTENSIONS_DATA_SITE);
902
+ var configurationListDataPromise;
903
+ async function ensureConfigurationListDataField() {
904
+ const fieldsUrl = `${SPFX_EXTENSIONS_SITE_URL}/_api/web/lists/GetByTitle('${CONFIGURATION_LIST_NAME}')/fields`;
905
+ try {
906
+ const req = await fetch(fieldsUrl, {
907
+ headers: {
908
+ Accept: "application/json;odata=verbose"
909
+ }
910
+ });
911
+ if (req.status === 200) {
912
+ const data = await req.json();
913
+ const fields = data.d.results;
914
+ const fieldNames = fields.map((f) => f.InternalName);
915
+ const titleField = fields.find((f) => f.InternalName === "Title");
916
+ if (!titleField) {
917
+ logGenericCoreError("Title field not found.");
918
+ return;
919
+ }
920
+ if (!titleField.EnforceUniqueValues) {
921
+ const updateFieldReq = await fetch(`${SPFX_EXTENSIONS_SITE_URL}/_api/web/lists/GetByTitle('${CONFIGURATION_LIST_NAME}')/fields('${titleField.Id}')`, {
922
+ method: "POST",
923
+ headers: {
924
+ Accept: "application/json;odata=verbose",
925
+ "Content-Type": "application/json;odata=verbose",
926
+ "X-RequestDigest": appCatalogDigest,
927
+ "X-HTTP-Method": "MERGE",
928
+ "If-Match": "*"
929
+ },
930
+ body: JSON.stringify({
931
+ __metadata: {
932
+ type: "SP.Field"
933
+ },
934
+ Indexed: true,
935
+ EnforceUniqueValues: true
936
+ })
937
+ });
938
+ if (updateFieldReq.status === 204) {
939
+ logGenericCoreInfo("Title field updated successfully.");
940
+ } else {
941
+ logGenericCoreError("Unable to update Title field.");
942
+ }
943
+ }
944
+ if (!fieldNames.includes("Data")) {
945
+ const addFieldReq = await fetch(fieldsUrl, {
946
+ method: "POST",
947
+ headers: {
948
+ Accept: "application/json;odata=verbose",
949
+ "Content-Type": "application/json;odata=verbose",
950
+ "X-RequestDigest": appCatalogDigest
951
+ },
952
+ body: JSON.stringify({
953
+ __metadata: {
954
+ type: "SP.Field"
955
+ },
956
+ Title: "Data",
957
+ FieldTypeKind: 2,
958
+ Required: true
959
+ })
960
+ });
961
+ if (addFieldReq.status === 201) {
962
+ logGenericCoreInfo("Data field added successfully.");
963
+ } else {
964
+ logGenericCoreError("Unable to add Data field.");
965
+ }
966
+ }
967
+ }
968
+ } catch (err) {
969
+ logGenericCoreError("Error while ensuring configuration list data fields.", err);
970
+ }
971
+ }
972
+ async function ensureConfigurationList() {
973
+ let newList = false;
974
+ try {
975
+ const req = await fetch(`${SPFX_EXTENSIONS_SITE_URL}/_api/web/lists/GetByTitle('${CONFIGURATION_LIST_NAME}')`);
976
+ newList = req.status === 404;
977
+ if (newList) {
978
+ logGenericCoreInfo("Creating configuration list.");
979
+ const createReq = await fetch(`${SPFX_EXTENSIONS_SITE_URL}/_api/web/lists`, {
980
+ method: "POST",
981
+ headers: {
982
+ Accept: "application/json;odata=verbose",
983
+ "Content-Type": "application/json;odata=verbose",
984
+ "X-RequestDigest": appCatalogDigest
985
+ },
986
+ body: JSON.stringify({
987
+ __metadata: {
988
+ type: "SP.List"
989
+ },
990
+ BaseTemplate: 100,
991
+ Title: "SPFxExtensionsConfiguration",
992
+ Description: "Configuration list for SPFxExtensions"
993
+ })
994
+ });
995
+ if (createReq.status === 201) {
996
+ logGenericCoreInfo("Configuration list created successfully.");
997
+ } else {
998
+ logGenericCoreError("Unable to create configuration list.");
999
+ }
1000
+ }
1001
+ await ensureConfigurationListDataField();
1002
+ } catch (err) {
1003
+ logGenericCoreError("Error while ensuring configuration list.", err);
1004
+ }
1005
+ return newList;
1006
+ }
1007
+ async function getConfigurationListItemsFromAPI() {
1008
+ const requestUrl = `${SPFX_EXTENSIONS_SITE_URL}/_api/web/lists/GetByTitle('${CONFIGURATION_LIST_NAME}')/items?$select=Title,Data`;
1009
+ const config = {
1010
+ headers: {
1011
+ Accept: "application/json;odata=verbose"
1012
+ }
1013
+ };
1014
+ const req = await fetch(requestUrl, {
1015
+ ...config
1016
+ });
1017
+ if (req.status !== 200) {
1018
+ logGenericCoreError("Unable to fetch configuration list items.");
1019
+ return [];
1020
+ }
1021
+ const data = await req.json();
1022
+ const results = data.d.results;
1023
+ return results;
1024
+ }
1025
+ async function createDefaultListItems() {
1026
+ for (const item of getCoreDefaultConfiguration(SPFX_EXTENSIONS_SITE_URL)) {
1027
+ const addReq = await fetch(`${SPFX_EXTENSIONS_SITE_URL}/_api/web/lists/GetByTitle('${CONFIGURATION_LIST_NAME}')/items`, {
1028
+ method: "POST",
1029
+ headers: {
1030
+ Accept: "application/json;odata=verbose",
1031
+ "Content-Type": "application/json;odata=verbose",
1032
+ "X-RequestDigest": appCatalogDigest
1033
+ },
1034
+ body: JSON.stringify({
1035
+ __metadata: {
1036
+ type: "SP.Data.SPFxExtensionsConfigurationListItem"
1037
+ },
1038
+ ...item
1039
+ })
1040
+ });
1041
+ if (addReq.status === 201) {
1042
+ logGenericCoreInfo(`Item ${item.Title} added successfully.`);
1043
+ } else {
1044
+ logGenericCoreError(`Unable to add item ${item.Title}.`);
1045
+ }
1046
+ }
1047
+ }
1048
+ function getConfigurationListData(fresh = false) {
1049
+ if (fresh) {
1050
+ return getConfigurationListItemsFromAPI();
1051
+ }
1052
+ if (configurationListDataPromise) {
1053
+ return configurationListDataPromise;
1054
+ }
1055
+ configurationListDataPromise = getConfigurationListDataCached();
1056
+ return configurationListDataPromise;
1057
+ }
1058
+ async function getConfigurationListDataCached() {
1059
+ let allConfig = await getAllExtensionConfigFromDB();
1060
+ if (allConfig.length < MINIMAL_CONFIG_COUNT) {
1061
+ const isNewList = await ensureConfigurationList();
1062
+ if (isNewList) {
1063
+ await createDefaultListItems();
1064
+ }
1065
+ const allListData = await getConfigurationListItemsFromAPI();
1066
+ await addOrUpdateExtensionConfigs(allListData, 240);
1067
+ allConfig = await getAllExtensionConfigFromDB();
1068
+ }
1069
+ return allConfig;
1070
+ }
1071
+
1072
+ // src/core/services/configurationWebService.ts
1073
+ async function createWeb(webUrl) {
1074
+ const appCatalog = await getAppCatalogUrlFromAPI();
1075
+ const appCatalogDigest2 = await getAppCatalogDigest();
1076
+ const response = await fetch(`${appCatalog}/_api/web/webs/add`, {
1077
+ method: "POST",
1078
+ headers: {
1079
+ Accept: "application/json;odata=nometadata",
1080
+ "Content-Type": "application/json",
1081
+ "X-RequestDigest": appCatalogDigest2
1082
+ },
1083
+ body: JSON.stringify({
1084
+ parameters: {
1085
+ Description: "Site that stores SPFxExtensions Data and global apps",
1086
+ Language: 1033,
1087
+ Title: "SPFxExtensions Data",
1088
+ Url: webUrl,
1089
+ UseSamePermissionsAsParentSite: true,
1090
+ WebTemplate: "STS"
1091
+ }
1092
+ })
1093
+ });
1094
+ if (!response.ok) {
1095
+ throw new Error(`Failed to create SPFxExtensionsData web in ${appCatalog}`);
1096
+ }
1097
+ const data = await response.json();
1098
+ return data;
1099
+ }
1100
+ async function getWebData() {
1101
+ const appCatalog = await getAppCatalogUrlFromAPI();
1102
+ const appCatalogDigest2 = await getAppCatalogDigest();
1103
+ const response = await fetch(`${appCatalog}/_api/web/webs`, {
1104
+ method: "GET",
1105
+ headers: {
1106
+ Accept: "application/json;odata=nometadata",
1107
+ "X-RequestDigest": appCatalogDigest2
1108
+ }
1109
+ });
1110
+ if (!response.ok) {
1111
+ throw new Error(`Failed to fetch data from ${appCatalog}/_api/web/webs`);
1112
+ }
1113
+ const data = await response.json();
1114
+ return data.value;
1115
+ }
1116
+ async function getWebDataCached() {
1117
+ const appCatalogWebs = await getExtensionConfigFromDB("AppCatalogWebs");
1118
+ return appCatalogWebs?.Data ?? [];
1119
+ }
1120
+ var ensureWebDataPromise;
1121
+ async function ensureSPFxWeb() {
1122
+ if (ensureWebDataPromise) {
1123
+ return ensureWebDataPromise;
1124
+ }
1125
+ ensureWebDataPromise = ensureWebDataInternal();
1126
+ return ensureWebDataPromise;
1127
+ }
1128
+ async function ensureWebDataInternal() {
1129
+ const webData = await getWebDataCached();
1130
+ const hasExtensionWeb = webData.some((web) => web.ServerRelativeUrl.endsWith(SPFX_EXTENSIONS_DATA_SITE));
1131
+ if (!hasExtensionWeb) {
1132
+ const apiData = await getWebData();
1133
+ const apiDataHasExtensionWeb = apiData.some((web) => web.ServerRelativeUrl.endsWith(SPFX_EXTENSIONS_DATA_SITE));
1134
+ if (!apiDataHasExtensionWeb) {
1135
+ const result = await createWeb(SPFX_EXTENSIONS_DATA_SITE);
1136
+ apiData.push(result);
1137
+ await addOrUpdateExtensionConfig({ Title: "AppCatalogWebs", Data: apiData, date: "", expires: "" }, 240);
1138
+ }
1139
+ return apiData;
1140
+ }
1141
+ return webData;
1142
+ }
1143
+
1144
+ // src/core/services/pageService.ts
1145
+ var CONFIGURATOR_APP_INSTANCEID = "f3ab710f-2c08-422e-a7ad-5d93eb51e7a3";
1146
+ var digest = await getAppCatalogDigest(SPFX_EXTENSIONS_DATA_SITE);
1147
+ var acceptHeader = { accept: "application/json" };
1148
+ var digestHeader = { "X-RequestDigest": digest };
1149
+ var contentType = { "Content-Type": "application/json" };
1150
+ async function createFullPage() {
1151
+ const response = await fetch(`${SPFX_EXTENSIONS_SITE_URL}/_api/sitepages/pages`, {
1152
+ headers: {
1153
+ ...acceptHeader,
1154
+ ...digestHeader,
1155
+ ...contentType
1156
+ },
1157
+ body: JSON.stringify({
1158
+ PageLayoutType: "SingleWebPartAppPage",
1159
+ PromotedState: 0
1160
+ }),
1161
+ method: "POST"
1162
+ });
1163
+ const data = await response.json();
1164
+ return data.Id;
1165
+ }
1166
+ async function getConfiguratorPageData() {
1167
+ const response = await fetch(`${SPFX_EXTENSIONS_SITE_URL}/_api/sitepages/pages/GetByUrl('${CONFIGURATOR_PAGE_URL}')`, {
1168
+ headers: {
1169
+ ...acceptHeader
1170
+ },
1171
+ method: "GET"
1172
+ });
1173
+ if (response.status === 404) {
1174
+ return;
1175
+ }
1176
+ const data = await response.json();
1177
+ return data;
1178
+ }
1179
+ var layout = [
1180
+ {
1181
+ dataVersion: "1.4",
1182
+ description: "Title Region Description",
1183
+ id: "cbe7b0a9-3504-44dd-a3a3-0e5cacd07788",
1184
+ instanceId: "cbe7b0a9-3504-44dd-a3a3-0e5cacd07788",
1185
+ properties: {
1186
+ authorByline: [],
1187
+ authors: [],
1188
+ layoutType: "FullWidthImage",
1189
+ showPublishDate: false,
1190
+ showTopicHeader: false,
1191
+ textAlignment: "Left",
1192
+ title: "SPFx Extensions Configurator",
1193
+ topicHeader: "",
1194
+ enableGradientEffect: true
1195
+ },
1196
+ reservedHeight: 280,
1197
+ serverProcessedContent: {
1198
+ htmlStrings: {},
1199
+ searchablePlainTexts: {},
1200
+ imageSources: {},
1201
+ links: {}
1202
+ },
1203
+ title: "Title area"
1204
+ }
1205
+ ];
1206
+ var canvas = [
1207
+ {
1208
+ addedFromPersistedData: false,
1209
+ controlType: 3,
1210
+ displayMode: 2,
1211
+ emphasis: {},
1212
+ id: CONFIGURATOR_APP_INSTANCEID,
1213
+ position: {
1214
+ controlIndex: 1,
1215
+ layoutIndex: 1,
1216
+ sectionFactor: 12,
1217
+ sectionIndex: 1,
1218
+ zoneIndex: 1
1219
+ },
1220
+ reservedHeight: 500,
1221
+ reservedWidth: 500,
1222
+ webPartData: {
1223
+ dataVersion: "1.0",
1224
+ description: "Allows you to add a custom developed app",
1225
+ id: SPFX_WEBPART_ID,
1226
+ instanceId: CONFIGURATOR_APP_INSTANCEID,
1227
+ properties: {
1228
+ description: "Select an app to load from the dropdown below",
1229
+ selectedApp: CONFIGURATOR_APP_ID,
1230
+ SPFxExtensionAppConfiguration: undefined
1231
+ },
1232
+ title: "SPFx Extension Loader"
1233
+ },
1234
+ webPartId: SPFX_WEBPART_ID
1235
+ },
1236
+ {
1237
+ controlType: 0,
1238
+ pageSettingsSlice: {
1239
+ isDefaultDescription: true,
1240
+ isDefaultThumbnail: true
1241
+ }
1242
+ }
1243
+ ];
1244
+ var save = {
1245
+ CanvasContent1: `${JSON.stringify(canvas)}`,
1246
+ LayoutWebpartsContent: `${JSON.stringify(layout)}`,
1247
+ Title: CONFIGURATOR_PAGE_NAME
1248
+ };
1249
+ async function setPageContent(pageId) {
1250
+ await fetch(`${SPFX_EXTENSIONS_SITE_URL}/_api/sitepages/pages(${pageId})/savepage`, {
1251
+ headers: {
1252
+ "Content-Type": "application/json",
1253
+ ...acceptHeader,
1254
+ ...digestHeader
1255
+ },
1256
+ body: JSON.stringify(save),
1257
+ method: "POST"
1258
+ });
1259
+ await fetch(`${SPFX_EXTENSIONS_SITE_URL}/_api/sitepages/pages(${pageId})/publish`, {
1260
+ headers: {
1261
+ ...acceptHeader,
1262
+ ...digestHeader
1263
+ },
1264
+ method: "POST"
1265
+ });
1266
+ }
1267
+ async function createConfiguratorPage() {
1268
+ const pageId = await createFullPage();
1269
+ await setPageContent(pageId);
1270
+ return getConfiguratorPageData();
1271
+ }
1272
+ async function getConfiguratorPageDataCached() {
1273
+ const cachedData = await getExtensionConfigFromDB("ConfiguratorPageData");
1274
+ if (cachedData?.Data) {
1275
+ return cachedData.Data;
1276
+ }
1277
+ const apiData = await getConfiguratorPageData();
1278
+ if (apiData) {
1279
+ await addOrUpdateExtensionConfig({ Title: "ConfiguratorPageData", Data: apiData, date: "", expires: "" }, 480);
1280
+ }
1281
+ return apiData;
1282
+ }
1283
+ async function ensureConfiguratorPage() {
1284
+ const data = await getConfiguratorPageDataCached();
1285
+ if (!data) {
1286
+ return createConfiguratorPage();
1287
+ }
1288
+ if (data.CanvasContent1.indexOf(CONFIGURATOR_APP_INSTANCEID) === -1) {
1289
+ await setPageContent(data.Id);
1290
+ const refreshData = await getConfiguratorPageData();
1291
+ await addOrUpdateExtensionConfig({ Title: "ConfiguratorPageData", Data: refreshData, date: "", expires: "" }, 480);
1292
+ return refreshData;
1293
+ }
1294
+ return data;
1295
+ }
1296
+
1297
+ // src/core/services/whiteListService.ts
1298
+ var digest2 = await getAppCatalogDigest(SPFX_EXTENSIONS_DATA_SITE);
1299
+ async function ensureAppWhiteListFields() {
1300
+ const fieldsUrl = `${SPFX_EXTENSIONS_SITE_URL}/_api/web/lists/GetByTitle('${ALLOWEDAPPSLIST_NAME}')/fields`;
1301
+ try {
1302
+ const req = await fetch(fieldsUrl, {
1303
+ headers: {
1304
+ Accept: "application/json;odata=verbose"
1305
+ }
1306
+ });
1307
+ if (req.status === 200) {
1308
+ const data = await req.json();
1309
+ const fields = data.d.results;
1310
+ const fieldNames = fields.map((f) => f.InternalName);
1311
+ if (!fieldNames.some((internalName) => internalName === "EntryPointUrl")) {
1312
+ await ensureMultiLineField(fieldsUrl, "EntryPointUrl", "Full URL to the Entrypoint JS file, if * is specified all entries will be allowed.", true);
1313
+ }
1314
+ }
1315
+ } catch (err) {
1316
+ logGenericCoreError("Error while ensuring list fields.", err);
1317
+ }
1318
+ }
1319
+ async function ensureMultiLineField(fieldsUrl, fieldInternalName, description, required) {
1320
+ const addFieldReq = await fetch(fieldsUrl, {
1321
+ method: "POST",
1322
+ headers: {
1323
+ Accept: "application/json;odata=verbose",
1324
+ "Content-Type": "application/json;odata=verbose",
1325
+ "X-RequestDigest": digest2
1326
+ },
1327
+ body: JSON.stringify({
1328
+ __metadata: {
1329
+ type: "SP.Field"
1330
+ },
1331
+ Title: fieldInternalName,
1332
+ FieldTypeKind: 3,
1333
+ Required: required,
1334
+ Description: description
1335
+ })
1336
+ });
1337
+ if (addFieldReq.status === 201) {
1338
+ logGenericCoreInfo(fieldInternalName, "field added successfully.");
1339
+ } else {
1340
+ logGenericCoreError(fieldInternalName, "Unable to add field.");
1341
+ }
1342
+ }
1343
+ async function createAppWhiteList() {
1344
+ try {
1345
+ const req = await fetch(`${SPFX_EXTENSIONS_SITE_URL}/_api/web/lists/GetByTitle('${ALLOWEDAPPSLIST_NAME}')?$select=*`, {
1346
+ method: "GET",
1347
+ headers: {
1348
+ Accept: "application/json;odata=verbose"
1349
+ }
1350
+ });
1351
+ const newList = req.status === 404;
1352
+ if (newList) {
1353
+ logGenericCoreInfo("Creating app white list.");
1354
+ const createReq = await fetch(`${SPFX_EXTENSIONS_SITE_URL}/_api/web/lists`, {
1355
+ method: "POST",
1356
+ headers: {
1357
+ Accept: "application/json;odata=verbose",
1358
+ "Content-Type": "application/json;odata=verbose",
1359
+ "X-RequestDigest": digest2
1360
+ },
1361
+ body: JSON.stringify({
1362
+ __metadata: {
1363
+ type: "SP.List"
1364
+ },
1365
+ BaseTemplate: 100,
1366
+ Title: ALLOWEDAPPSLIST_NAME,
1367
+ Description: "App whitelist for SPFxExtensions"
1368
+ })
1369
+ });
1370
+ if (createReq.status === 201) {
1371
+ logGenericCoreInfo("App whitelist created successfully.");
1372
+ return createReq.json();
1373
+ } else {
1374
+ logGenericCoreError("Unable to create app whitelist.");
1375
+ return;
1376
+ }
1377
+ }
1378
+ await ensureAppWhiteListFields();
1379
+ return req.json();
1380
+ } catch (err) {
1381
+ logGenericCoreError("Error while ensuring app whitelist.", err);
1382
+ }
1383
+ return;
1384
+ }
1385
+ async function ensureAppWhiteList() {
1386
+ const cachedData = await getExtensionConfigFromDB("AppWhiteList");
1387
+ if (cachedData?.Data) {
1388
+ return cachedData.Data;
1389
+ }
1390
+ const apiData = await createAppWhiteList();
1391
+ if (apiData) {
1392
+ await addOrUpdateExtensionConfig({ Title: "AppWhiteList", Data: apiData, date: "", expires: "" }, 480);
1393
+ }
1394
+ return apiData;
1395
+ }
1396
+
1397
+ // src/core/services/coreConfigService.ts
1398
+ var configurationInitializationPromise;
1399
+ async function initializeCoreConfiguration() {
1400
+ if (configurationInitializationPromise) {
1401
+ return configurationInitializationPromise;
1402
+ }
1403
+ configurationInitializationPromise = initializeCoreConfigurationInternal();
1404
+ return configurationInitializationPromise;
1405
+ }
1406
+ async function initializeCoreConfigurationInternal() {
1407
+ await ensureSPFxWeb();
1408
+ await ensureAppWhiteList();
1409
+ await ensureConfiguratorPage();
1410
+ window.__SPFxExtensions.Utils.ConfiguratorPageUrl = `${SPFX_EXTENSIONS_SITE_URL}/${CONFIGURATOR_PAGE_URL}`;
1411
+ }
1412
+ async function getCoreConfig(fresh = false) {
1413
+ await initializeCoreConfiguration();
1414
+ return getConfigurationListData(fresh);
1415
+ }
1416
+ async function getRootCDNLocation() {
1417
+ const coreConfig = await getCoreConfig();
1418
+ const ROOT_CDN_LOCATION = coreConfig.find((c) => c.Title === "RootCDNLocation")?.Data ?? `${SPFX_EXTENSIONS_SITE_URL}`;
1419
+ const ROOT_APPS_LOCATION = `${ROOT_CDN_LOCATION}${WELL_KNOWN_MANIFEST_LOCATION}`;
1420
+ return `${ROOT_APPS_LOCATION}${APPCOLLECTION_MANIFEST_NAME}`;
1421
+ }
1422
+
1423
+ // src/core/services/browserCache.ts
1424
+ async function cleanCacheOnUpgrade() {
1425
+ let coreConfig = await getCoreConfig();
1426
+ const keyParts = [
1427
+ "spfxextensions",
1428
+ "ff36e5d0-f7c7-421d-9e21-0a422626209a"
1429
+ ];
1430
+ if (coreConfig.find((c) => c.Title === "Version")?.Data !== "2025-04-26T18:12:40.559Z") {
1431
+ coreConfig = await getCoreConfig(true);
1432
+ addOrUpdateExtensionConfig({ Title: "Version", Data: "2025-04-26T18:12:40.559Z", date: "", expires: "" }, 240);
1433
+ const allStorages = await caches.keys();
1434
+ let somethingDeleted = false;
1435
+ for (const storageKey of allStorages) {
1436
+ const storage = await caches.open(storageKey);
1437
+ const allKeys = await storage.keys();
1438
+ const allPromises = [];
1439
+ for (const key of allKeys) {
1440
+ const url = key.url.toLowerCase();
1441
+ if (keyParts.some((k) => url.indexOf(k) > -1)) {
1442
+ logGenericCoreDebug("Deleting cache key", key);
1443
+ somethingDeleted = true;
1444
+ allPromises.push(storage.delete(key, { ignoreMethod: true, ignoreSearch: true }));
1445
+ }
1446
+ }
1447
+ await Promise.allSettled(allPromises);
1448
+ }
1449
+ if (somethingDeleted) {
1450
+ window.location.reload();
1451
+ }
1452
+ }
1453
+ }
1454
+ function GetRandomCacheStringAsync() {
1455
+ return getContentDigest(`${Date.now()}`, 13);
1456
+ }
1457
+
1458
+ // src/core/services/allowedAppsService.ts
1459
+ var AllowedAppsListDataPromise = getAllowedFilesDataCached();
1460
+ async function getAllowedFilesDataCached() {
1461
+ try {
1462
+ const evicted = await evictAllowedAppsCache();
1463
+ const cachedData = await getAllAllowedAppsFromDB();
1464
+ if (cachedData.length > 0 && !evicted) {
1465
+ return cachedData;
1466
+ }
1467
+ if (cachedData.length > 0) {
1468
+ logGenericCoreInfo("Cache mismatch, loading allowed apps data...");
1469
+ }
1470
+ const allowedAppsListData = await getAllowedFilesFromApi();
1471
+ await addOrUpdateAllowedAppsToCache(allowedAppsListData, 5);
1472
+ return allowedAppsListData;
1473
+ } catch (err) {
1474
+ logGenericCoreError("Unable to load allowed apps data...", err);
1475
+ return [];
1476
+ }
1477
+ }
1478
+ async function getAllowedFilesFromApi(fresh = false) {
1479
+ const coreConfig = await getCoreConfig(fresh);
1480
+ const appWhiteListEnabled = coreConfig.find((c) => c.Title === "EnableAppWhiteList")?.Data === "true";
1481
+ if (!appWhiteListEnabled) {
1482
+ return [
1483
+ {
1484
+ Id: 1,
1485
+ Title: "All apps allowed",
1486
+ EntryPointUrl: "*",
1487
+ date: new Date().toISOString(),
1488
+ expires: new Date().toISOString()
1489
+ }
1490
+ ];
1491
+ }
1492
+ return fetchAllowedFilesFromListInternal();
1493
+ }
1494
+ async function fetchAllowedFilesFromListInternal() {
1495
+ const url = `${SPFX_EXTENSIONS_SITE_URL}/_api/web/lists/getByTitle('${ALLOWEDAPPSLIST_NAME}')/Items?$select=Id,Title,EntryPointUrl&$top=1000`;
1496
+ const allowedAppsListData = await fetchAllowedFilesWithIterate(url);
1497
+ return allowedAppsListData;
1498
+ }
1499
+ async function fetchAllowedFilesWithIterate(url) {
1500
+ let fetchUrl = url;
1501
+ const allowedAppsListData = [];
1502
+ while (fetchUrl) {
1503
+ const response = await fetch(fetchUrl, {
1504
+ method: "GET",
1505
+ headers: {
1506
+ Accept: "application/json;odata=verbose"
1507
+ }
1508
+ });
1509
+ const json = await response.json();
1510
+ if (json.error) {
1511
+ throw new Error(JSON.stringify(json.error));
1512
+ }
1513
+ allowedAppsListData.push(...json.d.results);
1514
+ fetchUrl = json.d.__next;
1515
+ }
1516
+ return allowedAppsListData;
1517
+ }
1518
+ function fileIsAllowed(absoluteFileUrl, allowedList) {
1519
+ const allAllowed = allowedList.some((e) => e.EntryPointUrl === "*");
1520
+ if (allAllowed)
1521
+ return true;
1522
+ const fileOriginAndPath = (absoluteFileUrl.origin + absoluteFileUrl.pathname).toLowerCase();
1523
+ return allowedList.some((allowedEntry) => {
1524
+ try {
1525
+ const entryURL = new URL(allowedEntry.EntryPointUrl);
1526
+ const entryOriginAndPath = entryURL.origin + entryURL.pathname;
1527
+ return fileOriginAndPath === entryOriginAndPath.toLowerCase();
1528
+ } catch (err) {
1529
+ logGenericCoreError("Error while parsing allowed entry URL", allowedEntry.EntryPointUrl, err);
1530
+ return false;
1531
+ }
1532
+ });
1533
+ }
1534
+ async function isFileAllowedToRun(absoluteFileUrl, manifestName, fresh = false) {
1535
+ if (isFileInDebug(absoluteFileUrl))
1536
+ return true;
1537
+ const allowedList = fresh ? await getAllowedFilesFromApi(fresh) : await AllowedAppsListDataPromise;
1538
+ if (!fileIsAllowed(absoluteFileUrl, allowedList)) {
1539
+ logGenericCoreWarning("File", absoluteFileUrl, `is not allowed to be executed. Please add it to whitelist @ ${SPFX_EXTENSIONS_SITE_URL}.`);
1540
+ logGenericCoreWarning(`If you are a developer you can enable this app by adding localStorage item ${DEBUG_KEYS.SPFXEXT}${manifestName} with a number value corresponding to development port of the localhost server.`);
1541
+ return false;
1542
+ }
1543
+ return true;
1544
+ }
1545
+
1546
+ // src/services/spContextService.ts
1547
+ async function getModernContextAsync() {
1548
+ if (window.moduleLoaderPromise) {
1549
+ const result = await window.moduleLoaderPromise;
1550
+ return result?.context;
1551
+ }
1552
+ console.error("Unable to retrieve Modern SP Context...");
1553
+ }
1554
+ async function getContextInfoAsync() {
1555
+ if (window.moduleLoaderPromise) {
1556
+ const result = await window.moduleLoaderPromise;
1557
+ if (result?.context?.pageContext) {
1558
+ return {
1559
+ contextType: "SPOModernContext",
1560
+ context: result.context.pageContext
1561
+ };
1562
+ }
1563
+ throw "It seems this is a modern page, however it was not possible to retrieve SP Context...";
1564
+ }
1565
+ if (window._spPageContextInfo) {
1566
+ return {
1567
+ contextType: "ClassicContext",
1568
+ context: window._spPageContextInfo
1569
+ };
1570
+ }
1571
+ throw "It was not possible to retrieve SP Context either through modern or through classic means...";
1572
+ }
1573
+
1574
+ // src/core/services/contextService.ts
1575
+ var initialContext = await getContextInfoAsync();
1576
+ function getWebId() {
1577
+ return initialContext.contextType === "SPOModernContext" ? initialContext.context.web.id.toString() : extractGUIDFromString(initialContext.context.webId);
1578
+ }
1579
+ function getWebAbsoluteUrl() {
1580
+ const absoluteUrl = initialContext.contextType === "SPOModernContext" ? initialContext.context.web.absoluteUrl : initialContext.context.webAbsoluteUrl;
1581
+ return absoluteUrl.replace(/\/$/, "");
1582
+ }
1583
+ function getSiteId() {
1584
+ return initialContext.contextType === "SPOModernContext" ? initialContext.context.site.id.toString() : extractGUIDFromString(initialContext.context.siteId);
1585
+ }
1586
+ function getSiteAbsoluteUrl() {
1587
+ return initialContext.contextType === "SPOModernContext" ? initialContext.context.site.absoluteUrl : initialContext.context.siteAbsoluteUrl;
1588
+ }
1589
+ function getHubSiteId() {
1590
+ return (initialContext.contextType === "SPOModernContext" ? initialContext.context.legacyPageContext.hubSiteId?.toString() : initialContext.context.hubSiteId) ?? EMPTY_GUID;
1591
+ }
1592
+ function getIsHubSite() {
1593
+ return initialContext.contextType === "SPOModernContext" ? initialContext.context.legacyPageContext.isHubSite : initialContext.context.isHubSite;
1594
+ }
1595
+
1596
+ // src/core/services/txtAppsService.ts
1597
+ function validateAppsTXT(manifest) {
1598
+ if (!Array.isArray(manifest.enabledAppCollections)) {
1599
+ throw `${SPFxExtensionCore} ${APPCOLLECTION_MANIFEST_NAME} enabledAppCollections should be an array`;
1600
+ }
1601
+ if (!Array.isArray(manifest.urlMap)) {
1602
+ throw `${SPFxExtensionCore} ${APPCOLLECTION_MANIFEST_NAME} urlMap should be an array`;
1603
+ }
1604
+ }
1605
+ async function fetchAndCacheAppsTXT(url, name, type, isHubFetch, skipCache = false, cacheTimeMinutes = 60) {
1606
+ let appCollection = EMPTY_COLLECTION_MANIFEST;
1607
+ const fetchLocation = url.toLowerCase();
1608
+ if (!skipCache && !isInDebug) {
1609
+ const cachedManifest = await getAppCollectionTXTFromCache(fetchLocation);
1610
+ if (cachedManifest) {
1611
+ cachedManifest.isHubFetch = isHubFetch;
1612
+ return cachedManifest;
1613
+ }
1614
+ }
1615
+ const fetchUrl = `${fetchLocation}?v=${Date.now()}`;
1616
+ try {
1617
+ logGenericCoreDebug(`Fetching ${APPCOLLECTION_MANIFEST_NAME} from`, fetchUrl);
1618
+ const mnfReq = await fetch(fetchUrl);
1619
+ const result = await mnfReq.text();
1620
+ appCollection = JSON.parse(result);
1621
+ } catch (err) {
1622
+ logGenericCoreWarning(`Unable to fetch ${APPCOLLECTION_MANIFEST_NAME} from`, fetchUrl, err);
1623
+ }
1624
+ try {
1625
+ validateAppsTXT(appCollection);
1626
+ } catch (err) {
1627
+ logGenericCoreError(`Error while parsing ${APPCOLLECTION_MANIFEST_NAME} from`, fetchUrl, err);
1628
+ appCollection = EMPTY_COLLECTION_MANIFEST;
1629
+ }
1630
+ const hash = await getContentDigest(JSON.stringify(appCollection));
1631
+ const baseResult = {
1632
+ name,
1633
+ url: fetchLocation,
1634
+ type,
1635
+ hash
1636
+ };
1637
+ const retResult = { manifest: appCollection, ...baseResult };
1638
+ await setOrUpdateAppCollectionTXT(retResult, isInDebug ? 1 : cacheTimeMinutes);
1639
+ retResult.isHubFetch = isHubFetch;
1640
+ return retResult;
1641
+ }
1642
+ async function fetchAppCollectionConfigFromAllLocations(siteUrl, webUrl, hubUrl, skipCache = false) {
1643
+ const allAppManifests = [];
1644
+ const rootLocation = await getRootCDNLocation();
1645
+ allAppManifests.push(fetchAndCacheAppsTXT(rootLocation, "apps", "root", true, skipCache));
1646
+ const normalizedSiteUrl = siteUrl + WELL_KNOWN_MANIFEST_LOCATION;
1647
+ allAppManifests.push(fetchAndCacheAppsTXT(`${normalizedSiteUrl}${APPCOLLECTION_MANIFEST_NAME}`, "apps", "site", false, skipCache));
1648
+ if (hubUrl) {
1649
+ const normalizedHubUrl = hubUrl + WELL_KNOWN_MANIFEST_LOCATION;
1650
+ allAppManifests.push(fetchAndCacheAppsTXT(`${normalizedHubUrl}${APPCOLLECTION_MANIFEST_NAME}`, "apps", "site", true, skipCache));
1651
+ }
1652
+ const normalizedWebUrl = webUrl + WELL_KNOWN_MANIFEST_LOCATION;
1653
+ const fullWebUrl = `${normalizedWebUrl}${APPCOLLECTION_MANIFEST_NAME}`;
1654
+ const siteIsWeb = siteUrl.toLowerCase() === webUrl.toLowerCase();
1655
+ const webIsRoot = fullWebUrl.toLowerCase() === rootLocation.toLowerCase();
1656
+ if (!siteIsWeb && !webIsRoot) {
1657
+ allAppManifests.push(fetchAndCacheAppsTXT(fullWebUrl, "apps", "web", false, skipCache));
1658
+ }
1659
+ const manifestResult = await Promise.all(allAppManifests);
1660
+ return manifestResult;
1661
+ }
1662
+
1663
+ // src/core/services/txtManifestService.ts
1664
+ function validateManifestTXT(manifest) {
1665
+ if (Array.isArray(manifest) || typeof manifest !== "object") {
1666
+ throw `${SPFxExtensionCore} App manifest has to be an object.`;
1667
+ }
1668
+ if (!manifest.appRelativeEntryPointUrls) {
1669
+ logGenericCoreError(`Manifest does not have appRelativeEntryPointUrl property.`, manifest);
1670
+ throw `${SPFxExtensionCore} Manifest does not have appRelativeEntryPointUrl property.`;
1671
+ }
1672
+ if (!manifest.appDefinitionMap) {
1673
+ logGenericCoreError(`Manifest does not have enabledApps property.`, manifest);
1674
+ throw `${SPFxExtensionCore} Manifest does not have enabledApps property.`;
1675
+ }
1676
+ }
1677
+ async function fetchAndCacheManifestTXT(url, name, type, isHubFetch, skipCache = false, cacheTimeMinutes = 60) {
1678
+ let appManifest = { ...EMPTY_APP_MANIFEST };
1679
+ const fetchLocation = url.toLowerCase();
1680
+ if (!skipCache && !isInDebug) {
1681
+ const cachedManifest = await getManifestTXTFromCache(fetchLocation);
1682
+ if (cachedManifest) {
1683
+ cachedManifest.isHubFetch = isHubFetch;
1684
+ return cachedManifest;
1685
+ }
1686
+ }
1687
+ const fetchUrl = `${fetchLocation}?v=${Date.now()}`;
1688
+ try {
1689
+ logGenericCoreDebug(`Fetching ${MANIFEST_NAME} from`, fetchUrl);
1690
+ const mnfReq = await fetch(fetchUrl);
1691
+ const responseText = await mnfReq.text();
1692
+ appManifest = JSON.parse(responseText);
1693
+ } catch (err) {
1694
+ logGenericCoreWarning(`Unable to fetch ${MANIFEST_NAME} from`, fetchUrl, err);
1695
+ }
1696
+ try {
1697
+ validateManifestTXT(appManifest);
1698
+ } catch (err) {
1699
+ logGenericCoreError(`Error while parsing ${MANIFEST_NAME} from`, fetchUrl, err);
1700
+ appManifest = { ...EMPTY_APP_MANIFEST };
1701
+ }
1702
+ const hash = await getContentDigest(JSON.stringify(appManifest));
1703
+ const baseResult = {
1704
+ name,
1705
+ url: fetchLocation,
1706
+ type,
1707
+ hash
1708
+ };
1709
+ const retResult = {
1710
+ manifest: appManifest,
1711
+ ...baseResult
1712
+ };
1713
+ await setOrUpdateManifestTXT(retResult, isInDebug ? 1 : cacheTimeMinutes);
1714
+ retResult.isHubFetch = isHubFetch;
1715
+ return retResult;
1716
+ }
1717
+ function getManifestTXTLocation(baseUrl, appKey) {
1718
+ const siteLocation = `${baseUrl}${appKey}/${MANIFEST_NAME}`;
1719
+ const lsKey = `${DEBUG_KEYS.SPFXEXT}${appKey}`;
1720
+ const devSitePort = Number(localStorage.getItem(lsKey));
1721
+ if (devSitePort > 0) {
1722
+ const debugLoc = `https://localhost:${devSitePort}/${MANIFEST_NAME}`;
1723
+ logGenericCoreInfo(`<${appKey}> App is in debug mode, loading from`, debugLoc);
1724
+ return debugLoc;
1725
+ }
1726
+ return siteLocation;
1727
+ }
1728
+ function loadManifestTXT(appCollectionManifests, skipCache = false) {
1729
+ if (appCollectionManifests.length === 0)
1730
+ return [];
1731
+ const manifestTXTPromises = [];
1732
+ for (const appCollectionManifest of appCollectionManifests) {
1733
+ const baseUrl = appCollectionManifest.url.toLowerCase().replace(APPCOLLECTION_MANIFEST_NAME.toLowerCase(), "");
1734
+ for (const appFolderName of appCollectionManifest.manifest.enabledAppCollections) {
1735
+ const manifestLocation = getManifestTXTLocation(baseUrl, appFolderName);
1736
+ manifestTXTPromises.push(fetchAndCacheManifestTXT(manifestLocation, appFolderName, appCollectionManifest.type, appCollectionManifest.isHubFetch ?? false, skipCache));
1737
+ }
1738
+ }
1739
+ return manifestTXTPromises;
1740
+ }
1741
+ function getManifestTXTFromAllLocations(coreCollection, skipCache = false) {
1742
+ const rootAppsCollectionManifest = coreCollection.filter((app) => app.type === "root");
1743
+ const rootAppPromises = loadManifestTXT(rootAppsCollectionManifest, skipCache);
1744
+ const siteCollectionAppsManifest = coreCollection.filter((app) => app.type === "site");
1745
+ const scAppPromises = loadManifestTXT(siteCollectionAppsManifest, skipCache);
1746
+ const webAppCollectionManifest = coreCollection.filter((app) => app.type === "web");
1747
+ const subsitePromises = loadManifestTXT(webAppCollectionManifest, skipCache);
1748
+ const allManifestsTXT = [
1749
+ ...rootAppPromises,
1750
+ ...scAppPromises,
1751
+ ...subsitePromises
1752
+ ];
1753
+ return allManifestsTXT;
1754
+ }
1755
+
1756
+ // src/core/services/componentLoaderService.ts
1757
+ var isLoaded = false;
1758
+ var loadedAssets = [];
1759
+ async function importEntryPointsAndExecute(fullJSUrl, originalEntry, manifest) {
1760
+ if (!manifest.isESM) {
1761
+ const foundNonESMAppConfig = manifest.appDefinitionMap.find((a) => a.appId === originalEntry);
1762
+ if (!foundNonESMAppConfig) {
1763
+ const error = `Could not find app configuration item for non-ESM app ${originalEntry}`;
1764
+ logGenericCoreError(error);
1765
+ return [];
1766
+ }
1767
+ const isEnabled = isEntryEnabledInCurrentContext(foundNonESMAppConfig);
1768
+ if (!isEnabled) {
1769
+ logGenericCoreInfo(`App ${originalEntry} is not enabled in current context. Skipping...`);
1770
+ return [];
1771
+ }
1772
+ try {
1773
+ logGenericCoreWarning(`Non-ESM module detected. Make sure to call window.__SPFxExtensions.RegisterApp and window.__SPFxExtensions.InstantiateApp in code.`, fullJSUrl);
1774
+ await import(fullJSUrl);
1775
+ } catch (e) {
1776
+ const error = `Error while importing or executing ${fullJSUrl} ${e}`;
1777
+ logGenericCoreError(error);
1778
+ return [];
1779
+ }
1780
+ return [];
1781
+ } else {
1782
+ try {
1783
+ const appRegistrations = await import(fullJSUrl);
1784
+ const defaultExport = appRegistrations.default;
1785
+ if (!defaultExport) {
1786
+ logGenericCoreError(`No default export found in ${fullJSUrl}, only ESM modules are supported.`);
1787
+ return [];
1788
+ }
1789
+ return executeRegistrations(defaultExport, manifest, fullJSUrl);
1790
+ } catch (e) {
1791
+ logGenericCoreError(`Error while importing or executing`, fullJSUrl, e);
1792
+ return [];
1793
+ }
1794
+ }
1795
+ }
1796
+ async function parseManifestAndImportEntryPoints(manifestToParse) {
1797
+ const returnPromiseArray = [];
1798
+ const cdnLoc = manifestToParse.url.replace(MANIFEST_NAME, "");
1799
+ logGenericCoreDebug("Parsing", manifestToParse.type, "manifest:", manifestToParse.manifest);
1800
+ for (const entryUrl of manifestToParse.manifest.appRelativeEntryPointUrls) {
1801
+ const ep = entryUrl.replace(/\.\.\/?/g, "./").replace(/^\.\//, "");
1802
+ const fullJSUrl = `${cdnLoc}${ep}`.toLowerCase();
1803
+ logGenericCoreDebug(`EntryPoint JS: `, fullJSUrl);
1804
+ const jsUrl = new URL(fullJSUrl);
1805
+ if (manifestToParse.manifest.cacheString && manifestToParse.manifest.enableCaching) {
1806
+ const cacheString = isAppInDebug(manifestToParse.name) ? `${new Date().getTime()}` : manifestToParse.manifest.cacheString;
1807
+ jsUrl.searchParams.set("v", `${cacheString}`);
1808
+ }
1809
+ const isAllowed = await isFileAllowedToRun(jsUrl, manifestToParse.name);
1810
+ if (!isAllowed) {
1811
+ continue;
1812
+ }
1813
+ const plainUrl = `${jsUrl.origin}${jsUrl.pathname}`;
1814
+ const urlWithCache = `${jsUrl}`;
1815
+ const isScriptLoaded = loadedAssets.includes(plainUrl);
1816
+ if (isScriptLoaded) {
1817
+ logGenericCoreInfo(`EntryPoint already loaded:`, urlWithCache);
1818
+ continue;
1819
+ }
1820
+ loadedAssets.push(plainUrl);
1821
+ returnPromiseArray.push(importEntryPointsAndExecute(urlWithCache, entryUrl, manifestToParse.manifest));
1822
+ }
1823
+ return returnPromiseArray;
1824
+ }
1825
+ async function loadModernApps(siteUrl, webUrl, hubUrl, contextId, contextChange = false) {
1826
+ if (contextChange) {
1827
+ handleContextChange(contextId);
1828
+ }
1829
+ if (isLoaded)
1830
+ return;
1831
+ isLoaded = true;
1832
+ const coreCollection = await fetchAppCollectionConfigFromAllLocations(siteUrl, webUrl, hubUrl);
1833
+ const allManifestTXTs = getManifestTXTFromAllLocations(coreCollection);
1834
+ window.__SPFxExtensions.Utils.appManifestPromises = allManifestTXTs;
1835
+ window.__SPFxExtensions.Utils.spAppInitializationPromiseResolver();
1836
+ const allManifestTXTsPromises = await Promise.allSettled(allManifestTXTs);
1837
+ const resolvedManifestTXTs = allManifestTXTsPromises.filter((p) => p.status === "fulfilled");
1838
+ const successfullAppRegistrations = [];
1839
+ const resolvedRootAppsManifests = resolvedManifestTXTs.filter((m) => m.value.type === "root");
1840
+ const resolvedSiteAppsManifests = resolvedManifestTXTs.filter((m) => m.value.type === "site");
1841
+ const resolvedWebAppsManifests = resolvedManifestTXTs.filter((m) => m.value.type === "web");
1842
+ for (const rootManifestTXT of resolvedRootAppsManifests) {
1843
+ const rootEntries = await parseManifestAndImportEntryPoints(rootManifestTXT.value);
1844
+ successfullAppRegistrations.push(...rootEntries);
1845
+ }
1846
+ logGenericCoreDebug("Root apps loaded.");
1847
+ for (const siteManifests of resolvedSiteAppsManifests) {
1848
+ const siteEntries = await parseManifestAndImportEntryPoints(siteManifests.value);
1849
+ successfullAppRegistrations.push(...siteEntries);
1850
+ }
1851
+ logGenericCoreDebug("Site apps loaded.");
1852
+ for (const webManifests of resolvedWebAppsManifests) {
1853
+ const webEntries = await parseManifestAndImportEntryPoints(webManifests.value);
1854
+ successfullAppRegistrations.push(...webEntries);
1855
+ }
1856
+ logGenericCoreDebug("SiteWeb apps loaded.");
1857
+ const successfullyRegistered = (await Promise.allSettled(successfullAppRegistrations)).filter((r) => r.status === "fulfilled").flatMap((r) => r.value);
1858
+ await unregisterNonApplicable(successfullyRegistered);
1859
+ window.__SPFxExtensions.AllAppAssetsLoadedResolver();
1860
+ logGenericCoreInfo("SPFx Extensions Core Components Loaded.");
1861
+ }
1862
+ function handleContextChange(contextId) {
1863
+ isLoaded = false;
1864
+ loadedAssets.splice(0, loadedAssets.length);
1865
+ unmountInstancesOnContextChange(contextId);
1866
+ const { promise: assetPromise, resolve: assetPromiseResolver } = Promise.withResolvers();
1867
+ window.__SPFxExtensions.AllAppAssetsLoadedPromise = assetPromise;
1868
+ window.__SPFxExtensions.AllAppAssetsLoadedResolver = assetPromiseResolver;
1869
+ }
1870
+ async function unregisterNonApplicable(allExports) {
1871
+ for (const alreadyRegisteredApp of window.__SPFxExtensions.Apps) {
1872
+ const foundApp = allExports.find((a) => a.id === alreadyRegisteredApp.id);
1873
+ if (!foundApp && alreadyRegisteredApp.id !== CONFIGURATOR_APP_ID) {
1874
+ const unregistered = await window.__SPFxExtensions.UnregisterApp(alreadyRegisteredApp.id);
1875
+ if (unregistered) {
1876
+ logGenericCoreWarning(`Unregistered App ${alreadyRegisteredApp.id} (${alreadyRegisteredApp.name}) as it does not belong in this context`);
1877
+ }
1878
+ }
1879
+ }
1880
+ }
1881
+ async function executeRegistrations(registrations, manifestToParse, fullJSUrl) {
1882
+ if (!Array.isArray(registrations)) {
1883
+ logGenericCoreError(`Default export of entry point should be an array of App definitions. TODO: add documentation url`, fullJSUrl);
1884
+ }
1885
+ const successfullyRegistered = [];
1886
+ for (const appReg of registrations) {
1887
+ if (!appReg.id) {
1888
+ logGenericCoreError(`App definition does not have an id. Make sure that returned array is in proper format. TODO: add documentation url`, fullJSUrl, appReg);
1889
+ continue;
1890
+ }
1891
+ const foundMapItem = manifestToParse.appDefinitionMap.find((a) => a.appId.toLowerCase() === appReg.id.toLowerCase());
1892
+ const notEnabledMSG = `App with id ${appReg.id} (${appReg.name}) is not enabled for current web. Skipping...`;
1893
+ if (!foundMapItem) {
1894
+ logGenericCoreInfo(notEnabledMSG);
1895
+ continue;
1896
+ }
1897
+ const appEnabled = isEntryEnabledInCurrentContext(foundMapItem);
1898
+ if (!appEnabled) {
1899
+ logGenericCoreInfo(notEnabledMSG);
1900
+ continue;
1901
+ }
1902
+ const registeredApp = await window.__SPFxExtensions.RegisterApp(appReg);
1903
+ successfullyRegistered.push(appReg);
1904
+ if (!appReg.isWebPartApp && appReg.autoExecute) {
1905
+ if (registeredApp.instances.length < (appReg.maxInstances ?? Infinity)) {
1906
+ window.__SPFxExtensions.InstantiateApp(appReg.id, {});
1907
+ }
1908
+ }
1909
+ }
1910
+ return successfullyRegistered;
1911
+ }
1912
+ function isEntryEnabledInCurrentContext(foundMapItem) {
1913
+ const currentWebId = getWebId().toLowerCase();
1914
+ const currentSiteId = getSiteId().toLowerCase();
1915
+ const currentHubId = getHubSiteId().toLowerCase();
1916
+ const isEnabledEverywhere = foundMapItem.config.enabledEverywhere;
1917
+ const appEnabled = isEnabledEverywhere ? foundMapItem.config.excludedIds.indexOf(currentWebId) === -1 && foundMapItem.config.excludedIds.indexOf(currentSiteId) === -1 && foundMapItem.config.excludedHubIds.indexOf(currentHubId) === -1 : true;
1918
+ return appEnabled;
1919
+ }
1920
+
1921
+ // src/core/services/contextEventService.ts
1922
+ var contextServiceInitialized = false;
1923
+ function initializeContextEventService() {
1924
+ if (window.moduleLoaderPromise && !contextServiceInitialized) {
1925
+ contextServiceInitialized = true;
1926
+ window.moduleLoaderPromise.then((ctx) => {
1927
+ const originalInitialize = ctx.context.pageContext.initialize;
1928
+ ctx.context.pageContext.initialize = function(initializationData, legacyContext) {
1929
+ const previousContext = ctx.context.pageContext._initializationData;
1930
+ originalInitialize.call(this, initializationData, legacyContext);
1931
+ const detail = {
1932
+ initializationData,
1933
+ legacyContext
1934
+ };
1935
+ if (previousContext.web.id === initializationData.web.id) {
1936
+ dispatchCoreEvent("contextRefresh", detail);
1937
+ return;
1938
+ }
1939
+ dispatchCoreEvent("contextChange", detail);
1940
+ };
1941
+ });
1942
+ }
1943
+ }
1944
+ function dispatchCoreEvent(eventName, detail) {
1945
+ const event = new CustomEvent(eventName, {
1946
+ detail
1947
+ });
1948
+ window.dispatchEvent(event);
1949
+ window.__SPFxExtensions.Apps.forEach((app) => {
1950
+ app.instances.forEach((instance) => {
1951
+ instance.executeListeners(eventName, detail);
1952
+ });
1953
+ });
1954
+ }
1955
+
1956
+ // src/core/services/globalModernAppsListeners.ts
1957
+ function registerGlobalListeners() {
1958
+ if (!window.__SPFxExtensions.AppEventListeners) {
1959
+ window.__SPFxExtensions.AppEventListeners = [];
1960
+ }
1961
+ if (!window.__SPFxExtensions.AddAppEventListener) {
1962
+ window.__SPFxExtensions.AddAppEventListener = (ev, handler) => {
1963
+ const el = {
1964
+ key: window.crypto.randomUUID(),
1965
+ eventName: ev,
1966
+ handler
1967
+ };
1968
+ window.__SPFxExtensions.AppEventListeners.push(el);
1969
+ return el;
1970
+ };
1971
+ }
1972
+ if (!window.__SPFxExtensions.RemoveAppEventListener) {
1973
+ window.__SPFxExtensions.RemoveAppEventListener = (listener) => {
1974
+ const lisIdx = window.__SPFxExtensions.AppEventListeners.findIndex((l) => l.key === listener.key);
1975
+ if (lisIdx > -1) {
1976
+ window.__SPFxExtensions.AppEventListeners.splice(lisIdx, 1);
1977
+ }
1978
+ };
1979
+ }
1980
+ }
1981
+
1982
+ // src/core/services/historyService.ts
1983
+ var originalPushState = window.history.pushState;
1984
+ var originalReplaceState = window.history.replaceState;
1985
+ var originalHistoryBack = window.history.back;
1986
+ var originalHistoryForward = window.history.forward;
1987
+ var originalHistoryGo = window.history.go;
1988
+ function getCurrentState() {
1989
+ const currentState = window.history.state;
1990
+ const previousUrl = window.location.href;
1991
+ return { currentState, previousUrl };
1992
+ }
1993
+ function dispatchEvent(eventName, newState) {
1994
+ const detail = {
1995
+ ...getCurrentState(),
1996
+ ...newState
1997
+ };
1998
+ const evt = new CustomEvent(eventName, { detail });
1999
+ window.dispatchEvent(evt);
2000
+ }
2001
+ function interceptHistoryPushState() {
2002
+ function _pushState(newState, unused, newUrl) {
2003
+ originalPushState.call(this, newState, unused, newUrl);
2004
+ dispatchEvent("historyPush", { newState, newUrl });
2005
+ }
2006
+ window.history.pushState = _pushState;
2007
+ }
2008
+ function interceptHistoryReplaceState() {
2009
+ function _replaceState(newState, unused, newUrl) {
2010
+ originalReplaceState.call(this, newState, unused, newUrl);
2011
+ dispatchEvent("historyReplace", { newState, newUrl });
2012
+ }
2013
+ window.history.replaceState = _replaceState;
2014
+ }
2015
+ function interceptHistoryBack() {
2016
+ function _goBack() {
2017
+ originalHistoryBack.call(this);
2018
+ dispatchEvent("historyBack", {});
2019
+ }
2020
+ window.history.back = _goBack;
2021
+ }
2022
+ function interceptHistoryForward() {
2023
+ function _goForward() {
2024
+ originalHistoryForward.call(this);
2025
+ dispatchEvent("historyForward", {});
2026
+ }
2027
+ window.history.forward = _goForward;
2028
+ }
2029
+ function interceptHistoryGo() {
2030
+ function _go(delta) {
2031
+ originalHistoryGo.call(this, delta);
2032
+ dispatchEvent("historyGo", { delta });
2033
+ }
2034
+ window.history.go = _go;
2035
+ }
2036
+ var historyInterceptionInited = false;
2037
+ function initHistoryInterception() {
2038
+ if (historyInterceptionInited) {
2039
+ return;
2040
+ }
2041
+ historyInterceptionInited = true;
2042
+ interceptHistoryReplaceState();
2043
+ interceptHistoryPushState();
2044
+ interceptHistoryForward();
2045
+ interceptHistoryBack();
2046
+ interceptHistoryGo();
2047
+ }
2048
+
2049
+ // src/core/services/hubDataService.ts
2050
+ async function getHubSiteUrl() {
2051
+ if (getIsHubSite()) {
2052
+ return "";
2053
+ }
2054
+ const hubSiteId = getHubSiteId();
2055
+ const siteId = getSiteId();
2056
+ if (!hubSiteId || hubSiteId === EMPTY_GUID || hubSiteId === siteId) {
2057
+ return "";
2058
+ }
2059
+ await evictHubDataCache();
2060
+ const cached = await getHubData(hubSiteId);
2061
+ if (!cached) {
2062
+ const siteUrl = getSiteAbsoluteUrl();
2063
+ logGenericCoreInfo("Getting Hub data for HubSiteId:", hubSiteId);
2064
+ try {
2065
+ const hubSite = await fetch(`${siteUrl}/_api/hubsites/GetById?hubSiteId='${hubSiteId}'`, {
2066
+ headers: { accept: "application/json;odata=nometadata" }
2067
+ });
2068
+ const hubSiteData = await hubSite.json();
2069
+ await addOrUpdateHubDataToCache(hubSiteData);
2070
+ return hubSiteData.SiteUrl;
2071
+ } catch (e) {
2072
+ logGenericCoreError("Error fetching hub site data.", e);
2073
+ return "";
2074
+ }
2075
+ }
2076
+ return cached.SiteUrl;
2077
+ }
2078
+
2079
+ // src/core/services/manifestWatcherService.ts
2080
+ var CORE_MANIFEST_CHECK = "CORE_MANIFEST_CHECK";
2081
+ var CORE_MANIFEST_CHECK_INTERVAL = Number(localStorage.getItem(DEBUG_KEYS.SPFXEXT_CORE)) > 0 ? 1e5 : 60000;
2082
+ var manifestWatch = 0;
2083
+ function registerManifestWatcher(site, web, hubUrl, contextChange = false) {
2084
+ if (contextChange) {
2085
+ window.clearInterval(manifestWatch);
2086
+ manifestWatch = 0;
2087
+ }
2088
+ if (manifestWatch > 0)
2089
+ return;
2090
+ manifestWatch = window.setInterval(performManifestCheck, CORE_MANIFEST_CHECK_INTERVAL, site, web, hubUrl);
2091
+ performManifestCheck(site, web, hubUrl);
2092
+ }
2093
+ async function performManifestCheck(site, web, hubUrl) {
2094
+ try {
2095
+ const item = localStorage.getItem(CORE_MANIFEST_CHECK);
2096
+ if (item) {
2097
+ const lastCheck = new Date(item);
2098
+ const now = new Date;
2099
+ const diff = now.getTime() - lastCheck.getTime();
2100
+ const maxDiff = CORE_MANIFEST_CHECK_INTERVAL - 2000;
2101
+ if (diff < maxDiff) {
2102
+ logGenericCoreDebug("Manifest check already performed recently, skipping.", `${diff} < ${maxDiff}`);
2103
+ return;
2104
+ }
2105
+ }
2106
+ logGenericCoreInfo(`Checking for manifest updates across all locations...`);
2107
+ await Promise.all([evictAppsTXTCache(), evictManifestTXTCache()]);
2108
+ const appLocations = await fetchAppCollectionConfigFromAllLocations(site, web, hubUrl, true);
2109
+ const allManifests = getManifestTXTFromAllLocations(appLocations, true);
2110
+ await Promise.allSettled(allManifests);
2111
+ } catch (e) {
2112
+ logGenericCoreError("Error checking for manifest updates", e);
2113
+ }
2114
+ const nextCheck = new Date().toISOString();
2115
+ logGenericCoreDebug("Setting next manifest check to", nextCheck);
2116
+ localStorage.setItem(CORE_MANIFEST_CHECK, nextCheck);
2117
+ }
2118
+
2119
+ // src/core/services/initializationService.ts
2120
+ var coreGlobalPromise;
2121
+ async function initGlobal() {
2122
+ if (coreGlobalPromise) {
2123
+ return coreGlobalPromise;
2124
+ }
2125
+ coreGlobalPromise = initGlobalInternal();
2126
+ return coreGlobalPromise;
2127
+ }
2128
+ async function initGlobalInternal() {
2129
+ await initializeCoreConfiguration();
2130
+ const coreConfig = await getCoreConfig();
2131
+ const historyInterceptEnabled = coreConfig.find((c) => c.Title === "InterceptHistory")?.Data === "true";
2132
+ if (historyInterceptEnabled) {
2133
+ initHistoryInterception();
2134
+ }
2135
+ initializeContextEventService();
2136
+ registerGlobalListeners();
2137
+ registerAppService();
2138
+ registerAppInstanceService();
2139
+ const { promise: assetPromise, resolve: assetPromiseResolver } = Promise.withResolvers();
2140
+ if (!window.__SPFxExtensions.AllAppAssetsLoadedPromise) {
2141
+ window.__SPFxExtensions.AllAppAssetsLoadedPromise = assetPromise;
2142
+ window.__SPFxExtensions.AllAppAssetsLoadedResolver = assetPromiseResolver;
2143
+ }
2144
+ }
2145
+ async function initCoreServices() {
2146
+ await cleanCacheOnUpgrade();
2147
+ await initGlobal();
2148
+ window.__SPFxExtensions.__CorePromiseResolver?.();
2149
+ const siteUrl = getSiteAbsoluteUrl();
2150
+ const webUrl = getWebAbsoluteUrl();
2151
+ const hubSiteUrl = await getHubSiteUrl();
2152
+ await loadModernApps(siteUrl, webUrl, hubSiteUrl, getCurrentContextId());
2153
+ window.addEventListener("contextChange", async () => {
2154
+ logGenericCoreInfo("Context changed, reloading apps...");
2155
+ const siteUrl2 = getSiteAbsoluteUrl();
2156
+ const webUrl2 = getWebAbsoluteUrl();
2157
+ const hubSiteUrl2 = await getHubSiteUrl();
2158
+ const newCtx = getNewContext();
2159
+ await loadModernApps(siteUrl2, webUrl2, hubSiteUrl2, newCtx, true);
2160
+ registerManifestWatcher(siteUrl2, webUrl2, hubSiteUrl2, true);
2161
+ });
2162
+ registerManifestWatcher(siteUrl, webUrl, hubSiteUrl);
2163
+ logGenericCoreInfo("SPFx Extensions Core Has Been initialized.");
2164
+ }
2165
+
2166
+ // src/core/__spfxCore.ts
2167
+ var configuratorApp = {
2168
+ id: CONFIGURATOR_APP_ID,
2169
+ description: "Allows configuring custom apps",
2170
+ isWebPartApp: false,
2171
+ hideAppSelectorWhenAppLoaded: true,
2172
+ hideConfiguratorButton: true,
2173
+ name: "SPFx Extensions Configurator",
2174
+ async onInstanceRequested(newInstance) {
2175
+ const coreIsInDebug = import.meta.url.indexOf("localhost") > -1;
2176
+ if (coreIsInDebug) {
2177
+ logGenericCoreDebug("Core is in debug mode");
2178
+ }
2179
+ const configuratorUrl = coreIsInDebug ? import.meta.resolve(`./__spfxCoreConfigurator.js?v=${Date.now()}`) : window.__SPFxExtensions.__ConfiguratorUrl;
2180
+ try {
2181
+ const module = await import(configuratorUrl);
2182
+ return module.launch(newInstance);
2183
+ } catch (e) {
2184
+ logGenericCoreError("Error launching configurator app", e);
2185
+ if (newInstance.domElement) {
2186
+ newInstance.domElement.innerHTML = `<div style="text-align: center; padding: 20px; color: red;">Error launching configurator app. ${e}</div>`;
2187
+ }
2188
+ return () => {};
2189
+ }
2190
+ }
2191
+ };
2192
+ async function start() {
2193
+ const buildDate = "2025-04-26T18:12:40.559Z";
2194
+ logGenericCoreInfo(`Initializing Core Services Built:`, buildDate);
2195
+ await initCoreServices();
2196
+ try {
2197
+ await window.__SPFxExtensions.RegisterApp(configuratorApp);
2198
+ } catch (e) {
2199
+ logGenericCoreError("Error registering configurator app", e);
2200
+ }
2201
+ }
2202
+ start();