@kanonak-protocol/sdk 4.8.0 → 4.9.0

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.
package/dist/browser.js CHANGED
@@ -1,2 +1,2 @@
1
- import{a as fe,b as ge,c as me,d as C,e as E,f as d,g as Ye}from"./chunk-KGWDV7FW.js";import{a as Qe}from"./chunk-NV63IOB7.js";import"./chunk-QHABFCRC.js";import{b as L,c as W,d as F}from"./chunk-F26XWM5K.js";import{a as H}from"./chunk-4NO7MHS7.js";import{a as Pe,b as we,c as he}from"./chunk-RYOZTXI7.js";import{a as ke,b as be}from"./chunk-PEUTCG3B.js";import"./chunk-PEJALHXK.js";import"./chunk-SC5M74NM.js";import{A as Le,B as We,C as Fe,D as Ge,M as Xe,a as Ke,b as xe,c as Se,d as Re,f as De,g as Be,h as Ce,i as Ee,k as je,l as ve,m as _e,n as Ie,o as Ae,p as Te,q as Oe,r as Ve,s as $e,t as Ue,u as Me,v as ze,w as Ne,x as Je,y as He,z as qe}from"./chunk-IZRPJCQW.js";import"./chunk-SHDHMKMJ.js";import{a as Y,c as le,i as pe}from"./chunk-DSHPAWJQ.js";import{a as q}from"./chunk-NJ3AZYQD.js";import{a as ye}from"./chunk-UK2OIPAB.js";import"./chunk-PBNVHBS3.js";import{b as ue,c as de}from"./chunk-VKTFLHCW.js";import{a as G,b as X,c as Q,d as ee,e as re,f as te,g as ne,h as oe,i as se,j as ie,k as ae,l as ce}from"./chunk-T3JR2SV6.js";import{a as Z}from"./chunk-FUUTGGJS.js";import{c as O,d as V,e as $,f as U,g as M,h as z,i as N,j as J}from"./chunk-2ACBWC7K.js";var j="kanonak-credentials",u="credentials",Ze=1,g=class{async get(r){let e=d(r),t=await h();return new Promise((o,a)=>{let s=t.transaction(u,"readonly"),i=s.objectStore(u).get(e);i.onsuccess=()=>o(i.result??null),i.onerror=()=>a(new Error(`IndexedDB read failed for '${e}': ${i.error?.message}`)),s.oncomplete=()=>t.close()})}async store(r,e){let t=d(r),o=await h();return new Promise((a,s)=>{let l=o.transaction(u,"readwrite"),c=l.objectStore(u).put(e,t);c.onsuccess=()=>a(),c.onerror=()=>s(new Error(`IndexedDB write failed for '${t}': ${c.error?.message}`)),l.oncomplete=()=>o.close()})}async remove(r){let e=d(r),t=await h();return new Promise((o,a)=>{let s=t.transaction(u,"readwrite"),i=s.objectStore(u).delete(e);i.onsuccess=()=>o(),i.onerror=()=>a(new Error(`IndexedDB delete failed for '${e}': ${i.error?.message}`)),s.oncomplete=()=>t.close()})}async list(){let r=await h();return new Promise((e,t)=>{let o=r.transaction(u,"readonly"),s=o.objectStore(u).getAllKeys();s.onsuccess=()=>e(s.result??[]),s.onerror=()=>t(new Error(`IndexedDB list failed: ${s.error?.message}`)),o.oncomplete=()=>r.close()})}};function h(){return new Promise((n,r)=>{let e=indexedDB.open(j,Ze);e.onupgradeneeded=()=>{let t=e.result;t.objectStoreNames.contains(u)||t.createObjectStore(u)},e.onsuccess=()=>n(e.result),e.onerror=()=>r(new Error(`Failed to open IndexedDB '${j}': ${e.error?.message}
1
+ import{a as fe,b as ge,c as me,d as C,e as E,f as d,g as Ye}from"./chunk-KGWDV7FW.js";import{a as Qe}from"./chunk-NV63IOB7.js";import"./chunk-QHABFCRC.js";import{b as L,c as W,d as F}from"./chunk-MFQUKORC.js";import{a as H}from"./chunk-4NO7MHS7.js";import{a as Pe,b as we,c as he}from"./chunk-RYOZTXI7.js";import{a as ke,b as be}from"./chunk-PEUTCG3B.js";import"./chunk-PEJALHXK.js";import"./chunk-SC5M74NM.js";import{A as Le,B as We,C as Fe,D as Ge,M as Xe,a as Ke,b as xe,c as Se,d as Re,f as De,g as Be,h as Ce,i as Ee,k as je,l as ve,m as _e,n as Ie,o as Ae,p as Te,q as Oe,r as Ve,s as $e,t as Ue,u as Me,v as ze,w as Ne,x as Je,y as He,z as qe}from"./chunk-IZRPJCQW.js";import"./chunk-SHDHMKMJ.js";import{a as Y,c as le,i as pe}from"./chunk-DSHPAWJQ.js";import{a as q}from"./chunk-NJ3AZYQD.js";import{a as ye}from"./chunk-UK2OIPAB.js";import"./chunk-PBNVHBS3.js";import{b as ue,c as de}from"./chunk-VKTFLHCW.js";import{a as G,b as X,c as Q,d as ee,e as re,f as te,g as ne,h as oe,i as se,j as ie,k as ae,l as ce}from"./chunk-T3JR2SV6.js";import{a as Z}from"./chunk-FUUTGGJS.js";import{c as O,d as V,e as $,f as U,g as M,h as z,i as N,j as J}from"./chunk-2ACBWC7K.js";var j="kanonak-credentials",u="credentials",Ze=1,g=class{async get(r){let e=d(r),t=await h();return new Promise((o,a)=>{let s=t.transaction(u,"readonly"),i=s.objectStore(u).get(e);i.onsuccess=()=>o(i.result??null),i.onerror=()=>a(new Error(`IndexedDB read failed for '${e}': ${i.error?.message}`)),s.oncomplete=()=>t.close()})}async store(r,e){let t=d(r),o=await h();return new Promise((a,s)=>{let l=o.transaction(u,"readwrite"),c=l.objectStore(u).put(e,t);c.onsuccess=()=>a(),c.onerror=()=>s(new Error(`IndexedDB write failed for '${t}': ${c.error?.message}`)),l.oncomplete=()=>o.close()})}async remove(r){let e=d(r),t=await h();return new Promise((o,a)=>{let s=t.transaction(u,"readwrite"),i=s.objectStore(u).delete(e);i.onsuccess=()=>o(),i.onerror=()=>a(new Error(`IndexedDB delete failed for '${e}': ${i.error?.message}`)),s.oncomplete=()=>t.close()})}async list(){let r=await h();return new Promise((e,t)=>{let o=r.transaction(u,"readonly"),s=o.objectStore(u).getAllKeys();s.onsuccess=()=>e(s.result??[]),s.onerror=()=>t(new Error(`IndexedDB list failed: ${s.error?.message}`)),o.oncomplete=()=>r.close()})}};function h(){return new Promise((n,r)=>{let e=indexedDB.open(j,Ze);e.onupgradeneeded=()=>{let t=e.result;t.objectStoreNames.contains(u)||t.createObjectStore(u)},e.onsuccess=()=>n(e.result),e.onerror=()=>r(new Error(`Failed to open IndexedDB '${j}': ${e.error?.message}
2
2
  Credential storage requires IndexedDB support in your browser.`))})}async function _(){let n=await crypto.subtle.generateKey({name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),r=await crypto.subtle.exportKey("jwk",n.publicKey);return{signingKey:n.privateKey,publicKeyJwk:r}}async function k(){let n=await crypto.subtle.generateKey({name:"ECDSA",namedCurve:"P-256"},!0,["sign"]),r=await crypto.subtle.exportKey("jwk",n.publicKey),e=await crypto.subtle.exportKey("jwk",n.privateKey);return{keys:{signingKey:n.privateKey,publicKeyJwk:r},dpopKeyPair:{publicKey:r,privateKey:e}}}async function b(n){return{signingKey:await crypto.subtle.importKey("jwk",n.privateKey,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]),publicKeyJwk:n.publicKey}}async function K(n,r,e,t,o){let a={alg:"ES256",typ:"dpop+jwt",jwk:{kty:n.publicKeyJwk.kty,crv:n.publicKeyJwk.crv,x:n.publicKeyJwk.x,y:n.publicKeyJwk.y}},s={jti:crypto.randomUUID(),htm:r.toUpperCase(),htu:e,iat:Math.floor(Date.now()/1e3)};return t&&(s.ath=await rr(t)),o&&(s.nonce=o),await er(a,s,n.signingKey)}function x(n){return!n||n.length===0?!1:n.some(r=>r.toUpperCase()==="ES256")}async function er(n,r,e){let t=v(JSON.stringify(n)),o=v(JSON.stringify(r)),a=new TextEncoder().encode(`${t}.${o}`),s=await crypto.subtle.sign({name:"ECDSA",hash:"SHA-256"},e,a),l=D(s);return`${t}.${o}.${l}`}async function rr(n){let r=new TextEncoder().encode(n),e=await crypto.subtle.digest("SHA-256",r);return D(e)}function v(n){let r=new TextEncoder().encode(n);return D(r.buffer)}function D(n){let r=new Uint8Array(n),e="";for(let t=0;t<r.length;t++)e+=String.fromCharCode(r[t]);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var tr=300*1e3,S=class{credentialBackend;callbackUrl;constructor(r){this.credentialBackend=new g,this.callbackUrl=r??`${window.location.origin}/browser/callback.html`}async authorize(r){let e=d(r),t=await this.discover(e);if(!t)return{success:!1,error:`No OAuth discovery endpoint found for '${e}'.`};if(!t.authorizationEndpoint||!t.tokenEndpoint)return{success:!1,error:`OAuth metadata incomplete for '${e}'.`};let o=x(t.dpopSigningAlgValuesSupported),a=null,s=null;if(o){let f=await k();a=f.keys,s=f.dpopKeyPair}let l=await this.credentialBackend.get(e),i=l?.clientId??null,c=l?.clientSecret??null;if(!i&&t.registrationEndpoint){let f=await this.registerClient(t.registrationEndpoint);if(!f)return{success:!1,error:`Dynamic client registration failed for '${e}'.`};i=f.clientId,c=f.clientSecret??null}if(!i)return{success:!1,error:`No OAuth client credentials for '${e}'.`};let m=nr(),p=await or(m),R=sr(),A=ir(t.authorizationEndpoint,i,this.callbackUrl,R,p),y=await this.openAuthPopup(A,R);if(!y)return{success:!1,error:"Authorization timed out or was cancelled."};if(y.error)return{success:!1,error:`Authorization failed: ${y.error}`};if(!y.code)return{success:!1,error:"No authorization code received."};if(y.state!==R)return{success:!1,error:"State mismatch \u2014 possible CSRF attack."};let P=await this.exchangeCode(t.tokenEndpoint,i,c,y.code,this.callbackUrl,m,a);if(!P)return{success:!1,error:"Token exchange failed."};let T={clientId:i,clientSecret:c,accessToken:P.accessToken??null,refreshToken:P.refreshToken??null,expiresAt:P.expiresIn?new Date(Date.now()+P.expiresIn*1e3).toISOString():null,tokenEndpoint:t.tokenEndpoint,dpopKeyPair:s};return await this.credentialBackend.store(e,T),{success:!0,host:e}}async getCredentialWithKeys(r){let e=await this.credentialBackend.get(r);if(!e)return null;let t=null;return e.dpopKeyPair&&(t=await b(e.dpopKeyPair)),{credential:e,dpopKeys:t}}async logout(r){let e=d(r);return await this.credentialBackend.remove(e),{success:!0,host:e}}async listAuthenticated(){return this.credentialBackend.list()}async discover(r){for(let e of[`https://${r}/.well-known/oauth-authorization-server`,`https://${r}/.well-known/openid-configuration`])try{let t=await fetch(e);if(!t.ok)continue;let o=await t.json();return{issuer:w(o.issuer),authorizationEndpoint:w(o.authorization_endpoint),tokenEndpoint:w(o.token_endpoint),registrationEndpoint:w(o.registration_endpoint),revocationEndpoint:w(o.revocation_endpoint),dpopSigningAlgValuesSupported:I(o.dpop_signing_alg_values_supported),codeChallengeMethodsSupported:I(o.code_challenge_methods_supported)}}catch{continue}return null}async registerClient(r){try{let e=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_name:"Kanonak Browser",redirect_uris:[this.callbackUrl],grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"})});if(!e.ok)return null;let t=await e.json(),o=t.client_id;return o?{clientId:o,clientSecret:t.client_secret}:null}catch{return null}}openAuthPopup(r,e){return new Promise(t=>{let o=window.open(r,"kanonak-auth","width=500,height=700,menubar=no,toolbar=no,location=yes,status=no");if(!o){t(null);return}let a=setTimeout(()=>{i(),t(null)},tr),s=c=>{c.origin===window.location.origin&&(!c.data||c.data.type!=="kanonak-auth-callback"||(i(),t({code:c.data.code??void 0,state:c.data.state??void 0,error:c.data.error??void 0})))},l=setInterval(()=>{o.closed&&(i(),t(null))},500),i=()=>{clearTimeout(a),clearInterval(l),window.removeEventListener("message",s);try{o.close()}catch{}};window.addEventListener("message",s)})}async exchangeCode(r,e,t,o,a,s,l){let i=new URLSearchParams({grant_type:"authorization_code",client_id:e,code:o,redirect_uri:a,code_verifier:s});t&&i.set("client_secret",t);let c={"Content-Type":"application/x-www-form-urlencoded"};l&&(c.DPoP=await K(l,"POST",r));try{let m=await fetch(r,{method:"POST",headers:c,body:i.toString()});if(!m.ok)return null;let p=await m.json();return{accessToken:p.access_token,refreshToken:p.refresh_token,expiresIn:typeof p.expires_in=="number"?p.expires_in:void 0}}catch{return null}}};function nr(){let n=new Uint8Array(32);return crypto.getRandomValues(n),B(n.buffer)}async function or(n){let r=new TextEncoder().encode(n),e=await crypto.subtle.digest("SHA-256",r);return B(e)}function sr(){let n=new Uint8Array(16);return crypto.getRandomValues(n),B(n.buffer)}function ir(n,r,e,t,o){let a=new URLSearchParams({client_id:r,response_type:"code",redirect_uri:e,state:t,code_challenge:o,code_challenge_method:"S256"});return`${n}?${a}`}function B(n){let r=new Uint8Array(n),e="";for(let t=0;t<r.length;t++)e+=String.fromCharCode(r[t]);return btoa(e).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function w(n){return typeof n=="string"?n:null}function I(n){return Array.isArray(n)?n.filter(r=>typeof r=="string"):null}export{Ne as AmbiguousReferenceRule,se as BooleanStatement,g as BrowserCredentialBackend,S as BrowserOAuthFlow,Fe as ClassDefinitionRule,Ie as ClassHierarchyCycleRule,X as DefinedKanonak,Me as DefinitionPropertyReferenceRule,ge as EdgeType,Y as EmbeddedKanonak,je as EmbeddedKanonakTypeRule,ae as EmbeddedStatement,me as GraphBuilder,F as HttpKanonakDocumentRepository,ve as ImportExistenceRule,H as InMemoryKanonakDocumentRepository,Ue as InstancePropertyReferenceRule,G as Kanonak,we as KanonakDocumentPositions,pe as KanonakObjectParser,Xe as KanonakObjectValidator,q as KanonakParser,Z as KanonakUri,ke as KanonakUriBuilder,ce as ListStatement,Ge as MarkdownLinkRule,le as MarkdownStatement,$e as NamespaceImportCycleRule,De as NamespacePrefixRule,fe as NodeType,oe as NumberStatement,He as ObjectPropertyImportRule,qe as ObjectPropertyValueValidationRule,Se as OntologyValidationError,Ke as OntologyValidationResult,Le as PropertyDomainRule,Ae as PropertyHierarchyCycleRule,Pe as PropertyMetadata,Je as PropertyRangeReferenceRule,Te as PropertyRangeRequiredRule,Ce as PropertyTypeSpecificityRule,We as PropertyValueTypeRule,L as PublisherConfigResolver,W as PublisherIndex,ee as ReferenceKanonak,ie as ReferenceStatement,Be as ResourceNamingRule,ue as ResourceResolver,ye as ResourceTypeClassifier,te as ScalarStatement,re as Statement,ne as StringStatement,Oe as SubClassOfReferenceRule,Ve as SubPropertyOfReferenceRule,Q as SubjectKanonak,Ee as SubjectKanonakTypeRequiredRule,de as TypeResolver,_e as UnresolvedReferenceRule,Re as ValidationContext,xe as ValidationSeverity,ze as XsdImportRule,x as browserServerSupportsDPoP,Ye as buildOntologyModel,O as compareVersions,K as createBrowserDPoPProof,U as createVersion,Qe as findDerivation,be as findInstancesByType,$ as formatVersion,k as generateBrowserDPoPKeyPair,_ as generateBrowserDPoPKeys,E as hasValidToken,b as importDPoPKeys,z as isCompatibleVersion,C as isExpired,N as isMajorCompatible,d as normalizeHost,M as parseVersionString,he as parseWithPositions,J as pickHighestDocument,V as versionsEqual};
@@ -0,0 +1,2 @@
1
+ import{a as u}from"./chunk-SC5M74NM.js";import{a as y}from"./chunk-NJ3AZYQD.js";import{e as v}from"./chunk-2ACBWC7K.js";var F="https://{publisher}/index.txt",x="https://{publisher}/{package}/{version}.kan.yml",k={version:1};function A(c){return{version:1,index:F.replaceAll("{publisher}",c),package:x.replaceAll("{publisher}",c),auth:"none"}}var f=class{constructor(e){this.fetchFn=e}fetchFn;cache=new Map;getConfig(e){let n=this.cache.get(e);return n||(n=this.fetchConfig(e),this.cache.set(e,n),n.catch(()=>{this.cache.get(e)===n&&this.cache.delete(e)})),n}async fetchConfig(e){let n=`https://${e}/.well-known/kanonak.json`,r;try{r=await(this.fetchFn?this.fetchFn(n,e):fetch(n))}catch{return k}if(r.status===404)return k;if(!r.ok)throw new Error(`Failed to fetch publisher config: ${n} (${r.status} ${r.statusText})`);let t=await r.json();if(typeof t.version!="number")throw new Error(`Invalid publisher config at ${n}: missing or invalid "version" field`);let s={version:t.version};return typeof t.index=="string"&&(s.index=t.index),typeof t.package=="string"&&(s.package=t.package),(t.auth==="none"||t.auth==="oauth"||t.auth==="bearer")&&(s.auth=t.auth),Array.isArray(t.render)&&t.render.every(i=>typeof i=="string")&&(s.render=t.render),typeof t.resolveByRedirect=="boolean"&&(s.resolveByRedirect=t.resolveByRedirect),s}resolveIndexUrl(e,n){let r=n.index??F;return w(r,{publisher:e})}resolvePackageUrl(e,n,r,t){let s=t.package??x;return w(s,{publisher:e,package:n,version:r})}};function w(c,e){let n=c;for(let[t,s]of Object.entries(e))n=n.replaceAll(`{${t}}`,s);let r=n.match(/\{[a-z]+\}/);if(r)throw new Error(`Unresolved variable ${r[0]} in URL template: ${c}`);return n}import{VersionOperator as m}from"@kanonak-protocol/types/document/models/enums";var l=class c{indexCache=new Map;configResolver;fetchFn;constructor(e){this.configResolver=e?.configResolver??new f(e?.fetchFn),this.fetchFn=e?.fetchFn}async resolveVersion(e,n){let r=await this.getPackageVersions(e,n.packageName);if(r.length===0)return null;let t=r.filter(s=>this.isVersionCompatible(s,n.version,n.versionOperator));return t.length===0?null:(t.sort((s,i)=>this.compareVersionStrings(i,s)),t[0])}async getHighestVersion(e,n){let r=await this.getPackageVersions(e,n);return r.length===0?null:[...r].sort((s,i)=>this.compareVersionStrings(i,s))[0]}async listLatestPackages(e){let n=await this.getIndex(e),r=[];for(let[t,s]of n){if(s.length===0)continue;let i=[...s].sort((o,a)=>this.compareVersionStrings(a,o));r.push({packageName:t,version:i[0]})}return r.sort((t,s)=>t.packageName.localeCompare(s.packageName)),r}async getPackageUrl(e,n,r){let t=await this.configResolver.getConfig(e);return this.configResolver.resolvePackageUrl(e,n,r,t)}getConfig(e){return this.configResolver.getConfig(e)}async getPackageVersions(e,n){return(await this.getIndex(e)).get(n)??[]}getIndex(e){let n=this.indexCache.get(e);return n||(n=this.fetchIndex(e),this.indexCache.set(e,n),n.catch(()=>{this.indexCache.get(e)===n&&this.indexCache.delete(e)})),n}async fetchIndex(e){let n=await this.configResolver.getConfig(e),r=this.configResolver.resolveIndexUrl(e,n),t=this.fetchFn?await this.fetchFn(r,e):await fetch(r);if(!t.ok)throw new Error(`Failed to fetch publisher index: ${r} (${t.status} ${t.statusText})`);let s=await t.text();return c.parseIndex(s)}static parseIndex(e){let n=new Map;for(let r of e.split(`
2
+ `)){let t=r.trim();if(!t||t.startsWith("#"))continue;let s=t.indexOf("/");if(s===-1)continue;let i=t.substring(0,s),o=t.substring(s+1);if(!i||!o)continue;let a=n.get(i);a?a.push(o):n.set(i,[o])}return n}isVersionCompatible(e,n,r){let t=c.parseVersion(e);if(!t)return!1;switch(r){case m.Any:return!0;case m.Exact:return t.major===n.major&&t.minor===n.minor&&t.patch===n.patch;case m.Compatible:return t.major===n.major&&t.minor===n.minor&&t.patch>=n.patch;case m.Major:return t.major!==n.major?!1:t.minor>n.minor?!0:t.minor===n.minor?t.patch>=n.patch:!1;default:return!1}}static parseVersion(e){let n=e.split(".");if(n.length<2)return null;let r=parseInt(n[0],10),t=parseInt(n[1],10),s=n.length>=3?parseInt(n[2],10):0;return isNaN(r)||isNaN(t)||isNaN(s)?null:{major:r,minor:t,patch:s}}compareVersionStrings(e,n){let r=c.parseVersion(e),t=c.parseVersion(n);return!r&&!t?0:r?t?r.major!==t.major?r.major-t.major:r.minor!==t.minor?r.minor-t.minor:r.patch-t.patch:1:-1}};import{VersionOperator as C}from"@kanonak-protocol/types/document/models/enums";var P=class{parser=new y;publisherIndex;documents=new Map;contentCache=new Map;fetchFn;onFetch;getFromCache;constructor(e){this.onFetch=e?.onFetch,this.getFromCache=e?.getFromCache,this.fetchFn=e?.fetchFn,this.publisherIndex=e?.fetchFn?new l({fetchFn:e.fetchFn}):new l}async getHighestCompatibleVersionAsync(e,n){if((await this.publisherIndex.getConfig(e)).resolveByRedirect)return this.resolveByRedirect(e,n);let t=await this.publisherIndex.resolveVersion(e,n);if(!t)return null;let s=`${e}/${n.packageName}@${t}`,i=this.documents.get(s);if(i)return i;if(this.getFromCache){let p=this.getFromCache(e,n.packageName,t);if(p){let d=this.parser.parse(p);return u(d,e,n.packageName,t),this.documents.set(s,d),this.contentCache.set(s,p),d}}let o=await this.publisherIndex.getPackageUrl(e,n.packageName,t),a=this.fetchFn?await this.fetchFn(o,e):await fetch(o);if(!a.ok)throw new Error(`Failed to fetch Kanonak package: ${o} (${a.status} ${a.statusText})`);let g=await a.text(),h=this.parser.parse(g);return u(h,e,n.packageName,t),this.onFetch&&this.onFetch(e,n.packageName,t,g),this.documents.set(s,h),this.contentCache.set(s,g),h}async resolveByRedirect(e,n){let r=n.packageName,s=n.versionOperator===C.Exact?await this.publisherIndex.getPackageUrl(e,r,v(n.version)):`https://${e}/${r}.kan.yml`,i=await this.fetchFollowing(s,e);if(!i)return null;let o=this.parser.parse(i.content),a=o.metadata.namespace_;if(!a||!a.version)throw new Error(`Producer origin returned a package with no namespace/version for ${e}/${r}`);let g=v(a.version);u(o,e,r,g);let h=`${e}/${r}@${g}`;return this.onFetch&&this.onFetch(e,r,g,i.content),this.documents.set(h,o),this.contentCache.set(h,i.content),o}async fetchFollowing(e,n,r=4){let t=e;for(let s=0;s<r;s++){let i=this.fetchFn?await this.fetchFn(t,n):await fetch(t,{redirect:"manual"});if(i.status===301||i.status===302){let o=i.headers.get("location");if(!o)throw new Error(`Redirect with no Location header from ${t}`);t=new URL(o,t).toString();continue}if(i.status===404)return null;if(!i.ok)throw new Error(`Failed to fetch Kanonak package: ${t} (${i.status} ${i.statusText})`);return{url:t,content:await i.text()}}throw new Error(`Too many redirects resolving ${e}`)}async getAllDocumentsAsync(){return Array.from(this.documents.values())}async getDocumentAsync(e){return this.documents.get(e)??null}async getDocumentsByNamespaceAsync(e,n){return Array.from(this.documents.values()).filter(r=>{let t=r.metadata.namespace_;return t&&t.publisher===e&&t.package_===n})}async saveDocumentAsync(e,n){throw new Error("HttpKanonakDocumentRepository is read-only")}async deleteDocumentAsync(e){throw new Error("HttpKanonakDocumentRepository is read-only")}async clearNamespaceAsync(e,n){throw new Error("HttpKanonakDocumentRepository is read-only")}async getAllDocumentReferencesAsync(){return[]}async getDocumentContentAsync(e){return this.contentCache.get(e)??null}async getDocumentUriAsync(e){let n=e.match(/^(.+?)\/(.+?)@(.+)$/);if(!n)return null;let[,r,t,s]=n;return this.publisherIndex.getPackageUrl(r,t,s)}};export{A as a,f as b,l as c,P as d};
@@ -1 +1 @@
1
- import{d as v}from"./chunk-F26XWM5K.js";import{a as w}from"./chunk-4NO7MHS7.js";import{a as f}from"./chunk-NJ3AZYQD.js";import{c as A,d as R,g as b,h as F,i as S}from"./chunk-2ACBWC7K.js";import*as i from"fs/promises";import*as c from"path";import{pathToFileURL as x}from"url";import{VersionOperator as P}from"@kanonak-protocol/types/document/models/enums";var y=class{rootPath;recursive;parser;documentCache;filePathsByIdentifier;cacheInitialized=!1;cacheInitPromise=null;parsingErrors=new Map;constructor(e,t=!0,n){if(!e||e.trim().length===0)throw new Error("Root path cannot be null or empty");this.rootPath=c.resolve(e),this.recursive=t,this.parser=n??new f,this.documentCache=new Map,this.filePathsByIdentifier=new Map}async getAllDocumentsAsync(){await this.ensureCacheInitialized();let e=new Set(this.documentCache.values());return Array.from(e)}async getDocumentAsync(e){await this.ensureCacheInitialized();let t=this.documentCache.get(e);if(t)return t;let n=c.join(this.rootPath,e);if(t=this.documentCache.get(n),t)return t;for(let o of[".kan.yml",".yml",".yaml"])if(!e.endsWith(o)){let s=e+o;if(t=this.documentCache.get(s),t)return t;let a=c.join(this.rootPath,s);if(t=this.documentCache.get(a),t)return t}return null}async getDocumentsByNamespaceAsync(e,t){await this.ensureCacheInitialized();let n=new Set(this.documentCache.values());return Array.from(n).filter(o=>o.metadata.namespace_?.publisher===e&&o.metadata.namespace_?.package_===t)}async getHighestCompatibleVersionAsync(e,t){await this.ensureCacheInitialized();let n=new Set(this.documentCache.values()),o=Array.from(n).filter(a=>a.metadata?.namespace_?.publisher===e&&a.metadata?.namespace_?.package_===t.packageName&&a.metadata?.namespace_?.version!==void 0);if(o.length===0)return null;let s=o.filter(a=>{let r=a.metadata.namespace_.version;switch(t.versionOperator){case P.Exact:return R(r,t.version);case P.Compatible:return F(r,t.version);case P.Major:return S(r,t.version);case P.Any:return A(r,t.minVersion)>=0;default:return!1}});return s.length===0?null:(s.sort((a,r)=>{let m=a.metadata.namespace_.version,l=r.metadata.namespace_.version;return A(l,m)}),s[0])}async saveDocumentAsync(e,t){let n,o=e.metadata.namespace_?.toString();if(o&&o.includes("@")&&o.includes("/")){let m=o.split("/"),l=m[0],h=m[1].replace("@","@")+".kan.yml";n=c.join(this.rootPath,l,h)}else n=c.join(this.rootPath,t),!n.endsWith(".yml")&&!n.endsWith(".yaml")&&!n.endsWith(".kan.yml")&&(n+=".kan.yml");let s=c.dirname(n);await i.mkdir(s,{recursive:!0});let a=this.parser.save(e);await i.writeFile(n,a,"utf8"),o&&this.documentCache.set(o,e),this.documentCache.set(n,e);let r=c.relative(this.rootPath,n);this.documentCache.set(r,e)}async deleteDocumentAsync(e){let t=await this.getDocumentAsync(e);if(!t)return;let n=this.filePathsByIdentifier.get(e);if(!n)return;try{await i.unlink(n)}catch{}let o=t.metadata.namespace_?.toString();o&&this.documentCache.delete(o),this.documentCache.delete(e),this.documentCache.delete(n);let s=c.relative(this.rootPath,n);this.documentCache.delete(s)}async clearNamespaceAsync(e,t){await this.ensureCacheInitialized();let n=[];for(let[s,a]of this.documentCache.entries()){let r=a.metadata.namespace_?.toString()||"";r.includes(e)&&r.includes(t)&&n.push([s,a])}let o=c.join(this.rootPath,e);try{let s=await i.readdir(o);for(let a of s)a.includes(t)&&a.endsWith(".kan.yml")&&await i.unlink(c.join(o,a))}catch{}for(let[s]of n)this.documentCache.delete(s)}async getAllDocumentReferencesAsync(){await this.ensureCacheInitialized();let e=new Set(this.filePathsByIdentifier.values()),t=[];for(let n of e){let o=x(n).toString(),s;for(let[m,l]of this.documentCache.entries())if(this.filePathsByIdentifier.get(m)===n&&l.metadata.namespace_){s=l.metadata.namespace_.toString();break}let a=s??c.relative(this.rootPath,n),r=this.parsingErrors.has(n);t.push({identifier:a,uri:o,hasParseError:r})}return t}async getDocumentContentAsync(e){await this.ensureCacheInitialized();let t=this.filePathsByIdentifier.get(e);if(!t)try{await i.access(e),t=e}catch{let n=c.join(this.rootPath,e);try{await i.access(n),t=n}catch{return null}}try{return await i.readFile(t,"utf8")}catch{return null}}async getDocumentUriAsync(e){await this.ensureCacheInitialized();let t=this.filePathsByIdentifier.get(e);if(!t)try{await i.access(e),t=e}catch{let n=c.join(this.rootPath,e);try{await i.access(n),t=n}catch{return null}}return x(t).toString()}async refreshAsync(){this.documentCache.clear(),this.filePathsByIdentifier.clear(),this.parsingErrors.clear(),this.cacheInitialized=!1,this.cacheInitPromise=null,await this.ensureCacheInitialized()}async ensureCacheInitialized(){if(!this.cacheInitialized){if(this.cacheInitPromise){await this.cacheInitPromise;return}this.cacheInitPromise=this.loadDocuments(),await this.cacheInitPromise,this.cacheInitialized=!0}}async loadDocuments(){try{await i.mkdir(this.rootPath,{recursive:!0})}catch{}let t=(await this.findYamlFiles(this.rootPath,this.recursive)).map(async o=>{try{let s=await i.readFile(o,"utf8"),a=this.parser.parse(s);return{filePath:o,document:a,error:null}}catch(s){return{filePath:o,document:null,error:s instanceof Error?s.message:String(s)}}}),n=await Promise.all(t);for(let{filePath:o,document:s,error:a}of n){let r=c.relative(this.rootPath,o);if(s&&s.metadata.namespace_){let m=s.metadata.namespace_.toString();this.documentCache.set(m,s),this.documentCache.set(o,s),this.documentCache.set(r,s),this.filePathsByIdentifier.set(m,o),this.filePathsByIdentifier.set(o,o),this.filePathsByIdentifier.set(r,o)}else this.filePathsByIdentifier.set(o,o),this.filePathsByIdentifier.set(r,o);a&&this.parsingErrors.set(o,a)}}async findYamlFiles(e,t){let n=[];try{let o=await i.readdir(e,{withFileTypes:!0});for(let s of o){let a=c.join(e,s.name);if(s.isDirectory()&&t){let r=await this.findYamlFiles(a,t);n.push(...r)}else s.isFile()&&s.name.endsWith(".kan.yml")&&n.push(a)}}catch{}return n}};import*as g from"fs";var _=(n=>(n.NotFound="NotFound",n.Workspace="Workspace",n.Cache="Cache",n))(_||{}),k=class{cache;workspace;constructor(e,t,n){let o=n??new f;g.existsSync(e)||g.mkdirSync(e,{recursive:!0}),g.existsSync(t)||g.mkdirSync(t,{recursive:!0}),this.cache=new y(e,!0,o),this.workspace=new y(t,!0,o)}getCache(){return this.cache}getWorkspace(){return this.workspace}async getAllDocumentsAsync(){let e=await this.workspace.getAllDocumentsAsync(),t=await this.cache.getAllDocumentsAsync(),n=new Map;for(let o of t)if(o.metadata.namespace_){let s=o.metadata.namespace_.toString();n.set(s,o)}for(let o of e)if(o.metadata.namespace_){let s=o.metadata.namespace_.toString();n.set(s,o)}return Array.from(n.values())}async getDocumentAsync(e){let t=await this.workspace.getDocumentAsync(e);return t||await this.cache.getDocumentAsync(e)}async getDocumentsByNamespaceAsync(e,t){let n=await this.workspace.getDocumentsByNamespaceAsync(e,t),o=await this.cache.getDocumentsByNamespaceAsync(e,t),s=new Map;for(let a of o)if(a.metadata.namespace_?.version){let r=a.metadata.namespace_.version.toString();s.set(r,a)}for(let a of n)if(a.metadata.namespace_?.version){let r=a.metadata.namespace_.version.toString();s.set(r,a)}return Array.from(s.values())}async getHighestCompatibleVersionAsync(e,t){let n=await this.workspace.getHighestCompatibleVersionAsync(e,t);return n||await this.cache.getHighestCompatibleVersionAsync(e,t)}async saveDocumentAsync(e,t){await this.workspace.saveDocumentAsync(e,t)}async saveToCacheAsync(e,t){await this.cache.saveDocumentAsync(e,t)}async deleteDocumentAsync(e){await this.workspace.deleteDocumentAsync(e)}async clearNamespaceAsync(e,t){await this.workspace.clearNamespaceAsync(e,t)}async getAllDocumentReferencesAsync(){let e=await this.workspace.getAllDocumentReferencesAsync(),t=await this.cache.getAllDocumentReferencesAsync(),n=[];return n.push(...e),n.push(...t),n}async getDocumentContentAsync(e){let t=await this.workspace.getDocumentContentAsync(e);return t||await this.cache.getDocumentContentAsync(e)}async getDocumentUriAsync(e){let t=await this.workspace.getDocumentUriAsync(e);return t||await this.cache.getDocumentUriAsync(e)}async getDocumentLocationAsync(e){return await this.workspace.getDocumentAsync(e)?"Workspace":await this.cache.getDocumentAsync(e)?"Cache":"NotFound"}};import{homedir as $}from"os";import{join as B}from"path";function d(){let u=process.env.KANONAK_PACKAGE_CACHE;return u||B($(),".kanonak","packages")}var C=class u{static createComposite(e,t,n){let o=e??d(),s=t??".";return new k(o,s,n)}static createFromEnvironment(e){let t=d(),n=process.env.KANONAK_WORKSPACE_PATH??".";return u.createComposite(t,n,e)}};var D=class{repos;constructor(...e){this.repos=e}async getHighestCompatibleVersionAsync(e,t){for(let n of this.repos)try{let o=await n.getHighestCompatibleVersionAsync(e,t);if(o)return o}catch{}return null}async getAllDocumentsAsync(){let e=[],t=new Set;for(let n of this.repos)try{for(let o of await n.getAllDocumentsAsync()){let s=o.metadata?.namespace_,a=s?s.version?`${s.publisher}/${s.package_}@${s.version.major}.${s.version.minor}.${s.version.patch}`:`${s.publisher}/${s.package_}`:void 0;if(a!==void 0){if(t.has(a))continue;t.add(a)}e.push(o)}}catch{}return e}async getDocumentAsync(e){for(let t of this.repos)try{let n=await t.getDocumentAsync(e);if(n)return n}catch{}return null}async getDocumentsByNamespaceAsync(e,t){for(let n of this.repos)try{let o=await n.getDocumentsByNamespaceAsync(e,t);if(o.length>0)return o}catch{}return[]}async saveDocumentAsync(e,t){await this.repos[0].saveDocumentAsync(e,t)}async deleteDocumentAsync(e){await this.repos[0].deleteDocumentAsync(e)}async clearNamespaceAsync(e,t){await this.repos[0].clearNamespaceAsync(e,t)}async getAllDocumentReferencesAsync(){return this.repos[0].getAllDocumentReferencesAsync()}async getDocumentContentAsync(e){for(let t of this.repos)try{let n=await t.getDocumentContentAsync(e);if(n)return n}catch{}return null}async getDocumentUriAsync(e){for(let t of this.repos)try{let n=await t.getDocumentUriAsync(e);if(n)return n}catch{}return null}};import{VersionOperator as H}from"@kanonak-protocol/types/document/models/enums";var K=class{constructor(e,t){this.base=e;this.lock=t}base;lock;pinnedVersion(e,t){return this.lock.packages[`${e}/${t}`]?.version}async getHighestCompatibleVersionAsync(e,t){let n=this.pinnedVersion(e,t.packageName);if(n){let o=b(n);if(o){let s={...t,versionOperator:H.Exact,version:o};return this.base.getHighestCompatibleVersionAsync(e,s)}}return this.base.getHighestCompatibleVersionAsync(e,t)}async getDocumentsByNamespaceAsync(e,t){let n=await this.base.getDocumentsByNamespaceAsync(e,t),o=this.pinnedVersion(e,t);return o?n.filter(s=>{let a=s.metadata.namespace_?.version;return a?`${a.major}.${a.minor}.${a.patch}`===o:!1}):n}getAllDocumentsAsync(){return this.base.getAllDocumentsAsync()}getDocumentAsync(e){return this.base.getDocumentAsync(e)}saveDocumentAsync(e,t){return this.base.saveDocumentAsync(e,t)}deleteDocumentAsync(e){return this.base.deleteDocumentAsync(e)}clearNamespaceAsync(e,t){return this.base.clearNamespaceAsync(e,t)}getAllDocumentReferencesAsync(){return this.base.getAllDocumentReferencesAsync()}getDocumentContentAsync(e){return this.base.getDocumentContentAsync(e)}getDocumentUriAsync(e){return this.base.getDocumentUriAsync(e)}};import{readFileSync as V,readdirSync as j}from"fs";import{join as N}from"path";var E=new Set(["node_modules",".kanonak",".git","_site","build",".stage"]);function I(u,e=[]){for(let t of j(u,{withFileTypes:!0}))t.isDirectory()?E.has(t.name)||I(N(u,t.name),e):t.name.endsWith(".kan.yml")&&e.push(N(u,t.name));return e}async function z(u,e=new f,t={}){let n=new w(e);for(let m of I(u))try{let l=e.parse(V(m,"utf-8")),p=l.metadata?.namespace_,h=p?.version;p&&h&&await n.saveDocumentAsync(l,`${p.publisher}/${p.package_}@${h.major}.${h.minor}.${h.patch}`)}catch{}let o=new y(d(),!0,e),s=new Map,a=t.httpCache??{getFromCache:(m,l,p)=>s.get(`${m}|${l}|${p}`)??null,onFetch:(m,l,p,h)=>{s.set(`${m}|${l}|${p}`,h)}},r=new v({getFromCache:a.getFromCache,onFetch:a.onFetch});return new D(n,o,r)}export{y as a,_ as b,k as c,d,C as e,D as f,K as g,I as h,z as i};
1
+ import{d as v}from"./chunk-MFQUKORC.js";import{a as w}from"./chunk-4NO7MHS7.js";import{a as f}from"./chunk-NJ3AZYQD.js";import{c as A,d as R,g as b,h as F,i as S}from"./chunk-2ACBWC7K.js";import*as i from"fs/promises";import*as c from"path";import{pathToFileURL as x}from"url";import{VersionOperator as P}from"@kanonak-protocol/types/document/models/enums";var y=class{rootPath;recursive;parser;documentCache;filePathsByIdentifier;cacheInitialized=!1;cacheInitPromise=null;parsingErrors=new Map;constructor(e,t=!0,n){if(!e||e.trim().length===0)throw new Error("Root path cannot be null or empty");this.rootPath=c.resolve(e),this.recursive=t,this.parser=n??new f,this.documentCache=new Map,this.filePathsByIdentifier=new Map}async getAllDocumentsAsync(){await this.ensureCacheInitialized();let e=new Set(this.documentCache.values());return Array.from(e)}async getDocumentAsync(e){await this.ensureCacheInitialized();let t=this.documentCache.get(e);if(t)return t;let n=c.join(this.rootPath,e);if(t=this.documentCache.get(n),t)return t;for(let o of[".kan.yml",".yml",".yaml"])if(!e.endsWith(o)){let s=e+o;if(t=this.documentCache.get(s),t)return t;let a=c.join(this.rootPath,s);if(t=this.documentCache.get(a),t)return t}return null}async getDocumentsByNamespaceAsync(e,t){await this.ensureCacheInitialized();let n=new Set(this.documentCache.values());return Array.from(n).filter(o=>o.metadata.namespace_?.publisher===e&&o.metadata.namespace_?.package_===t)}async getHighestCompatibleVersionAsync(e,t){await this.ensureCacheInitialized();let n=new Set(this.documentCache.values()),o=Array.from(n).filter(a=>a.metadata?.namespace_?.publisher===e&&a.metadata?.namespace_?.package_===t.packageName&&a.metadata?.namespace_?.version!==void 0);if(o.length===0)return null;let s=o.filter(a=>{let r=a.metadata.namespace_.version;switch(t.versionOperator){case P.Exact:return R(r,t.version);case P.Compatible:return F(r,t.version);case P.Major:return S(r,t.version);case P.Any:return A(r,t.minVersion)>=0;default:return!1}});return s.length===0?null:(s.sort((a,r)=>{let m=a.metadata.namespace_.version,l=r.metadata.namespace_.version;return A(l,m)}),s[0])}async saveDocumentAsync(e,t){let n,o=e.metadata.namespace_?.toString();if(o&&o.includes("@")&&o.includes("/")){let m=o.split("/"),l=m[0],h=m[1].replace("@","@")+".kan.yml";n=c.join(this.rootPath,l,h)}else n=c.join(this.rootPath,t),!n.endsWith(".yml")&&!n.endsWith(".yaml")&&!n.endsWith(".kan.yml")&&(n+=".kan.yml");let s=c.dirname(n);await i.mkdir(s,{recursive:!0});let a=this.parser.save(e);await i.writeFile(n,a,"utf8"),o&&this.documentCache.set(o,e),this.documentCache.set(n,e);let r=c.relative(this.rootPath,n);this.documentCache.set(r,e)}async deleteDocumentAsync(e){let t=await this.getDocumentAsync(e);if(!t)return;let n=this.filePathsByIdentifier.get(e);if(!n)return;try{await i.unlink(n)}catch{}let o=t.metadata.namespace_?.toString();o&&this.documentCache.delete(o),this.documentCache.delete(e),this.documentCache.delete(n);let s=c.relative(this.rootPath,n);this.documentCache.delete(s)}async clearNamespaceAsync(e,t){await this.ensureCacheInitialized();let n=[];for(let[s,a]of this.documentCache.entries()){let r=a.metadata.namespace_?.toString()||"";r.includes(e)&&r.includes(t)&&n.push([s,a])}let o=c.join(this.rootPath,e);try{let s=await i.readdir(o);for(let a of s)a.includes(t)&&a.endsWith(".kan.yml")&&await i.unlink(c.join(o,a))}catch{}for(let[s]of n)this.documentCache.delete(s)}async getAllDocumentReferencesAsync(){await this.ensureCacheInitialized();let e=new Set(this.filePathsByIdentifier.values()),t=[];for(let n of e){let o=x(n).toString(),s;for(let[m,l]of this.documentCache.entries())if(this.filePathsByIdentifier.get(m)===n&&l.metadata.namespace_){s=l.metadata.namespace_.toString();break}let a=s??c.relative(this.rootPath,n),r=this.parsingErrors.has(n);t.push({identifier:a,uri:o,hasParseError:r})}return t}async getDocumentContentAsync(e){await this.ensureCacheInitialized();let t=this.filePathsByIdentifier.get(e);if(!t)try{await i.access(e),t=e}catch{let n=c.join(this.rootPath,e);try{await i.access(n),t=n}catch{return null}}try{return await i.readFile(t,"utf8")}catch{return null}}async getDocumentUriAsync(e){await this.ensureCacheInitialized();let t=this.filePathsByIdentifier.get(e);if(!t)try{await i.access(e),t=e}catch{let n=c.join(this.rootPath,e);try{await i.access(n),t=n}catch{return null}}return x(t).toString()}async refreshAsync(){this.documentCache.clear(),this.filePathsByIdentifier.clear(),this.parsingErrors.clear(),this.cacheInitialized=!1,this.cacheInitPromise=null,await this.ensureCacheInitialized()}async ensureCacheInitialized(){if(!this.cacheInitialized){if(this.cacheInitPromise){await this.cacheInitPromise;return}this.cacheInitPromise=this.loadDocuments(),await this.cacheInitPromise,this.cacheInitialized=!0}}async loadDocuments(){try{await i.mkdir(this.rootPath,{recursive:!0})}catch{}let t=(await this.findYamlFiles(this.rootPath,this.recursive)).map(async o=>{try{let s=await i.readFile(o,"utf8"),a=this.parser.parse(s);return{filePath:o,document:a,error:null}}catch(s){return{filePath:o,document:null,error:s instanceof Error?s.message:String(s)}}}),n=await Promise.all(t);for(let{filePath:o,document:s,error:a}of n){let r=c.relative(this.rootPath,o);if(s&&s.metadata.namespace_){let m=s.metadata.namespace_.toString();this.documentCache.set(m,s),this.documentCache.set(o,s),this.documentCache.set(r,s),this.filePathsByIdentifier.set(m,o),this.filePathsByIdentifier.set(o,o),this.filePathsByIdentifier.set(r,o)}else this.filePathsByIdentifier.set(o,o),this.filePathsByIdentifier.set(r,o);a&&this.parsingErrors.set(o,a)}}async findYamlFiles(e,t){let n=[];try{let o=await i.readdir(e,{withFileTypes:!0});for(let s of o){let a=c.join(e,s.name);if(s.isDirectory()&&t){let r=await this.findYamlFiles(a,t);n.push(...r)}else s.isFile()&&s.name.endsWith(".kan.yml")&&n.push(a)}}catch{}return n}};import*as g from"fs";var _=(n=>(n.NotFound="NotFound",n.Workspace="Workspace",n.Cache="Cache",n))(_||{}),k=class{cache;workspace;constructor(e,t,n){let o=n??new f;g.existsSync(e)||g.mkdirSync(e,{recursive:!0}),g.existsSync(t)||g.mkdirSync(t,{recursive:!0}),this.cache=new y(e,!0,o),this.workspace=new y(t,!0,o)}getCache(){return this.cache}getWorkspace(){return this.workspace}async getAllDocumentsAsync(){let e=await this.workspace.getAllDocumentsAsync(),t=await this.cache.getAllDocumentsAsync(),n=new Map;for(let o of t)if(o.metadata.namespace_){let s=o.metadata.namespace_.toString();n.set(s,o)}for(let o of e)if(o.metadata.namespace_){let s=o.metadata.namespace_.toString();n.set(s,o)}return Array.from(n.values())}async getDocumentAsync(e){let t=await this.workspace.getDocumentAsync(e);return t||await this.cache.getDocumentAsync(e)}async getDocumentsByNamespaceAsync(e,t){let n=await this.workspace.getDocumentsByNamespaceAsync(e,t),o=await this.cache.getDocumentsByNamespaceAsync(e,t),s=new Map;for(let a of o)if(a.metadata.namespace_?.version){let r=a.metadata.namespace_.version.toString();s.set(r,a)}for(let a of n)if(a.metadata.namespace_?.version){let r=a.metadata.namespace_.version.toString();s.set(r,a)}return Array.from(s.values())}async getHighestCompatibleVersionAsync(e,t){let n=await this.workspace.getHighestCompatibleVersionAsync(e,t);return n||await this.cache.getHighestCompatibleVersionAsync(e,t)}async saveDocumentAsync(e,t){await this.workspace.saveDocumentAsync(e,t)}async saveToCacheAsync(e,t){await this.cache.saveDocumentAsync(e,t)}async deleteDocumentAsync(e){await this.workspace.deleteDocumentAsync(e)}async clearNamespaceAsync(e,t){await this.workspace.clearNamespaceAsync(e,t)}async getAllDocumentReferencesAsync(){let e=await this.workspace.getAllDocumentReferencesAsync(),t=await this.cache.getAllDocumentReferencesAsync(),n=[];return n.push(...e),n.push(...t),n}async getDocumentContentAsync(e){let t=await this.workspace.getDocumentContentAsync(e);return t||await this.cache.getDocumentContentAsync(e)}async getDocumentUriAsync(e){let t=await this.workspace.getDocumentUriAsync(e);return t||await this.cache.getDocumentUriAsync(e)}async getDocumentLocationAsync(e){return await this.workspace.getDocumentAsync(e)?"Workspace":await this.cache.getDocumentAsync(e)?"Cache":"NotFound"}};import{homedir as $}from"os";import{join as B}from"path";function d(){let u=process.env.KANONAK_PACKAGE_CACHE;return u||B($(),".kanonak","packages")}var C=class u{static createComposite(e,t,n){let o=e??d(),s=t??".";return new k(o,s,n)}static createFromEnvironment(e){let t=d(),n=process.env.KANONAK_WORKSPACE_PATH??".";return u.createComposite(t,n,e)}};var D=class{repos;constructor(...e){this.repos=e}async getHighestCompatibleVersionAsync(e,t){for(let n of this.repos)try{let o=await n.getHighestCompatibleVersionAsync(e,t);if(o)return o}catch{}return null}async getAllDocumentsAsync(){let e=[],t=new Set;for(let n of this.repos)try{for(let o of await n.getAllDocumentsAsync()){let s=o.metadata?.namespace_,a=s?s.version?`${s.publisher}/${s.package_}@${s.version.major}.${s.version.minor}.${s.version.patch}`:`${s.publisher}/${s.package_}`:void 0;if(a!==void 0){if(t.has(a))continue;t.add(a)}e.push(o)}}catch{}return e}async getDocumentAsync(e){for(let t of this.repos)try{let n=await t.getDocumentAsync(e);if(n)return n}catch{}return null}async getDocumentsByNamespaceAsync(e,t){for(let n of this.repos)try{let o=await n.getDocumentsByNamespaceAsync(e,t);if(o.length>0)return o}catch{}return[]}async saveDocumentAsync(e,t){await this.repos[0].saveDocumentAsync(e,t)}async deleteDocumentAsync(e){await this.repos[0].deleteDocumentAsync(e)}async clearNamespaceAsync(e,t){await this.repos[0].clearNamespaceAsync(e,t)}async getAllDocumentReferencesAsync(){return this.repos[0].getAllDocumentReferencesAsync()}async getDocumentContentAsync(e){for(let t of this.repos)try{let n=await t.getDocumentContentAsync(e);if(n)return n}catch{}return null}async getDocumentUriAsync(e){for(let t of this.repos)try{let n=await t.getDocumentUriAsync(e);if(n)return n}catch{}return null}};import{VersionOperator as H}from"@kanonak-protocol/types/document/models/enums";var K=class{constructor(e,t){this.base=e;this.lock=t}base;lock;pinnedVersion(e,t){return this.lock.packages[`${e}/${t}`]?.version}async getHighestCompatibleVersionAsync(e,t){let n=this.pinnedVersion(e,t.packageName);if(n){let o=b(n);if(o){let s={...t,versionOperator:H.Exact,version:o};return this.base.getHighestCompatibleVersionAsync(e,s)}}return this.base.getHighestCompatibleVersionAsync(e,t)}async getDocumentsByNamespaceAsync(e,t){let n=await this.base.getDocumentsByNamespaceAsync(e,t),o=this.pinnedVersion(e,t);return o?n.filter(s=>{let a=s.metadata.namespace_?.version;return a?`${a.major}.${a.minor}.${a.patch}`===o:!1}):n}getAllDocumentsAsync(){return this.base.getAllDocumentsAsync()}getDocumentAsync(e){return this.base.getDocumentAsync(e)}saveDocumentAsync(e,t){return this.base.saveDocumentAsync(e,t)}deleteDocumentAsync(e){return this.base.deleteDocumentAsync(e)}clearNamespaceAsync(e,t){return this.base.clearNamespaceAsync(e,t)}getAllDocumentReferencesAsync(){return this.base.getAllDocumentReferencesAsync()}getDocumentContentAsync(e){return this.base.getDocumentContentAsync(e)}getDocumentUriAsync(e){return this.base.getDocumentUriAsync(e)}};import{readFileSync as V,readdirSync as j}from"fs";import{join as N}from"path";var E=new Set(["node_modules",".kanonak",".git","_site","build",".stage"]);function I(u,e=[]){for(let t of j(u,{withFileTypes:!0}))t.isDirectory()?E.has(t.name)||I(N(u,t.name),e):t.name.endsWith(".kan.yml")&&e.push(N(u,t.name));return e}async function z(u,e=new f,t={}){let n=new w(e);for(let m of I(u))try{let l=e.parse(V(m,"utf-8")),p=l.metadata?.namespace_,h=p?.version;p&&h&&await n.saveDocumentAsync(l,`${p.publisher}/${p.package_}@${h.major}.${h.minor}.${h.patch}`)}catch{}let o=new y(d(),!0,e),s=new Map,a=t.httpCache??{getFromCache:(m,l,p)=>s.get(`${m}|${l}|${p}`)??null,onFetch:(m,l,p,h)=>{s.set(`${m}|${l}|${p}`,h)}},r=new v({getFromCache:a.getFromCache,onFetch:a.onFetch});return new D(n,o,r)}export{y as a,_ as b,k as c,d,C as e,D as f,K as g,I as h,z as i};
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import{a as Pn,b as wn,c as Sn,d as Cn,e as be}from"./chunk-RWEGPZ23.js";import{a as yr,c as Ce,e as He,h as ze,i as We,j as gr}from"./chunk-OOR5SVNQ.js";import{a as hn,b as kn,c as bn,d as W,e as G,f as l,g as hr}from"./chunk-KGWDV7FW.js";import{a as fr}from"./chunk-NV63IOB7.js";import"./chunk-QHABFCRC.js";import{a as zt,b as Wt,c as Gt,d as Jt,e as qt,f as en,g as tn,h as nn,i as rn}from"./chunk-MPBNEKCQ.js";import{b as Yt,c as Zt,d as Qt}from"./chunk-F26XWM5K.js";import{a as Ht}from"./chunk-4NO7MHS7.js";import{a as En,b as xn,c as In,d as vn}from"./chunk-RYOZTXI7.js";import{a as Kn,b as Dn}from"./chunk-PEUTCG3B.js";import{a as jn}from"./chunk-PEJALHXK.js";import{a as Xt}from"./chunk-SC5M74NM.js";import{A as lr,B as ur,C as pr,D as dr,M as mr,a as Nn,b as Tn,c as Ln,d as _n,e as Un,f as Fn,g as Mn,h as Hn,i as zn,j as Wn,k as Gn,l as Jn,m as qn,n as Yn,o as Zn,p as Xn,q as Qn,r as er,s as tr,t as nr,u as rr,v as or,w as ar,x as ir,y as sr,z as cr}from"./chunk-IZRPJCQW.js";import"./chunk-SHDHMKMJ.js";import{a as y,b as C,c as sn,d as Fe,e as v,f as ke,g as fn,h as yn,i as $}from"./chunk-DSHPAWJQ.js";import{a as S}from"./chunk-NJ3AZYQD.js";import{a as gn,b as Pe,c as $n,d as h,e as An,f as Vn,g as Bn,h as On}from"./chunk-UK2OIPAB.js";import{f as z,k as j,l as we,m as Se,n as Me}from"./chunk-PBNVHBS3.js";import{b as cn,c as ln,d as K,e as un,f as pn,h as dn,j as mn}from"./chunk-VKTFLHCW.js";import{a as on,b as fe,c as f,d as p,e as an,f as ye,g as R,h as ge,i as he,j as E,k as x,l as I}from"./chunk-T3JR2SV6.js";import{a as H}from"./chunk-FUUTGGJS.js";import{a as Nt,b as me,c as M,d as Tt,e as k,f as Lt,g as _t,h as Ut,i as Ft,j as Mt}from"./chunk-2ACBWC7K.js";import{a as Rn}from"./chunk-ODIECDN7.js";import{VersionOperator as Ni}from"@kanonak-protocol/types/document/models/enums";import{existsSync as Or,readFileSync as Dr}from"fs";import{homedir as Nr}from"os";import{join as Tr}from"path";import{execFile as kr}from"child_process";import{promisify as br}from"util";var J=br(kr),q="kanonak",Y="/usr/bin/security",A=class{async get(e){let t=l(e);try{let{stdout:r}=await J(Y,["find-generic-password","-s",q,"-a",t,"-w"],{timeout:1e4});try{return JSON.parse(r.trim())}catch{throw new Error(`Stored credential for '${t}' is corrupted (not valid JSON).
1
+ import{a as Pn,b as wn,c as Sn,d as Cn,e as be}from"./chunk-RWEGPZ23.js";import{a as yr,c as Ce,e as He,h as ze,i as We,j as gr}from"./chunk-OOR5SVNQ.js";import{a as hn,b as kn,c as bn,d as W,e as G,f as l,g as hr}from"./chunk-KGWDV7FW.js";import{a as fr}from"./chunk-NV63IOB7.js";import"./chunk-QHABFCRC.js";import{a as zt,b as Wt,c as Gt,d as Jt,e as qt,f as en,g as tn,h as nn,i as rn}from"./chunk-T63Q2PMS.js";import{b as Yt,c as Zt,d as Qt}from"./chunk-MFQUKORC.js";import{a as Ht}from"./chunk-4NO7MHS7.js";import{a as En,b as xn,c as In,d as vn}from"./chunk-RYOZTXI7.js";import{a as Kn,b as Dn}from"./chunk-PEUTCG3B.js";import{a as jn}from"./chunk-PEJALHXK.js";import{a as Xt}from"./chunk-SC5M74NM.js";import{A as lr,B as ur,C as pr,D as dr,M as mr,a as Nn,b as Tn,c as Ln,d as _n,e as Un,f as Fn,g as Mn,h as Hn,i as zn,j as Wn,k as Gn,l as Jn,m as qn,n as Yn,o as Zn,p as Xn,q as Qn,r as er,s as tr,t as nr,u as rr,v as or,w as ar,x as ir,y as sr,z as cr}from"./chunk-IZRPJCQW.js";import"./chunk-SHDHMKMJ.js";import{a as y,b as C,c as sn,d as Fe,e as v,f as ke,g as fn,h as yn,i as $}from"./chunk-DSHPAWJQ.js";import{a as S}from"./chunk-NJ3AZYQD.js";import{a as gn,b as Pe,c as $n,d as h,e as An,f as Vn,g as Bn,h as On}from"./chunk-UK2OIPAB.js";import{f as z,k as j,l as we,m as Se,n as Me}from"./chunk-PBNVHBS3.js";import{b as cn,c as ln,d as K,e as un,f as pn,h as dn,j as mn}from"./chunk-VKTFLHCW.js";import{a as on,b as fe,c as f,d as p,e as an,f as ye,g as R,h as ge,i as he,j as E,k as x,l as I}from"./chunk-T3JR2SV6.js";import{a as H}from"./chunk-FUUTGGJS.js";import{a as Nt,b as me,c as M,d as Tt,e as k,f as Lt,g as _t,h as Ut,i as Ft,j as Mt}from"./chunk-2ACBWC7K.js";import{a as Rn}from"./chunk-ODIECDN7.js";import{VersionOperator as Ni}from"@kanonak-protocol/types/document/models/enums";import{existsSync as Or,readFileSync as Dr}from"fs";import{homedir as Nr}from"os";import{join as Tr}from"path";import{execFile as kr}from"child_process";import{promisify as br}from"util";var J=br(kr),q="kanonak",Y="/usr/bin/security",A=class{async get(e){let t=l(e);try{let{stdout:r}=await J(Y,["find-generic-password","-s",q,"-a",t,"-w"],{timeout:1e4});try{return JSON.parse(r.trim())}catch{throw new Error(`Stored credential for '${t}' is corrupted (not valid JSON).
2
2
  Run 'kanonak logout ${t}' then 'kanonak login ${t}' to fix.`)}}catch(r){if(Ge(r,44))return null;throw new Error(`macOS Keychain read failed for '${t}': ${Z(r)}
3
3
  The Keychain may be locked or inaccessible.
4
4
  Try unlocking it via Keychain Access.app or running 'security unlock-keychain'.`)}}async store(e,t){let r=l(e),o=JSON.stringify(t);try{await J(Y,["add-generic-password","-s",q,"-a",r,"-U","-w",o],{timeout:1e4})}catch(a){throw new Error(`macOS Keychain write failed for '${r}': ${Z(a)}
@@ -1,3 +1,4 @@
1
+ import type { AuthenticatedFetchFn } from '../auth/index.js';
1
2
  export interface PublisherConfig {
2
3
  version: number;
3
4
  index?: string;
@@ -43,7 +44,9 @@ export interface PublisherConfig {
43
44
  */
44
45
  export declare function defaultPublisherConfig(publisher: string): PublisherConfig;
45
46
  export declare class PublisherConfigResolver {
47
+ private readonly fetchFn?;
46
48
  private readonly cache;
49
+ constructor(fetchFn?: AuthenticatedFetchFn | undefined);
47
50
  getConfig(publisher: string): Promise<PublisherConfig>;
48
51
  private fetchConfig;
49
52
  resolveIndexUrl(publisher: string, config: PublisherConfig): string;
@@ -1 +1 @@
1
- import{b as e,c as r,d as n}from"../chunk-F26XWM5K.js";import{a as o}from"../chunk-4NO7MHS7.js";import"../chunk-SC5M74NM.js";import"../chunk-NJ3AZYQD.js";import"../chunk-2ACBWC7K.js";export{n as HttpKanonakDocumentRepository,o as InMemoryKanonakDocumentRepository,e as PublisherConfigResolver,r as PublisherIndex};
1
+ import{b as e,c as r,d as n}from"../chunk-MFQUKORC.js";import{a as o}from"../chunk-4NO7MHS7.js";import"../chunk-SC5M74NM.js";import"../chunk-NJ3AZYQD.js";import"../chunk-2ACBWC7K.js";export{n as HttpKanonakDocumentRepository,o as InMemoryKanonakDocumentRepository,e as PublisherConfigResolver,r as PublisherIndex};
@@ -1 +1 @@
1
- import{a as b,b as c,c as d,d as e,e as f,f as k,g as l,h as m,i as n}from"../chunk-MPBNEKCQ.js";import{a as g,b as h,c as i,d as j}from"../chunk-F26XWM5K.js";import{a}from"../chunk-4NO7MHS7.js";import"../chunk-SC5M74NM.js";import"../chunk-NJ3AZYQD.js";import"../chunk-2ACBWC7K.js";export{d as CompositeKanonakDocumentRepository,c as DocumentLocation,b as FileSystemKanonakDocumentRepository,j as HttpKanonakDocumentRepository,a as InMemoryKanonakDocumentRepository,k as LocalFirstRepository,l as LockAwareRepository,h as PublisherConfigResolver,i as PublisherIndex,f as RepositoryFactory,n as buildLocalFirstRepository,m as collectKanonakFiles,g as defaultPublisherConfig,e as getGlobalCachePath};
1
+ import{a as b,b as c,c as d,d as e,e as f,f as k,g as l,h as m,i as n}from"../chunk-T63Q2PMS.js";import{a as g,b as h,c as i,d as j}from"../chunk-MFQUKORC.js";import{a}from"../chunk-4NO7MHS7.js";import"../chunk-SC5M74NM.js";import"../chunk-NJ3AZYQD.js";import"../chunk-2ACBWC7K.js";export{d as CompositeKanonakDocumentRepository,c as DocumentLocation,b as FileSystemKanonakDocumentRepository,j as HttpKanonakDocumentRepository,a as InMemoryKanonakDocumentRepository,k as LocalFirstRepository,l as LockAwareRepository,h as PublisherConfigResolver,i as PublisherIndex,f as RepositoryFactory,n as buildLocalFirstRepository,m as collectKanonakFiles,g as defaultPublisherConfig,e as getGlobalCachePath};
@@ -1,13 +1,13 @@
1
- import{j as ee}from"../chunk-OOR5SVNQ.js";import"../chunk-QHABFCRC.js";import{a as me,d as U,f as fe,h as J}from"../chunk-MPBNEKCQ.js";import{a as he,b as ke,c as z,d as Y}from"../chunk-F26XWM5K.js";import{a as ge}from"../chunk-4NO7MHS7.js";import"../chunk-PEUTCG3B.js";import{a as be}from"../chunk-PEJALHXK.js";import"../chunk-SC5M74NM.js";import"../chunk-SHDHMKMJ.js";import{i as Q}from"../chunk-DSHPAWJQ.js";import{a as L}from"../chunk-NJ3AZYQD.js";import{b as X}from"../chunk-UK2OIPAB.js";import{g as Z}from"../chunk-PBNVHBS3.js";import"../chunk-VKTFLHCW.js";import{c as ye}from"../chunk-T3JR2SV6.js";import"../chunk-FUUTGGJS.js";import{c as F,e as K,f as H,g as ue}from"../chunk-2ACBWC7K.js";import{readFileSync as Pe,writeFileSync as De,mkdirSync as _e}from"fs";import{join as $e}from"path";function ve(n){let e=n.metadata?.namespace_;return e?`${e.publisher}/${e.package_}`:void 0}async function T(n,e){let t=new Set,r=[...n];for(;r.length>0;){let s=r.shift(),a=ve(s);if(!a||t.has(a))continue;t.add(a);let h=s.metadata?.imports;if(h)for(let[u,f]of Object.entries(h))for(let p of f)try{let g=await e.getHighestCompatibleVersionAsync(u,p);g&&r.push(g)}catch{}}return t}var B=class{constructor(e,t){this.inner=e;this.scope=t}inner;scope;async getAllDocumentsAsync(){return(await this.inner.getAllDocumentsAsync()).filter(t=>{let r=ve(t);return r!==void 0&&this.scope.has(r)})}getDocumentAsync(e){return this.inner.getDocumentAsync(e)}getDocumentsByNamespaceAsync(e,t){return this.inner.getDocumentsByNamespaceAsync(e,t)}getHighestCompatibleVersionAsync(e,t){return this.inner.getHighestCompatibleVersionAsync(e,t)}saveDocumentAsync(e,t){return this.inner.saveDocumentAsync(e,t)}deleteDocumentAsync(e){return this.inner.deleteDocumentAsync(e)}clearNamespaceAsync(e,t){return this.inner.clearNamespaceAsync(e,t)}getAllDocumentReferencesAsync(){return this.inner.getAllDocumentReferencesAsync()}getDocumentContentAsync(e){return this.inner.getDocumentContentAsync(e)}getDocumentUriAsync(e){return this.inner.getDocumentUriAsync(e)}};var Se=[{publisher:"kanonak.org",package_:"core-kanonak"},{publisher:"kanonak.org",package_:"site"},{publisher:"kanonak.org",package_:"link"},{publisher:"kanonak.org",package_:"look-tokens"},{publisher:"kanonak.org",package_:"look-styles"},{publisher:"kanonak.org",package_:"look"},{publisher:"kanonak.org",package_:"universal-look"}];function W(n){let e=n?.render;if(e&&e.length>0){let t=[];for(let r of e)try{let s=X(r);s.kind==="package"?t.push({publisher:s.publisher,package_:s.package_}):s.kind==="resource"&&t.push({publisher:s.uri.publisher,package_:s.uri.package_})}catch{}if(t.length>0)return t}return Se}function C(n){return`${n.publisher}/${n.package_}`}function G(n){let e={"kanonak.org/look-styles":"pages render UNSTYLED \u2014 generated CSS stops at the :root token block","kanonak.org/look-tokens":"the :root block loses the universal design-token floor (colors, fonts, spacing)","kanonak.org/universal-look":"resources without their own look render as an empty HTML comment","kanonak.org/look":"band vocabulary (Hero, PropertyList, \u2026) is unresolvable \u2014 declared looks cannot render","kanonak.org/site":"the site vocabulary (content, navigation) is unresolvable \u2014 the base stylesheet cannot bind","kanonak.org/core-kanonak":"the Package/Publisher classes are unresolvable \u2014 package and publisher pages degrade","kanonak.org/link":"link vocabulary is unresolvable \u2014 cross-reference styling degrades"},t=[];for(let r of n)if(r.origin==="missing"){let s=C(r),a=e[s]??"whatever this package contributes to rendering is lost";t.push(`Render-stack package ${s} is MISSING (${r.reason??"unknown reason"}) \u2014 ${a}. Fix: kanonak install ${s} (as the user running the render), or restore network access to ${r.publisher}.`)}else r.resolvedButNotInCatalog&&t.push(`Render-stack package ${C(r)} resolved (${r.origin}) but is NOT in the parsed catalog \u2014 this is a closure-scoping bug; please report it.`);return t}function re(n){let{publisher:e,availablePublishers:t,catalog:r,lookRenderer:s,localNamespaces:a,rawByNsKey:h,renderStack:u,producers:f}=n,p=new Map,g=new Map,o=new Map,m=new Set;for(let k of r){if(!(k instanceof ye))continue;let S=k.namespace||"";if(!a.has(S))continue;p.set(`${S}/${k.name}`,k);let b=S.split("/")[1]??"",[D,_]=b.split("@");if(!D||!_)continue;let I=ue(_);I&&(m.has(b)||(m.add(b),g.has(D)||g.set(D,[]),g.get(D).push({verStr:_,version:I})),k.name===D&&o.set(b,k))}for(let k of g.values())k.sort((S,b)=>F(b.version,S.version));return{publisher:e,availablePublishers:t,catalog:r,lookRenderer:s,localNamespaces:a,rawByNsKey:h,bySubject:p,pkgVersions:g,pkgSelfByVer:o,renderStack:u,...f?{producers:f}:{}}}async function se(n,e={}){let t=new L,r=new ge(t),s=[],a=[];for(let l of J(n)){let d;try{d=Pe(l,"utf-8")}catch{continue}let v;try{v=t.parse(d).metadata?.namespace_}catch{continue}if(!v?.version)continue;let N=v.version;a.push({publisher:v.publisher,package_:v.package_,verStr:K(N),version:N,source:d})}a.sort((l,d)=>F(d.version,l.version));for(let l of a)await r.saveDocumentAsync(t.parse(l.source),`${l.publisher}/${l.package_}@${l.verStr}`),s.push({publisher:l.publisher,package_:l.package_,verStr:l.verStr,source:l.source});let h=[...new Set(s.map(l=>l.publisher))].sort(),u=e.publisher;if(u){if(!h.includes(u))throw new Error(`Publisher "${u}" not found in workspace. Available: ${h.join(", ")||"(none)"}`)}else if(h.length===1)u=h[0];else throw h.length===0?new Error(`No Kanonak packages found under ${n}`):new Error(`Workspace has multiple publishers (${h.join(", ")}). Pass --publisher <domain> to choose which one to serve.`);let f=new Set,p=new Map;for(let l of s)l.publisher===u&&(f.add(`${l.publisher}/${l.package_}@${l.verStr}`),p.set(`${l.package_}@${l.verStr}`,l.source));let g=U(),o=new me(g,!0,t),m=e.repository??new fe(r,o,new Y(e.httpCache?{getFromCache:e.httpCache.getFromCache,onFetch:e.httpCache.onFetch}:void 0)),k=e.log??(()=>{}),S=W(void 0),b=[],D=l=>l.map(d=>d.metadata.namespace_?.version).filter(d=>d!==void 0).sort((d,v)=>F(v,d)).map(K);if(!e.repository){k(`[render-stack] resolving ${S.length} ambient look-stack package(s); cache: ${g}`);let l=new z;for(let d of S){let v=C(d),N=await r.getDocumentsByNamespaceAsync(d.publisher,d.package_);if(N.length>0){let $=D(N);b.push({...d,origin:"workspace",versions:$}),k(`[render-stack] ${v} \u2014 workspace (${$.join(", ")})`);continue}let O=await o.getDocumentsByNamespaceAsync(d.publisher,d.package_);if(O.length>0){let $=D(O);b.push({...d,origin:"cache",versions:$}),k(`[render-stack] ${v} \u2014 cache (${$.join(", ")})`);continue}try{let $=await l.getHighestVersion(d.publisher,d.package_);if(!$){let c=`publisher ${d.publisher} reachable but its index does not list ${d.package_}`;b.push({...d,origin:"missing",reason:c}),k(`[render-stack] ${v} \u2014 MISSING: ${c}`);continue}let j=await l.getPackageUrl(d.publisher,d.package_,$),V=await fetch(j);if(!V.ok){let c=`fetch ${j} failed: HTTP ${V.status} ${V.statusText}`;b.push({...d,origin:"missing",reason:c}),k(`[render-stack] ${v} \u2014 MISSING: ${c}`);continue}let i=await V.text();await r.saveDocumentAsync(t.parse(i),`${d.publisher}/${d.package_}@${$}`);try{let c=$e(g,d.publisher);_e(c,{recursive:!0}),De($e(c,`${d.package_}@${$}.kan.yml`),i,"utf-8"),b.push({...d,origin:"fetched",versions:[$]}),k(`[render-stack] ${v}@${$} \u2014 fetched from ${j}, installed to cache`)}catch(c){b.push({...d,origin:"fetched",versions:[$]}),k(`[render-stack] ${v}@${$} \u2014 fetched from ${j}, but cache ${g} is NOT WRITABLE (${c.message}); usable for this load only \u2014 every load will re-fetch it`)}}catch($){let j=`fetch failed: ${$.message}`;b.push({...d,origin:"missing",reason:j}),k(`[render-stack] ${v} \u2014 MISSING: ${j}`)}}}let _=m;if(!e.repository){let l=(await r.getAllDocumentsAsync()).filter(v=>v.metadata.namespace_?.publisher===u),d=await T(l,m);for(let v of S)d.add(C(v));_=new B(m,d)}let I=await new Q(t).parseKanonaks(_),q=new ee(I),oe=(l,d)=>Z(I,{publisher:l,package_:d,name:d}).length>0,A;if(e.repository){A=[];for(let l of S){let d=await m.getDocumentsByNamespaceAsync(l.publisher,l.package_);A.push(d.length>0?{...l,origin:"repository",versions:D(d)}:{...l,origin:"missing",reason:"not present in the caller-supplied repository"})}}else A=b.map(l=>l.origin==="missing"||oe(l.publisher,l.package_)?l:{...l,resolvedButNotInCatalog:!0});let E=G(A);for(let l of E)k(`[render-stack] WARNING: ${l}`);return re({publisher:u,availablePublishers:h,catalog:I,lookRenderer:q,localNamespaces:f,rawByNsKey:p,renderStack:{contractSource:"universal-default",cachePath:g,packages:A,warnings:E}})}import{existsSync as je,readFileSync as Ce,writeFileSync as Ie,mkdirSync as Ae}from"fs";import{join as we}from"path";async function ae(n,e={}){let t=new L,r=X(n),s=r.kind==="resource"?r.uri.publisher:r.publisher,a=e.log??(()=>{}),h=e.cacheRoot??U(),u=(i,c,y)=>we(h,i,`${c}@${y}.kan.yml`),f=new Set,p=new Set,g=new Map,o=new Y({getFromCache:(i,c,y)=>{let P=u(i,c,y),w=je(P)?Ce(P,"utf-8"):null;return w!==null&&f.add(`${i}/${c}`),w},onFetch:(i,c,y,P)=>{p.add(`${i}/${c}`);try{let w=we(h,i);Ae(w,{recursive:!0}),Ie(u(i,c,y),P,"utf-8")}catch(w){g.set(`${i}/${c}`,w.message),a(`[render] fetched ${i}/${c}@${y} but cache ${h} is NOT WRITABLE (${w.message}); usable for this load only \u2014 every load will re-fetch it`)}},...e.fetchFn?{fetchFn:e.fetchFn}:{}}),m=new z(e.fetchFn?{fetchFn:e.fetchFn}:void 0),k;if(r.kind==="resource"){let i=r.uri.version;k=[i?{package_:r.uri.package_,version:`${i.major}.${i.minor}.${i.patch}`}:{package_:r.uri.package_}]}else if(r.kind==="package"){let i=r.version;k=[i?{package_:r.package_,version:`${i.major}.${i.minor}.${i.patch}`}:{package_:r.package_}]}else k=(await m.listLatestPackages(s)).map(c=>({package_:c.packageName}));let S=async(i,c,y)=>{try{let P=y?t.buildImport(c,"=",y,i):t.buildImport(c,"*","0.0.0",i),w=await o.getHighestCompatibleVersionAsync(i,P);return w?{doc:w}:{doc:null,error:`${i} did not resolve ${c}${y?`@${y}`:""} (not in its index, or unreachable)`}}catch(P){return{doc:null,error:P.message}}},b=[],D=[];for(let i of k){let{doc:c,error:y}=await S(s,i.package_,i.version);c?b.push(c):y&&D.push(y)}if(b.length===0)throw new Error(`Could not fetch any package for address "${n}" from publisher "${s}".`+(D.length>0?` Reasons: ${D.join("; ")}`:""));let _=await new ke().getConfig(s).catch(()=>{}),I=W(_),q=_?.render&&_.render.length>0?"publisher-well-known":"universal-default",oe=i=>i.map(c=>c.metadata.namespace_?.version).filter(c=>c!==void 0).sort((c,y)=>F(y,c)).map(K);a(`[render-stack] resolving ${I.length} ambient look-stack package(s) (contract: ${q}); cache: ${h}`);let A=[],E=[];for(let i of I){let c=C(i),{doc:y,error:P}=await S(i.publisher,i.package_,void 0);if(y){A.push(y);let w=oe([y]),pe=p.has(c)?"fetched":f.has(c)?"cache":"fetched";E.push({...i,origin:pe,versions:w}),a(`[render-stack] ${c} \u2014 ${pe} (${w.join(", ")})`+(g.has(c)?" [cache write FAILED \u2014 will re-fetch next load]":""))}else E.push({...i,origin:"missing",reason:P??"unresolved"}),a(`[render-stack] ${c} \u2014 MISSING: ${P??"unresolved"}`)}let de=await T([...b,...A],o),l=new B(o,de),d=await new Q(t).parseKanonaks(l),v=new ee(d),N=E.map(i=>i.origin==="missing"||Z(d,{publisher:i.publisher,package_:i.package_,name:i.package_}).length>0?i:{...i,resolvedButNotInCatalog:!0}),O=G(N);for(let i of O)a(`[render-stack] WARNING: ${i}`);let $={contractSource:q,cachePath:h,packages:N,warnings:O},j=new Set,V=new Map;for(let i of await o.getAllDocumentsAsync()){let c=i.metadata.namespace_;if(!c?.version||c.publisher!==s)continue;let y=K(c.version),P=`${c.publisher}/${c.package_}@${y}`;j.add(P);let w=await o.getDocumentContentAsync(P);w!==null&&V.set(`${c.package_}@${y}`,w)}return re({publisher:s,availablePublishers:[s],catalog:d,lookRenderer:v,localNamespaces:j,rawByNsKey:V,renderStack:$})}import{VersionOperator as te}from"@kanonak-protocol/types/document/models/enums";function ne(n){let{lookRenderer:e,publisher:t,renderStack:r,catalog:s}=n,a=e.explainStylesheet(e.publisherSubject(t)),h=[...a.tokens.entries()].map(([o,m])=>({name:o,value:m.value,source:`${m.sourceNamespace}/${m.sourceName}`,level:m.level})),u=a.baseStylesheet,f={present:u.css!==void 0,...u.sourceNamespace!==void 0?{source:u.sourceNamespace}:{},...u.scope!==void 0?{scope:u.scope}:{},...u.css!==void 0?{bytes:u.css.length}:{},...u.problem!==void 0?{problem:u.problem}:{},candidates:u.candidates},p=new Map;for(let o of s){let m=o.namespace;m&&p.set(m,(p.get(m)??0)+1)}let g=[...p.entries()].map(([o,m])=>({namespace:o,resources:m})).sort((o,m)=>o.namespace.localeCompare(m.namespace));return{publisher:t,renderStack:{contractSource:r.contractSource,cachePath:r.cachePath,packages:r.packages.map(o=>({package_:C(o),origin:o.origin,...o.versions!==void 0?{versions:o.versions}:{},...o.reason!==void 0?{reason:o.reason}:{},...o.resolvedButNotInCatalog!==void 0?{resolvedButNotInCatalog:o.resolvedButNotInCatalog}:{}}))},stylesheet:{tokens:h,baseStylesheet:f,...a.look?{look:{sourceClass:`${a.look.sourceClass.publisher}/${a.look.sourceClass.package_}/${a.look.sourceClass.name}`}}:{}},catalog:g,warnings:[...r.warnings,...a.warnings.filter(o=>!r.warnings.includes(o))]}}function Ne(n){return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function ie(n){let e=Ne,t=n.warnings.length===0,r=n.warnings.length===0?'<p class="ok">\u2713 No problems detected \u2014 the render stack is fully resolved and pages should be styled.</p>':n.warnings.map(p=>`<div class="warn">\u26A0 ${e(p)}</div>`).join(`
2
- `),s=n.renderStack.packages.map(p=>{let g=p.origin!=="missing"&&!p.resolvedButNotInCatalog,o=p.origin==="missing"?'<span class="bad">MISSING</span>':p.resolvedButNotInCatalog?`<span class="bad">${e(p.origin)} (not in catalog)</span>`:`<span class="good">${e(p.origin)}</span>`,m=p.reason?e(p.reason):e((p.versions??[]).join(", "));return`<tr class="${g?"":"row-bad"}"><td><code>${e(p.package_)}</code></td><td>${o}</td><td>${m}</td></tr>`}).join(`
3
- `),a=n.stylesheet.baseStylesheet,h=a.present?`<p><span class="good">\u2713 present</span> \u2014 <code>${e(a.source??"")}</code> (${a.bytes} bytes, ${e(a.scope??"")})</p>`:`<p><span class="bad">\u2717 MISSING</span>${a.problem?` \u2014 ${e(a.problem)}`:""}${a.candidates.length>0?`<br>candidates considered: ${a.candidates.map(p=>`<code>${e(p)}</code>`).join(", ")}`:""}</p><p>Without the base stylesheet, generated CSS stops at the <code>:root</code> token block and pages appear unstyled.</p>`,u=n.stylesheet.tokens.map(p=>`<tr><td><code>--kan-${e(p.name)}</code></td><td><code>${e(p.value)}</code></td><td><code>${e(p.source)}</code></td><td>${e(p.level)}</td></tr>`).join(`
4
- `),f=n.catalog.map(p=>`<tr><td><code>${e(p.namespace)}</code></td><td>${p.resources}</td></tr>`).join(`
1
+ import{j as ee}from"../chunk-OOR5SVNQ.js";import"../chunk-QHABFCRC.js";import{a as he,d as z,f as ke,h as J}from"../chunk-T63Q2PMS.js";import{a as me,b as fe,c as O,d as Y}from"../chunk-MFQUKORC.js";import{a as ge}from"../chunk-4NO7MHS7.js";import"../chunk-PEUTCG3B.js";import{a as be}from"../chunk-PEJALHXK.js";import"../chunk-SC5M74NM.js";import"../chunk-SHDHMKMJ.js";import{i as Q}from"../chunk-DSHPAWJQ.js";import{a as E}from"../chunk-NJ3AZYQD.js";import{b as X}from"../chunk-UK2OIPAB.js";import{g as Z}from"../chunk-PBNVHBS3.js";import"../chunk-VKTFLHCW.js";import{c as ye}from"../chunk-T3JR2SV6.js";import"../chunk-FUUTGGJS.js";import{c as M,e as F,f as L,g as ue}from"../chunk-2ACBWC7K.js";import{readFileSync as Pe,writeFileSync as De,mkdirSync as _e}from"fs";import{join as we}from"path";function ve(t){let e=t.metadata?.namespace_;return e?`${e.publisher}/${e.package_}`:void 0}async function H(t,e){let n=new Set,r=[...t];for(;r.length>0;){let s=r.shift(),a=ve(s);if(!a||n.has(a))continue;n.add(a);let m=s.metadata?.imports;if(m)for(let[p,k]of Object.entries(m))for(let d of k)try{let u=await e.getHighestCompatibleVersionAsync(p,d);u&&r.push(u)}catch{}}return n}var V=class{constructor(e,n){this.inner=e;this.scope=n}inner;scope;async getAllDocumentsAsync(){return(await this.inner.getAllDocumentsAsync()).filter(n=>{let r=ve(n);return r!==void 0&&this.scope.has(r)})}getDocumentAsync(e){return this.inner.getDocumentAsync(e)}getDocumentsByNamespaceAsync(e,n){return this.inner.getDocumentsByNamespaceAsync(e,n)}getHighestCompatibleVersionAsync(e,n){return this.inner.getHighestCompatibleVersionAsync(e,n)}saveDocumentAsync(e,n){return this.inner.saveDocumentAsync(e,n)}deleteDocumentAsync(e){return this.inner.deleteDocumentAsync(e)}clearNamespaceAsync(e,n){return this.inner.clearNamespaceAsync(e,n)}getAllDocumentReferencesAsync(){return this.inner.getAllDocumentReferencesAsync()}getDocumentContentAsync(e){return this.inner.getDocumentContentAsync(e)}getDocumentUriAsync(e){return this.inner.getDocumentUriAsync(e)}};var Se=[{publisher:"kanonak.org",package_:"core-kanonak"},{publisher:"kanonak.org",package_:"site"},{publisher:"kanonak.org",package_:"link"},{publisher:"kanonak.org",package_:"look-tokens"},{publisher:"kanonak.org",package_:"look-styles"},{publisher:"kanonak.org",package_:"look"},{publisher:"kanonak.org",package_:"universal-look"}];function T(t){let e=t?.render;if(e&&e.length>0){let n=[];for(let r of e)try{let s=X(r);s.kind==="package"?n.push({publisher:s.publisher,package_:s.package_}):s.kind==="resource"&&n.push({publisher:s.uri.publisher,package_:s.uri.package_})}catch{}if(n.length>0)return n}return Se}function C(t){return`${t.publisher}/${t.package_}`}function W(t){let e={"kanonak.org/look-styles":"pages render UNSTYLED \u2014 generated CSS stops at the :root token block","kanonak.org/look-tokens":"the :root block loses the universal design-token floor (colors, fonts, spacing)","kanonak.org/universal-look":"resources without their own look render as an empty HTML comment","kanonak.org/look":"band vocabulary (Hero, PropertyList, \u2026) is unresolvable \u2014 declared looks cannot render","kanonak.org/site":"the site vocabulary (content, navigation) is unresolvable \u2014 the base stylesheet cannot bind","kanonak.org/core-kanonak":"the Package/Publisher classes are unresolvable \u2014 package and publisher pages degrade","kanonak.org/link":"link vocabulary is unresolvable \u2014 cross-reference styling degrades"},n=[];for(let r of t)if(r.origin==="missing"){let s=C(r),a=e[s]??"whatever this package contributes to rendering is lost";n.push(`Render-stack package ${s} is MISSING (${r.reason??"unknown reason"}) \u2014 ${a}. Fix: kanonak install ${s} (as the user running the render), or restore network access to ${r.publisher}.`)}else r.resolvedButNotInCatalog&&n.push(`Render-stack package ${C(r)} resolved (${r.origin}) but is NOT in the parsed catalog \u2014 this is a closure-scoping bug; please report it.`);return n}function re(t){let{publisher:e,availablePublishers:n,catalog:r,lookRenderer:s,localNamespaces:a,rawByNsKey:m,renderStack:p,producers:k}=t,d=new Map,u=new Map,o=new Map,h=new Set;for(let y of r){if(!(y instanceof ye))continue;let b=y.namespace||"";if(!a.has(b))continue;d.set(`${b}/${y.name}`,y);let $=b.split("/")[1]??"",[w,_]=$.split("@");if(!w||!_)continue;let I=ue(_);I&&(h.has($)||(h.add($),u.has(w)||u.set(w,[]),u.get(w).push({verStr:_,version:I})),y.name===w&&o.set($,y))}for(let y of u.values())y.sort((b,$)=>M($.version,b.version));return{publisher:e,availablePublishers:n,catalog:r,lookRenderer:s,localNamespaces:a,rawByNsKey:m,bySubject:d,pkgVersions:u,pkgSelfByVer:o,renderStack:p,...k?{producers:k}:{}}}async function se(t,e={}){let n=new E,r=new ge(n),s=[],a=[];for(let c of J(t)){let l;try{l=Pe(c,"utf-8")}catch{continue}let v;try{v=n.parse(l).metadata?.namespace_}catch{continue}if(!v?.version)continue;let N=v.version;a.push({publisher:v.publisher,package_:v.package_,verStr:F(N),version:N,source:l})}a.sort((c,l)=>M(l.version,c.version));for(let c of a)await r.saveDocumentAsync(n.parse(c.source),`${c.publisher}/${c.package_}@${c.verStr}`),s.push({publisher:c.publisher,package_:c.package_,verStr:c.verStr,source:c.source});let m=[...new Set(s.map(c=>c.publisher))].sort(),p=e.publisher;if(p){if(!m.includes(p))throw new Error(`Publisher "${p}" not found in workspace. Available: ${m.join(", ")||"(none)"}`)}else if(m.length===1)p=m[0];else throw m.length===0?new Error(`No Kanonak packages found under ${t}`):new Error(`Workspace has multiple publishers (${m.join(", ")}). Pass --publisher <domain> to choose which one to serve.`);let k=new Set,d=new Map;for(let c of s)c.publisher===p&&(k.add(`${c.publisher}/${c.package_}@${c.verStr}`),d.set(`${c.package_}@${c.verStr}`,c.source));let u=z(),o=new he(u,!0,n),h={};e.httpCache&&(h.getFromCache=e.httpCache.getFromCache,h.onFetch=e.httpCache.onFetch),e.fetchFn&&(h.fetchFn=e.fetchFn);let y=e.repository??new ke(r,o,new Y(h)),b=e.log??(()=>{}),$=T(void 0),w=[],_=c=>c.map(l=>l.metadata.namespace_?.version).filter(l=>l!==void 0).sort((l,v)=>M(v,l)).map(F);if(!e.repository){b(`[render-stack] resolving ${$.length} ambient look-stack package(s); cache: ${u}`);let c=e.fetchFn?new O({fetchFn:e.fetchFn}):new O;for(let l of $){let v=C(l),N=await r.getDocumentsByNamespaceAsync(l.publisher,l.package_);if(N.length>0){let S=_(N);w.push({...l,origin:"workspace",versions:S}),b(`[render-stack] ${v} \u2014 workspace (${S.join(", ")})`);continue}let U=await o.getDocumentsByNamespaceAsync(l.publisher,l.package_);if(U.length>0){let S=_(U);w.push({...l,origin:"cache",versions:S}),b(`[render-stack] ${v} \u2014 cache (${S.join(", ")})`);continue}try{let S=await c.getHighestVersion(l.publisher,l.package_);if(!S){let f=`publisher ${l.publisher} reachable but its index does not list ${l.package_}`;w.push({...l,origin:"missing",reason:f}),b(`[render-stack] ${v} \u2014 MISSING: ${f}`);continue}let j=await c.getPackageUrl(l.publisher,l.package_,S),i=await(e.fetchFn?e.fetchFn(j,l.publisher):fetch(j));if(!i.ok){let f=`fetch ${j} failed: HTTP ${i.status} ${i.statusText}`;w.push({...l,origin:"missing",reason:f}),b(`[render-stack] ${v} \u2014 MISSING: ${f}`);continue}let g=await i.text();await r.saveDocumentAsync(n.parse(g),`${l.publisher}/${l.package_}@${S}`);try{let f=we(u,l.publisher);_e(f,{recursive:!0}),De(we(f,`${l.package_}@${S}.kan.yml`),g,"utf-8"),w.push({...l,origin:"fetched",versions:[S]}),b(`[render-stack] ${v}@${S} \u2014 fetched from ${j}, installed to cache`)}catch(f){w.push({...l,origin:"fetched",versions:[S]}),b(`[render-stack] ${v}@${S} \u2014 fetched from ${j}, but cache ${u} is NOT WRITABLE (${f.message}); usable for this load only \u2014 every load will re-fetch it`)}}catch(S){let j=`fetch failed: ${S.message}`;w.push({...l,origin:"missing",reason:j}),b(`[render-stack] ${v} \u2014 MISSING: ${j}`)}}}let I=y;if(!e.repository){let c=(await r.getAllDocumentsAsync()).filter(v=>v.metadata.namespace_?.publisher===p),l=await H(c,y);for(let v of $)l.add(C(v));I=new V(y,l)}let B=await new Q(n).parseKanonaks(I),oe=new ee(B),G=(c,l)=>Z(B,{publisher:c,package_:l,name:l}).length>0,A;if(e.repository){A=[];for(let c of $){let l=await y.getDocumentsByNamespaceAsync(c.publisher,c.package_);A.push(l.length>0?{...c,origin:"repository",versions:_(l)}:{...c,origin:"missing",reason:"not present in the caller-supplied repository"})}}else A=w.map(c=>c.origin==="missing"||G(c.publisher,c.package_)?c:{...c,resolvedButNotInCatalog:!0});let q=W(A);for(let c of q)b(`[render-stack] WARNING: ${c}`);return re({publisher:p,availablePublishers:m,catalog:B,lookRenderer:oe,localNamespaces:k,rawByNsKey:d,renderStack:{contractSource:"universal-default",cachePath:u,packages:A,warnings:q}})}import{existsSync as je,readFileSync as Ce,writeFileSync as Ae,mkdirSync as Ie}from"fs";import{join as $e}from"path";async function ae(t,e={}){let n=new E,r=X(t),s=r.kind==="resource"?r.uri.publisher:r.publisher,a=e.log??(()=>{}),m=e.cacheRoot??z(),p=(i,g,f)=>$e(m,i,`${g}@${f}.kan.yml`),k=new Set,d=new Set,u=new Map,o=new Y({getFromCache:(i,g,f)=>{let D=p(i,g,f),R=je(D)?Ce(D,"utf-8"):null;return R!==null&&k.add(`${i}/${g}`),R},onFetch:(i,g,f,D)=>{d.add(`${i}/${g}`);try{let R=$e(m,i);Ie(R,{recursive:!0}),Ae(p(i,g,f),D,"utf-8")}catch(R){u.set(`${i}/${g}`,R.message),a(`[render] fetched ${i}/${g}@${f} but cache ${m} is NOT WRITABLE (${R.message}); usable for this load only \u2014 every load will re-fetch it`)}},...e.fetchFn?{fetchFn:e.fetchFn}:{}}),h=new O(e.fetchFn?{fetchFn:e.fetchFn}:void 0),y;if(r.kind==="resource"){let i=r.uri.version;y=[i?{package_:r.uri.package_,version:`${i.major}.${i.minor}.${i.patch}`}:{package_:r.uri.package_}]}else if(r.kind==="package"){let i=r.version;y=[i?{package_:r.package_,version:`${i.major}.${i.minor}.${i.patch}`}:{package_:r.package_}]}else y=(await h.listLatestPackages(s)).map(g=>({package_:g.packageName}));let b=async(i,g,f)=>{try{let D=f?n.buildImport(g,"=",f,i):n.buildImport(g,"*","0.0.0",i),R=await o.getHighestCompatibleVersionAsync(i,D);return R?{doc:R}:{doc:null,error:`${i} did not resolve ${g}${f?`@${f}`:""} (not in its index, or unreachable)`}}catch(D){return{doc:null,error:D.message}}},$=[],w=[];for(let i of y){let{doc:g,error:f}=await b(s,i.package_,i.version);g?$.push(g):f&&w.push(f)}if($.length===0)throw new Error(`Could not fetch any package for address "${t}" from publisher "${s}".`+(w.length>0?` Reasons: ${w.join("; ")}`:""));let _=await new fe(e.fetchFn).getConfig(s).catch(()=>{}),I=T(_),B=_?.render&&_.render.length>0?"publisher-well-known":"universal-default",oe=i=>i.map(g=>g.metadata.namespace_?.version).filter(g=>g!==void 0).sort((g,f)=>M(f,g)).map(F);a(`[render-stack] resolving ${I.length} ambient look-stack package(s) (contract: ${B}); cache: ${m}`);let G=[],A=[];for(let i of I){let g=C(i),{doc:f,error:D}=await b(i.publisher,i.package_,void 0);if(f){G.push(f);let R=oe([f]),pe=d.has(g)?"fetched":k.has(g)?"cache":"fetched";A.push({...i,origin:pe,versions:R}),a(`[render-stack] ${g} \u2014 ${pe} (${R.join(", ")})`+(u.has(g)?" [cache write FAILED \u2014 will re-fetch next load]":""))}else A.push({...i,origin:"missing",reason:D??"unresolved"}),a(`[render-stack] ${g} \u2014 MISSING: ${D??"unresolved"}`)}let q=await H([...$,...G],o),de=new V(o,q),c=await new Q(n).parseKanonaks(de),l=new ee(c),v=A.map(i=>i.origin==="missing"||Z(c,{publisher:i.publisher,package_:i.package_,name:i.package_}).length>0?i:{...i,resolvedButNotInCatalog:!0}),N=W(v);for(let i of N)a(`[render-stack] WARNING: ${i}`);let U={contractSource:B,cachePath:m,packages:v,warnings:N},S=new Set,j=new Map;for(let i of await o.getAllDocumentsAsync()){let g=i.metadata.namespace_;if(!g?.version||g.publisher!==s)continue;let f=F(g.version),D=`${g.publisher}/${g.package_}@${f}`;S.add(D);let R=await o.getDocumentContentAsync(D);R!==null&&j.set(`${g.package_}@${f}`,R)}return re({publisher:s,availablePublishers:[s],catalog:c,lookRenderer:l,localNamespaces:S,rawByNsKey:j,renderStack:U})}import{VersionOperator as ne}from"@kanonak-protocol/types/document/models/enums";function te(t){let{lookRenderer:e,publisher:n,renderStack:r,catalog:s}=t,a=e.explainStylesheet(e.publisherSubject(n)),m=[...a.tokens.entries()].map(([o,h])=>({name:o,value:h.value,source:`${h.sourceNamespace}/${h.sourceName}`,level:h.level})),p=a.baseStylesheet,k={present:p.css!==void 0,...p.sourceNamespace!==void 0?{source:p.sourceNamespace}:{},...p.scope!==void 0?{scope:p.scope}:{},...p.css!==void 0?{bytes:p.css.length}:{},...p.problem!==void 0?{problem:p.problem}:{},candidates:p.candidates},d=new Map;for(let o of s){let h=o.namespace;h&&d.set(h,(d.get(h)??0)+1)}let u=[...d.entries()].map(([o,h])=>({namespace:o,resources:h})).sort((o,h)=>o.namespace.localeCompare(h.namespace));return{publisher:n,renderStack:{contractSource:r.contractSource,cachePath:r.cachePath,packages:r.packages.map(o=>({package_:C(o),origin:o.origin,...o.versions!==void 0?{versions:o.versions}:{},...o.reason!==void 0?{reason:o.reason}:{},...o.resolvedButNotInCatalog!==void 0?{resolvedButNotInCatalog:o.resolvedButNotInCatalog}:{}}))},stylesheet:{tokens:m,baseStylesheet:k,...a.look?{look:{sourceClass:`${a.look.sourceClass.publisher}/${a.look.sourceClass.package_}/${a.look.sourceClass.name}`}}:{}},catalog:u,warnings:[...r.warnings,...a.warnings.filter(o=>!r.warnings.includes(o))]}}function Ne(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function ie(t){let e=Ne,n=t.warnings.length===0,r=t.warnings.length===0?'<p class="ok">\u2713 No problems detected \u2014 the render stack is fully resolved and pages should be styled.</p>':t.warnings.map(d=>`<div class="warn">\u26A0 ${e(d)}</div>`).join(`
2
+ `),s=t.renderStack.packages.map(d=>{let u=d.origin!=="missing"&&!d.resolvedButNotInCatalog,o=d.origin==="missing"?'<span class="bad">MISSING</span>':d.resolvedButNotInCatalog?`<span class="bad">${e(d.origin)} (not in catalog)</span>`:`<span class="good">${e(d.origin)}</span>`,h=d.reason?e(d.reason):e((d.versions??[]).join(", "));return`<tr class="${u?"":"row-bad"}"><td><code>${e(d.package_)}</code></td><td>${o}</td><td>${h}</td></tr>`}).join(`
3
+ `),a=t.stylesheet.baseStylesheet,m=a.present?`<p><span class="good">\u2713 present</span> \u2014 <code>${e(a.source??"")}</code> (${a.bytes} bytes, ${e(a.scope??"")})</p>`:`<p><span class="bad">\u2717 MISSING</span>${a.problem?` \u2014 ${e(a.problem)}`:""}${a.candidates.length>0?`<br>candidates considered: ${a.candidates.map(d=>`<code>${e(d)}</code>`).join(", ")}`:""}</p><p>Without the base stylesheet, generated CSS stops at the <code>:root</code> token block and pages appear unstyled.</p>`,p=t.stylesheet.tokens.map(d=>`<tr><td><code>--kan-${e(d.name)}</code></td><td><code>${e(d.value)}</code></td><td><code>${e(d.source)}</code></td><td>${e(d.level)}</td></tr>`).join(`
4
+ `),k=t.catalog.map(d=>`<tr><td><code>${e(d.namespace)}</code></td><td>${d.resources}</td></tr>`).join(`
5
5
  `);return`<!doctype html>
6
6
  <html lang="en">
7
7
  <head>
8
8
  <meta charset="utf-8">
9
9
  <meta name="viewport" content="width=device-width,initial-scale=1">
10
- <title>Render diagnostics \u2014 ${e(n.publisher)}</title>
10
+ <title>Render diagnostics \u2014 ${e(t.publisher)}</title>
11
11
  <style>
12
12
  body { font-family: system-ui, sans-serif; max-width: 64rem; margin: 2rem auto; padding: 0 1rem; line-height: 1.5; color: #1a1a1a; background: #fff; }
13
13
  h1 { font-size: 1.5rem; } h2 { font-size: 1.15rem; margin-top: 2rem; border-bottom: 1px solid #ddd; padding-bottom: .25rem; }
@@ -21,12 +21,12 @@ import{j as ee}from"../chunk-OOR5SVNQ.js";import"../chunk-QHABFCRC.js";import{a
21
21
  .row-bad td { background: #fff5f5; }
22
22
  .meta { color: #666; font-size: .85rem; }
23
23
  .status-banner { font-size: 1.1rem; padding: .5rem 1rem; border-radius: 6px; display: inline-block; margin-bottom: 1rem;
24
- background: ${t?"#ecfdf3":"#fef2f2"}; border: 1px solid ${t?"#0a7d33":"#b91c1c"}; }
24
+ background: ${n?"#ecfdf3":"#fef2f2"}; border: 1px solid ${n?"#0a7d33":"#b91c1c"}; }
25
25
  </style>
26
26
  </head>
27
27
  <body>
28
- <h1>Render diagnostics \u2014 ${e(n.publisher)}</h1>
29
- <p class="status-banner">${t?"\u2713 Healthy":`\u2717 ${n.warnings.length} problem(s) found`}</p>
28
+ <h1>Render diagnostics \u2014 ${e(t.publisher)}</h1>
29
+ <p class="status-banner">${n?"\u2713 Healthy":`\u2717 ${t.warnings.length} problem(s) found`}</p>
30
30
  <p class="meta">Machine-readable version: <a href="/.well-known/kanonak-render.json"><code>/.well-known/kanonak-render.json</code></a></p>
31
31
 
32
32
  <h2>Problems</h2>
@@ -34,7 +34,7 @@ ${r}
34
34
 
35
35
  <h2>Ambient render stack</h2>
36
36
  <p class="meta">The look stack is discovered, not imported \u2014 these packages must be resolvable for any publisher's pages to render styled.
37
- Contract: <code>${e(n.renderStack.contractSource)}</code> \xB7 Package cache: <code>${e(n.renderStack.cachePath)}</code></p>
37
+ Contract: <code>${e(t.renderStack.contractSource)}</code> \xB7 Package cache: <code>${e(t.renderStack.cachePath)}</code></p>
38
38
  <table>
39
39
  <tr><th>Package</th><th>Origin</th><th>Versions / reason</th></tr>
40
40
  ${s}
@@ -42,25 +42,25 @@ ${s}
42
42
 
43
43
  <h2>Base stylesheet</h2>
44
44
  <p class="meta">Everything after the <code>:root</code> block in generated CSS comes from a <code>look-styles/base-stylesheet</code> asset in the render catalog.</p>
45
- ${h}
45
+ ${m}
46
46
 
47
47
  <h2>Design tokens (:root)</h2>
48
48
  <p class="meta">Resolved for the publisher landing page. Each token shows which resource in the cascade supplied it.</p>
49
- ${n.stylesheet.tokens.length===0?'<p><span class="bad">\u2717 No tokens resolved</span></p>':`<table>
49
+ ${t.stylesheet.tokens.length===0?'<p><span class="bad">\u2717 No tokens resolved</span></p>':`<table>
50
50
  <tr><th>Token</th><th>Value</th><th>Declared by</th><th>Cascade level</th></tr>
51
- ${u}
51
+ ${p}
52
52
  </table>`}
53
53
 
54
54
  <h2>Look (page body)</h2>
55
- ${n.stylesheet.look?`<p><span class="good">\u2713</span> Bands resolve from <code>${e(n.stylesheet.look.sourceClass)}</code></p>`:'<p><span class="bad">\u2717 No look resolved</span> \u2014 the page body renders as an empty comment.</p>'}
55
+ ${t.stylesheet.look?`<p><span class="good">\u2713</span> Bands resolve from <code>${e(t.stylesheet.look.sourceClass)}</code></p>`:'<p><span class="bad">\u2717 No look resolved</span> \u2014 the page body renders as an empty comment.</p>'}
56
56
 
57
- <h2>Render catalog (${n.catalog.length} package version(s))</h2>
57
+ <h2>Render catalog (${t.catalog.length} package version(s))</h2>
58
58
  <p class="meta">Everything the renderer can see for this publisher \u2014 the served packages, their import closure, and the ambient render stack.</p>
59
59
  <table>
60
60
  <tr><th>Package version</th><th>Resources</th></tr>
61
- ${f}
61
+ ${k}
62
62
  </table>
63
63
  </body>
64
- </html>`}var R={".html":"text/html; charset=utf-8",".css":"text/css; charset=utf-8",".svg":"image/svg+xml",".md":"text/markdown; charset=utf-8",".kan.yml":"application/yaml; charset=utf-8",".txt":"text/plain; charset=utf-8",".json":"application/json; charset=utf-8"},x=(n,e,t,r)=>({status:n,headers:{"Content-Type":e,...r||{}},body:t}),M=n=>x(404,R[".html"],`<!doctype html><meta charset=utf-8><title>404</title><h1>404</h1><p>Not found: ${n}</p>`),Ke=n=>({status:301,headers:{Location:n},body:""}),Me=n=>({status:302,headers:{Location:n},body:""});function Ve(n){switch(n.kind){case"exact":return{operator:te.Exact,version:H(n.major,n.minor,n.patch)};case"minor-pin":return{operator:te.Compatible,version:H(n.major,n.minor,0)};case"major-pin":return{operator:te.Major,version:H(n.major,0,0)};default:return{operator:te.Any,version:H(0,0,0)}}}async function Fe(n,e,t,r){if(!r)return null;let s=n.producers?.find(f=>f.canProduce(n.publisher,e));if(!s)return null;let a=await s.resolveVersion(n.publisher,e,Ve(t));if(!a)return null;let h=K(a);if(t.kind!=="exact")return Me(`/${e}/${h}.kan.yml`);let{source:u}=await s.produce(n.publisher,e,a);return x(200,R[".kan.yml"],u)}function Re(n,e,t){let r=n.pkgVersions.get(e);if(!r||r.length===0)return null;switch(t.kind){case"any":return r[0].verStr;case"major-pin":return r.find(s=>s.version.major===t.major)?.verStr??null;case"minor-pin":return r.find(s=>s.version.major===t.major&&s.version.minor===t.minor)?.verStr??null;case"exact":return r.find(s=>s.version.major===t.major&&s.version.minor===t.minor&&s.version.patch===t.patch)?.verStr??null;default:return null}}async function ce(n,e,t=""){let{lookRenderer:r,publisher:s}=n;if(e==="/.well-known/kanonak.json"){let o=he(s);return n.producers&&n.producers.length>0&&(o.resolveByRedirect=!0),x(200,R[".json"],JSON.stringify(o,null,2))}if(e==="/index.txt"){let o=[...n.localNamespaces].map(m=>m.split("/")[1].replace("@","/")).sort();return x(200,R[".txt"],o.join(`
64
+ </html>`}var x={".html":"text/html; charset=utf-8",".css":"text/css; charset=utf-8",".svg":"image/svg+xml",".md":"text/markdown; charset=utf-8",".kan.yml":"application/yaml; charset=utf-8",".txt":"text/plain; charset=utf-8",".json":"application/json; charset=utf-8"},P=(t,e,n,r)=>({status:t,headers:{"Content-Type":e,...r||{}},body:n}),K=t=>P(404,x[".html"],`<!doctype html><meta charset=utf-8><title>404</title><h1>404</h1><p>Not found: ${t}</p>`),Fe=t=>({status:301,headers:{Location:t},body:""}),Ke=t=>({status:302,headers:{Location:t},body:""});function Me(t){switch(t.kind){case"exact":return{operator:ne.Exact,version:L(t.major,t.minor,t.patch)};case"minor-pin":return{operator:ne.Compatible,version:L(t.major,t.minor,0)};case"major-pin":return{operator:ne.Major,version:L(t.major,0,0)};default:return{operator:ne.Any,version:L(0,0,0)}}}async function Ve(t,e,n,r){if(!r)return null;let s=t.producers?.find(k=>k.canProduce(t.publisher,e));if(!s)return null;let a=await s.resolveVersion(t.publisher,e,Me(n));if(!a)return null;let m=F(a);if(n.kind!=="exact")return Ke(`/${e}/${m}.kan.yml`);let{source:p}=await s.produce(t.publisher,e,a);return P(200,x[".kan.yml"],p)}function Re(t,e,n){let r=t.pkgVersions.get(e);if(!r||r.length===0)return null;switch(n.kind){case"any":return r[0].verStr;case"major-pin":return r.find(s=>s.version.major===n.major)?.verStr??null;case"minor-pin":return r.find(s=>s.version.major===n.major&&s.version.minor===n.minor)?.verStr??null;case"exact":return r.find(s=>s.version.major===n.major&&s.version.minor===n.minor&&s.version.patch===n.patch)?.verStr??null;default:return null}}async function ce(t,e,n=""){let{lookRenderer:r,publisher:s}=t;if(e==="/.well-known/kanonak.json"){let o=me(s);return t.producers&&t.producers.length>0&&(o.resolveByRedirect=!0),P(200,x[".json"],JSON.stringify(o,null,2))}if(e==="/index.txt"){let o=[...t.localNamespaces].map(h=>h.split("/")[1].replace("@","/")).sort();return P(200,x[".txt"],o.join(`
65
65
  `)+`
66
- `)}if(e==="/.well-known/kanonak-render.json")return x(200,R[".json"],JSON.stringify(ne(n),null,2));if(e==="/.well-known/kanonak-render")return x(200,R[".html"],ie(ne(n)));if(e==="/"||e==="/index.html"||e==="/index.css"){let o=r.publisherSubject(s);return e==="/index.css"?x(200,R[".css"],r.renderStylesheet(o)):x(200,R[".html"],await r.renderDocument(o,{rootIndex:!0}))}let a=".html",h=!1,u=e;for(let o of[".kan.yml",".css",".svg",".md",".html"])if(e.endsWith(o)){a=o,h=!0,u=e.slice(0,-o.length);break}let f=!h&&/application\/yaml|text\/yaml/i.test(t),p=u.endsWith("/");p&&u!=="/"&&(u=u.slice(0,-1));let g=be.parse(u,s);if(!g)return M(e);if(g.kind==="package"){let o=Re(n,g.package_,g.versionSpec);if(!o)return await Fe(n,g.package_,g.versionSpec,a===".kan.yml"||f)??M(e);if(a===".kan.yml"||f){let S=n.rawByNsKey.get(`${g.package_}@${o}`);return S!==void 0?x(200,R[".kan.yml"],S):M(e)}let m=n.pkgSelfByVer.get(`${g.package_}@${o}`);if(!m)return M(e);if(a===".css")return x(200,R[".css"],r.renderStylesheet(m));if(!p)return Ke(u+"/");let k=g.versionSpec.kind==="any";if(k&&!r.hasDeclaredView(m)){let S=(n.pkgVersions.get(g.package_)||[]).map(b=>b.verStr);return x(200,R[".html"],r.renderPackageVersionList(g.package_,S,m))}return x(200,R[".html"],await r.renderDocument(m,k?{bareOverview:!0}:void 0))}if(g.kind==="resource"){let o=Re(n,g.package_,g.versionSpec);if(!o)return M(e);let m=n.bySubject.get(`${s}/${g.package_}@${o}/${g.name}`);if(!m)return M(e);switch(a){case".css":return x(200,R[".css"],r.renderStylesheet(m));case".svg":return x(200,R[".svg"],await r.renderSvg(m));case".md":{let k=r.renderRawMarkdown(m);return k===void 0?M(e):x(200,R[".md"],k)}default:return x(200,R[".html"],await r.renderDocument(m))}}return M(e)}import{readFileSync as Be}from"fs";var le=class{constructor(e={}){this.options=e}options;models=new Map;workspaceIndex;clearCache(){this.models.clear(),this.workspaceIndex=void 0}getWorkspaceIndex(){if(this.workspaceIndex)return this.workspaceIndex;let e=new Set,t=new Set;if(this.options.root!==void 0){let r=new L;for(let s of J(this.options.root))try{let a=r.parse(Be(s,"utf-8")).metadata?.namespace_;if(!a?.version)continue;let h=a.version;e.add(`${a.publisher}/${a.package_}@${h.major}.${h.minor}.${h.patch}`),t.add(`${a.publisher}/${a.package_}`)}catch{}}return this.workspaceIndex={exact:e,pkgs:t},this.workspaceIndex}async modelFor(e,t,r){let s=this.getWorkspaceIndex(),a={...this.options.fetchFn?{fetchFn:this.options.fetchFn}:{},...this.options.log?{log:this.options.log}:{}},h=t?r?s.exact.has(`${e}/${t}@${r}`):s.pkgs.has(`${e}/${t}`):[...s.pkgs].some(o=>o.startsWith(`${e}/`)),u,f;if(h&&this.options.root!==void 0){let o=this.options.root;u=`ws:${e}`,f=()=>se(o,{publisher:e,...this.options.log?{log:this.options.log}:{}})}else{let o=t?r?`${e}/${t}@${r}`:`${e}/${t}`:e;u=`rm:${o}`,f=()=>ae(o,a)}let p=this.models.get(u);if(p)return p;let g=await f();return g.lookRenderer.setLinkMode("open-world"),this.models.set(u,g),g}async handle(e,t=""){let r=e.split("/").filter(Boolean);if(r.length===0)return{status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:xe()};let s=r[0];if(!s.includes("."))return{status:404,headers:{"Content-Type":"text/html; charset=utf-8"},body:"<!doctype html><meta charset=utf-8><title>404</title><h1>404</h1><p>Expected a publisher domain as the first path segment: <code>/{publisher}/{package}/{version}/{resource}</code></p>"};let a=r.length>=2&&(r[1]==="index.html"||r[1]==="index.css"||r[1]==="index.txt"||r[1]===".well-known"),h=!a&&r.length>=2?r[1]:void 0,u=!a&&r.length>=3&&/^\d+\.\d+\.\d+$/.test(r[2])?r[2]:void 0,f=await this.modelFor(s,h,u),p=e.endsWith("/")&&r.length>1?"/":"",g="/"+r.slice(1).join("/")+p,o=await ce(f,g,t);return o.headers.Location?{...o,headers:{...o.headers,Location:`/${s}${o.headers.Location}`}}:o}};function xe(){return'<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Kanonak origin</title></head><body style="font-family:system-ui;max-width:40rem;margin:4rem auto;padding:0 1rem"><h1>Kanonak request-driven origin</h1><p>Open a resource by its address:</p><p><code>/{publisher}/{package}/{version}/{resource}</code></p><p>e.g. <code>/kanonak.org/capabilities/2.0.0/Capability</code></p></body></html>'}export{B as ClosureScopedRepository,le as RequestRouter,Se as UNIVERSAL_RENDER_BASE,ne as buildRenderDiagnostics,G as buildRenderStackWarnings,T as deriveImportClosure,xe as landingPage,ae as loadResourceModel,se as loadServerModel,ie as renderDiagnosticsHtml,C as renderRefKey,W as resolveRenderContract,ce as route};
66
+ `)}if(e==="/.well-known/kanonak-render.json")return P(200,x[".json"],JSON.stringify(te(t),null,2));if(e==="/.well-known/kanonak-render")return P(200,x[".html"],ie(te(t)));if(e==="/"||e==="/index.html"||e==="/index.css"){let o=r.publisherSubject(s);return e==="/index.css"?P(200,x[".css"],r.renderStylesheet(o)):P(200,x[".html"],await r.renderDocument(o,{rootIndex:!0}))}let a=".html",m=!1,p=e;for(let o of[".kan.yml",".css",".svg",".md",".html"])if(e.endsWith(o)){a=o,m=!0,p=e.slice(0,-o.length);break}let k=!m&&/application\/yaml|text\/yaml/i.test(n),d=p.endsWith("/");d&&p!=="/"&&(p=p.slice(0,-1));let u=be.parse(p,s);if(!u)return K(e);if(u.kind==="package"){let o=Re(t,u.package_,u.versionSpec);if(!o)return await Ve(t,u.package_,u.versionSpec,a===".kan.yml"||k)??K(e);if(a===".kan.yml"||k){let b=t.rawByNsKey.get(`${u.package_}@${o}`);return b!==void 0?P(200,x[".kan.yml"],b):K(e)}let h=t.pkgSelfByVer.get(`${u.package_}@${o}`);if(!h)return K(e);if(a===".css")return P(200,x[".css"],r.renderStylesheet(h));if(!d)return Fe(p+"/");let y=u.versionSpec.kind==="any";if(y&&!r.hasDeclaredView(h)){let b=(t.pkgVersions.get(u.package_)||[]).map($=>$.verStr);return P(200,x[".html"],r.renderPackageVersionList(u.package_,b,h))}return P(200,x[".html"],await r.renderDocument(h,y?{bareOverview:!0}:void 0))}if(u.kind==="resource"){let o=Re(t,u.package_,u.versionSpec);if(!o)return K(e);let h=t.bySubject.get(`${s}/${u.package_}@${o}/${u.name}`);if(!h)return K(e);switch(a){case".css":return P(200,x[".css"],r.renderStylesheet(h));case".svg":return P(200,x[".svg"],await r.renderSvg(h));case".md":{let y=r.renderRawMarkdown(h);return y===void 0?K(e):P(200,x[".md"],y)}default:return P(200,x[".html"],await r.renderDocument(h))}}return K(e)}import{readFileSync as Be}from"fs";var le=class{constructor(e={}){this.options=e}options;models=new Map;workspaceIndex;clearCache(){this.models.clear(),this.workspaceIndex=void 0}getWorkspaceIndex(){if(this.workspaceIndex)return this.workspaceIndex;let e=new Set,n=new Set;if(this.options.root!==void 0){let r=new E;for(let s of J(this.options.root))try{let a=r.parse(Be(s,"utf-8")).metadata?.namespace_;if(!a?.version)continue;let m=a.version;e.add(`${a.publisher}/${a.package_}@${m.major}.${m.minor}.${m.patch}`),n.add(`${a.publisher}/${a.package_}`)}catch{}}return this.workspaceIndex={exact:e,pkgs:n},this.workspaceIndex}async modelFor(e,n,r){let s=this.getWorkspaceIndex(),a={...this.options.fetchFn?{fetchFn:this.options.fetchFn}:{},...this.options.log?{log:this.options.log}:{}},m=n?r?s.exact.has(`${e}/${n}@${r}`):s.pkgs.has(`${e}/${n}`):[...s.pkgs].some(o=>o.startsWith(`${e}/`)),p,k;if(m&&this.options.root!==void 0){let o=this.options.root;p=`ws:${e}`,k=()=>se(o,{publisher:e,...this.options.log?{log:this.options.log}:{}})}else{let o=n?r?`${e}/${n}@${r}`:`${e}/${n}`:e;p=`rm:${o}`,k=()=>ae(o,a)}let d=this.models.get(p);if(d)return d;let u=await k();return u.lookRenderer.setLinkMode("open-world"),this.models.set(p,u),u}async handle(e,n=""){let r=e.split("/").filter(Boolean);if(r.length===0)return{status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:xe()};let s=r[0];if(!s.includes("."))return{status:404,headers:{"Content-Type":"text/html; charset=utf-8"},body:"<!doctype html><meta charset=utf-8><title>404</title><h1>404</h1><p>Expected a publisher domain as the first path segment: <code>/{publisher}/{package}/{version}/{resource}</code></p>"};let a=r.length>=2&&(r[1]==="index.html"||r[1]==="index.css"||r[1]==="index.txt"||r[1]===".well-known"),m=!a&&r.length>=2?r[1]:void 0,p=!a&&r.length>=3&&/^\d+\.\d+\.\d+$/.test(r[2])?r[2]:void 0,k=await this.modelFor(s,m,p),d=e.endsWith("/")&&r.length>1?"/":"",u="/"+r.slice(1).join("/")+d,o=await ce(k,u,n);return o.headers.Location?{...o,headers:{...o.headers,Location:`/${s}${o.headers.Location}`}}:o}};function xe(){return'<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Kanonak origin</title></head><body style="font-family:system-ui;max-width:40rem;margin:4rem auto;padding:0 1rem"><h1>Kanonak request-driven origin</h1><p>Open a resource by its address:</p><p><code>/{publisher}/{package}/{version}/{resource}</code></p><p>e.g. <code>/kanonak.org/capabilities/2.0.0/Capability</code></p></body></html>'}export{V as ClosureScopedRepository,le as RequestRouter,Se as UNIVERSAL_RENDER_BASE,te as buildRenderDiagnostics,W as buildRenderStackWarnings,H as deriveImportClosure,xe as landingPage,ae as loadResourceModel,se as loadServerModel,ie as renderDiagnosticsHtml,C as renderRefKey,T as resolveRenderContract,ce as route};
@@ -4,6 +4,7 @@ import type { Kanonak } from '../kanonaks/index.js';
4
4
  import { SubjectKanonak } from '../kanonaks/index.js';
5
5
  import type { LookRenderer } from '../look/index.js';
6
6
  import type { HttpCacheHooks } from '../repositories/index.js';
7
+ import type { AuthenticatedFetchFn } from '../auth/index.js';
7
8
  import type { IPackageProducer } from '../producer/index.js';
8
9
  import type { RenderStackReport } from './renderStack.js';
9
10
  /** A package version present in the served workspace. */
@@ -76,6 +77,15 @@ export interface LoadServerModelOptions {
76
77
  repository?: IKanonakDocumentRepository;
77
78
  /** HTTP write-through cache hook for the default stack (e.g. a disk cache). */
78
79
  httpCache?: HttpCacheHooks;
80
+ /**
81
+ * Transport for ALL remote fetches the default stack performs — the HTTP
82
+ * repository's index/package fetches, the publisher config fetch, AND the
83
+ * ambient render-stack package fetch below. A consumer that must control
84
+ * fetching (a sandboxed/no-disk environment, or one synthesizing sources
85
+ * from a non-HTTP store) provides this so no request escapes to a raw
86
+ * `fetch`. Ignored when `repository` is supplied (the caller owns transport).
87
+ */
88
+ fetchFn?: AuthenticatedFetchFn;
79
89
  /**
80
90
  * Progress/observability sink. When provided, model loading narrates what it
81
91
  * is doing — workspace scan results, where each render-stack package
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kanonak-protocol/sdk",
3
- "version": "4.8.0",
3
+ "version": "4.9.0",
4
4
  "description": "TypeScript SDK for the Kanonak Protocol — parse, resolve, validate, reason over, and render .kan.yml packages.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -125,7 +125,7 @@
125
125
  "yaml-parser"
126
126
  ],
127
127
  "dependencies": {
128
- "@kanonak-protocol/types": "^4.8.0",
128
+ "@kanonak-protocol/types": "^4.9.0",
129
129
  "ignore": "^7.0.5",
130
130
  "js-yaml": "^4.1.0",
131
131
  "yaml": "^2.7.0"
@@ -1,2 +0,0 @@
1
- import{a as u}from"./chunk-SC5M74NM.js";import{a as y}from"./chunk-NJ3AZYQD.js";import{e as v}from"./chunk-2ACBWC7K.js";var x="https://{publisher}/index.txt",P="https://{publisher}/{package}/{version}.kan.yml",k={version:1};function A(c){return{version:1,index:x.replaceAll("{publisher}",c),package:P.replaceAll("{publisher}",c),auth:"none"}}var f=class{cache=new Map;getConfig(t){let n=this.cache.get(t);return n||(n=this.fetchConfig(t),this.cache.set(t,n),n.catch(()=>{this.cache.get(t)===n&&this.cache.delete(t)})),n}async fetchConfig(t){let n=`https://${t}/.well-known/kanonak.json`,r;try{r=await fetch(n)}catch{return k}if(r.status===404)return k;if(!r.ok)throw new Error(`Failed to fetch publisher config: ${n} (${r.status} ${r.statusText})`);let e=await r.json();if(typeof e.version!="number")throw new Error(`Invalid publisher config at ${n}: missing or invalid "version" field`);let s={version:e.version};return typeof e.index=="string"&&(s.index=e.index),typeof e.package=="string"&&(s.package=e.package),(e.auth==="none"||e.auth==="oauth"||e.auth==="bearer")&&(s.auth=e.auth),Array.isArray(e.render)&&e.render.every(i=>typeof i=="string")&&(s.render=e.render),typeof e.resolveByRedirect=="boolean"&&(s.resolveByRedirect=e.resolveByRedirect),s}resolveIndexUrl(t,n){let r=n.index??x;return w(r,{publisher:t})}resolvePackageUrl(t,n,r,e){let s=e.package??P;return w(s,{publisher:t,package:n,version:r})}};function w(c,t){let n=c;for(let[e,s]of Object.entries(t))n=n.replaceAll(`{${e}}`,s);let r=n.match(/\{[a-z]+\}/);if(r)throw new Error(`Unresolved variable ${r[0]} in URL template: ${c}`);return n}import{VersionOperator as m}from"@kanonak-protocol/types/document/models/enums";var l=class c{indexCache=new Map;configResolver;fetchFn;constructor(t){this.configResolver=t?.configResolver??new f,this.fetchFn=t?.fetchFn}async resolveVersion(t,n){let r=await this.getPackageVersions(t,n.packageName);if(r.length===0)return null;let e=r.filter(s=>this.isVersionCompatible(s,n.version,n.versionOperator));return e.length===0?null:(e.sort((s,i)=>this.compareVersionStrings(i,s)),e[0])}async getHighestVersion(t,n){let r=await this.getPackageVersions(t,n);return r.length===0?null:[...r].sort((s,i)=>this.compareVersionStrings(i,s))[0]}async listLatestPackages(t){let n=await this.getIndex(t),r=[];for(let[e,s]of n){if(s.length===0)continue;let i=[...s].sort((o,a)=>this.compareVersionStrings(a,o));r.push({packageName:e,version:i[0]})}return r.sort((e,s)=>e.packageName.localeCompare(s.packageName)),r}async getPackageUrl(t,n,r){let e=await this.configResolver.getConfig(t);return this.configResolver.resolvePackageUrl(t,n,r,e)}getConfig(t){return this.configResolver.getConfig(t)}async getPackageVersions(t,n){return(await this.getIndex(t)).get(n)??[]}getIndex(t){let n=this.indexCache.get(t);return n||(n=this.fetchIndex(t),this.indexCache.set(t,n),n.catch(()=>{this.indexCache.get(t)===n&&this.indexCache.delete(t)})),n}async fetchIndex(t){let n=await this.configResolver.getConfig(t),r=this.configResolver.resolveIndexUrl(t,n),e=this.fetchFn?await this.fetchFn(r,t):await fetch(r);if(!e.ok)throw new Error(`Failed to fetch publisher index: ${r} (${e.status} ${e.statusText})`);let s=await e.text();return c.parseIndex(s)}static parseIndex(t){let n=new Map;for(let r of t.split(`
2
- `)){let e=r.trim();if(!e||e.startsWith("#"))continue;let s=e.indexOf("/");if(s===-1)continue;let i=e.substring(0,s),o=e.substring(s+1);if(!i||!o)continue;let a=n.get(i);a?a.push(o):n.set(i,[o])}return n}isVersionCompatible(t,n,r){let e=c.parseVersion(t);if(!e)return!1;switch(r){case m.Any:return!0;case m.Exact:return e.major===n.major&&e.minor===n.minor&&e.patch===n.patch;case m.Compatible:return e.major===n.major&&e.minor===n.minor&&e.patch>=n.patch;case m.Major:return e.major!==n.major?!1:e.minor>n.minor?!0:e.minor===n.minor?e.patch>=n.patch:!1;default:return!1}}static parseVersion(t){let n=t.split(".");if(n.length<2)return null;let r=parseInt(n[0],10),e=parseInt(n[1],10),s=n.length>=3?parseInt(n[2],10):0;return isNaN(r)||isNaN(e)||isNaN(s)?null:{major:r,minor:e,patch:s}}compareVersionStrings(t,n){let r=c.parseVersion(t),e=c.parseVersion(n);return!r&&!e?0:r?e?r.major!==e.major?r.major-e.major:r.minor!==e.minor?r.minor-e.minor:r.patch-e.patch:1:-1}};import{VersionOperator as C}from"@kanonak-protocol/types/document/models/enums";var F=class{parser=new y;publisherIndex;documents=new Map;contentCache=new Map;fetchFn;onFetch;getFromCache;constructor(t){this.onFetch=t?.onFetch,this.getFromCache=t?.getFromCache,this.fetchFn=t?.fetchFn,this.publisherIndex=t?.fetchFn?new l({fetchFn:t.fetchFn}):new l}async getHighestCompatibleVersionAsync(t,n){if((await this.publisherIndex.getConfig(t)).resolveByRedirect)return this.resolveByRedirect(t,n);let e=await this.publisherIndex.resolveVersion(t,n);if(!e)return null;let s=`${t}/${n.packageName}@${e}`,i=this.documents.get(s);if(i)return i;if(this.getFromCache){let p=this.getFromCache(t,n.packageName,e);if(p){let d=this.parser.parse(p);return u(d,t,n.packageName,e),this.documents.set(s,d),this.contentCache.set(s,p),d}}let o=await this.publisherIndex.getPackageUrl(t,n.packageName,e),a=this.fetchFn?await this.fetchFn(o,t):await fetch(o);if(!a.ok)throw new Error(`Failed to fetch Kanonak package: ${o} (${a.status} ${a.statusText})`);let g=await a.text(),h=this.parser.parse(g);return u(h,t,n.packageName,e),this.onFetch&&this.onFetch(t,n.packageName,e,g),this.documents.set(s,h),this.contentCache.set(s,g),h}async resolveByRedirect(t,n){let r=n.packageName,s=n.versionOperator===C.Exact?await this.publisherIndex.getPackageUrl(t,r,v(n.version)):`https://${t}/${r}.kan.yml`,i=await this.fetchFollowing(s,t);if(!i)return null;let o=this.parser.parse(i.content),a=o.metadata.namespace_;if(!a||!a.version)throw new Error(`Producer origin returned a package with no namespace/version for ${t}/${r}`);let g=v(a.version);u(o,t,r,g);let h=`${t}/${r}@${g}`;return this.onFetch&&this.onFetch(t,r,g,i.content),this.documents.set(h,o),this.contentCache.set(h,i.content),o}async fetchFollowing(t,n,r=4){let e=t;for(let s=0;s<r;s++){let i=this.fetchFn?await this.fetchFn(e,n):await fetch(e,{redirect:"manual"});if(i.status===301||i.status===302){let o=i.headers.get("location");if(!o)throw new Error(`Redirect with no Location header from ${e}`);e=new URL(o,e).toString();continue}if(i.status===404)return null;if(!i.ok)throw new Error(`Failed to fetch Kanonak package: ${e} (${i.status} ${i.statusText})`);return{url:e,content:await i.text()}}throw new Error(`Too many redirects resolving ${t}`)}async getAllDocumentsAsync(){return Array.from(this.documents.values())}async getDocumentAsync(t){return this.documents.get(t)??null}async getDocumentsByNamespaceAsync(t,n){return Array.from(this.documents.values()).filter(r=>{let e=r.metadata.namespace_;return e&&e.publisher===t&&e.package_===n})}async saveDocumentAsync(t,n){throw new Error("HttpKanonakDocumentRepository is read-only")}async deleteDocumentAsync(t){throw new Error("HttpKanonakDocumentRepository is read-only")}async clearNamespaceAsync(t,n){throw new Error("HttpKanonakDocumentRepository is read-only")}async getAllDocumentReferencesAsync(){return[]}async getDocumentContentAsync(t){return this.contentCache.get(t)??null}async getDocumentUriAsync(t){let n=t.match(/^(.+?)\/(.+?)@(.+)$/);if(!n)return null;let[,r,e,s]=n;return this.publisherIndex.getPackageUrl(r,e,s)}};export{A as a,f as b,l as c,F as d};