@kanonak-protocol/sdk 3.71.0 → 3.72.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 ge,b as fe,c as me,d as C,e as E,f as d}from"./chunk-Y7TGQ7UF.js";import{a as Qe}from"./chunk-F5ANO7MJ.js";import"./chunk-QHABFCRC.js";import{b as L,c as W,d as F}from"./chunk-HAR3BNTB.js";import{a as H}from"./chunk-4NO7MHS7.js";import{a as Pe,b as we,c as he}from"./chunk-GN2XODVC.js";import{a as ke,b as be}from"./chunk-PEUTCG3B.js";import"./chunk-PEJALHXK.js";import"./chunk-SC5M74NM.js";import{A as We,B as Fe,C as Ge,G 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,j as je,k as ve,l as _e,m as Ie,n as Ae,o as Te,p as Oe,q as Ve,r as $e,s as Ue,t as ze,u as Me,v as Ne,w as Je,x as He,y as qe,z as Le}from"./chunk-RRODBYIK.js";import"./chunk-SHDHMKMJ.js";import{a as Y,c as le,f as pe}from"./chunk-G2DKKSZ4.js";import{a as q}from"./chunk-TJPQETHV.js";import{a as ye}from"./chunk-BGQKZBNE.js";import"./chunk-CRKSKIAL.js";import{b as ue,c as de}from"./chunk-IOMNZBK4.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-W6T7MOKY.js";import{a as Z}from"./chunk-FUUTGGJS.js";import{c as O,d as V,e as $,f as U,g as z,h as M,i as N,j as J}from"./chunk-2ACBWC7K.js";var j="kanonak-credentials",u="credentials",Ye=1,f=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,Ye);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 ge,b as fe,c as me,d as C,e as E,f as d}from"./chunk-Y7TGQ7UF.js";import{a as Qe}from"./chunk-F5ANO7MJ.js";import"./chunk-QHABFCRC.js";import{b as L,c as W,d as F}from"./chunk-LKBG2MK6.js";import{a as H}from"./chunk-4NO7MHS7.js";import{a as Pe,b as we,c as he}from"./chunk-GN2XODVC.js";import{a as ke,b as be}from"./chunk-PEUTCG3B.js";import"./chunk-PEJALHXK.js";import"./chunk-SC5M74NM.js";import{A as We,B as Fe,C as Ge,G 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,j as je,k as ve,l as _e,m as Ie,n as Ae,o as Te,p as Oe,q as Ve,r as $e,s as Ue,t as ze,u as Me,v as Ne,w as Je,x as He,y as qe,z as Le}from"./chunk-RRODBYIK.js";import"./chunk-SHDHMKMJ.js";import{a as Y,c as le,f as pe}from"./chunk-G2DKKSZ4.js";import{a as q}from"./chunk-TJPQETHV.js";import{a as ye}from"./chunk-BGQKZBNE.js";import"./chunk-CRKSKIAL.js";import{b as ue,c as de}from"./chunk-IOMNZBK4.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-W6T7MOKY.js";import{a as Z}from"./chunk-FUUTGGJS.js";import{c as O,d as V,e as $,f as U,g as z,h as M,i as N,j as J}from"./chunk-2ACBWC7K.js";var j="kanonak-credentials",u="credentials",Ye=1,f=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,Ye);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 er(t)),o&&(s.nonce=o),await Ze(a,s,n.signingKey)}function x(n){return!n||n.length===0?!1:n.some(r=>r.toUpperCase()==="ES256")}async function Ze(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 er(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 rr=300*1e3,S=class{credentialBackend;callbackUrl;constructor(r){this.credentialBackend=new f,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 g=await k();a=g.keys,s=g.dpopKeyPair}let l=await this.credentialBackend.get(e),i=l?.clientId??null,c=l?.clientSecret??null;if(!i&&t.registrationEndpoint){let g=await this.registerClient(t.registrationEndpoint);if(!g)return{success:!1,error:`Dynamic client registration failed for '${e}'.`};i=g.clientId,c=g.clientSecret??null}if(!i)return{success:!1,error:`No OAuth client credentials for '${e}'.`};let m=tr(),p=await nr(m),R=or(),A=sr(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)},rr),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 tr(){let n=new Uint8Array(32);return crypto.getRandomValues(n),B(n.buffer)}async function nr(n){let r=new TextEncoder().encode(n),e=await crypto.subtle.digest("SHA-256",r);return B(e)}function or(){let n=new Uint8Array(16);return crypto.getRandomValues(n),B(n.buffer)}function sr(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,f as BrowserCredentialBackend,S as BrowserOAuthFlow,Fe as ClassDefinitionRule,Ie as ClassHierarchyCycleRule,X as DefinedKanonak,ze as DefinitionPropertyReferenceRule,fe 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,ge 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,Me as XsdImportRule,x as browserServerSupportsDPoP,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,M as isCompatibleVersion,C as isExpired,N as isMajorCompatible,d as normalizeHost,z as parseVersionString,he as parseWithPositions,J as pickHighestDocument,V as versionsEqual};
@@ -1 +1 @@
1
- import{d as v}from"./chunk-HAR3BNTB.js";import{a as A}from"./chunk-4NO7MHS7.js";import{a as f}from"./chunk-TJPQETHV.js";import{c as w,d as I,h as R,i as F}from"./chunk-2ACBWC7K.js";import*as i from"fs/promises";import*as c from"path";import{pathToFileURL as b}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 I(r,t.version);case P.Compatible:return R(r,t.version);case P.Major:return F(r,t.version);case P.Any:return w(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 w(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],p=m[1].replace("@","@")+".kan.yml";n=c.join(this.rootPath,l,p)}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=b(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 b(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 d from"fs";var S=(n=>(n.NotFound="NotFound",n.Workspace="Workspace",n.Cache="Cache",n))(S||{}),k=class{cache;workspace;constructor(e,t,n){let o=n??new f;d.existsSync(e)||d.mkdirSync(e,{recursive:!0}),d.existsSync(t)||d.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 N}from"path";function g(){let u=process.env.KANONAK_PACKAGE_CACHE;return u||N(_(),".kanonak","packages")}var C=class u{static createComposite(e,t,n){let o=e??g(),s=t??".";return new k(o,s,n)}static createFromEnvironment(e){let t=g(),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{readFileSync as B,readdirSync as H}from"fs";import{join as x}from"path";var $=new Set(["node_modules",".kanonak",".git","_site","build",".stage"]);function K(u,e=[]){for(let t of H(u,{withFileTypes:!0}))t.isDirectory()?$.has(t.name)||K(x(u,t.name),e):t.name.endsWith(".kan.yml")&&e.push(x(u,t.name));return e}async function j(u,e=new f,t={}){let n=new A(e);for(let m of K(u))try{let l=e.parse(B(m,"utf-8")),h=l.metadata?.namespace_,p=h?.version;h&&p&&await n.saveDocumentAsync(l,`${h.publisher}/${h.package_}@${p.major}.${p.minor}.${p.patch}`)}catch{}let o=new y(g(),!0,e),s=new Map,a=t.httpCache??{getFromCache:(m,l,h)=>s.get(`${m}|${l}|${h}`)??null,onFetch:(m,l,h,p)=>{s.set(`${m}|${l}|${h}`,p)}},r=new v({getFromCache:a.getFromCache,onFetch:a.onFetch});return new D(n,o,r)}export{y as a,S as b,k as c,g as d,C as e,D as f,K as g,j as h};
1
+ import{d as v}from"./chunk-LKBG2MK6.js";import{a as A}from"./chunk-4NO7MHS7.js";import{a as f}from"./chunk-TJPQETHV.js";import{c as w,d as I,h as R,i as F}from"./chunk-2ACBWC7K.js";import*as i from"fs/promises";import*as c from"path";import{pathToFileURL as b}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 I(r,t.version);case P.Compatible:return R(r,t.version);case P.Major:return F(r,t.version);case P.Any:return w(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 w(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],p=m[1].replace("@","@")+".kan.yml";n=c.join(this.rootPath,l,p)}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=b(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 b(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 d from"fs";var S=(n=>(n.NotFound="NotFound",n.Workspace="Workspace",n.Cache="Cache",n))(S||{}),k=class{cache;workspace;constructor(e,t,n){let o=n??new f;d.existsSync(e)||d.mkdirSync(e,{recursive:!0}),d.existsSync(t)||d.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 N}from"path";function g(){let u=process.env.KANONAK_PACKAGE_CACHE;return u||N(_(),".kanonak","packages")}var C=class u{static createComposite(e,t,n){let o=e??g(),s=t??".";return new k(o,s,n)}static createFromEnvironment(e){let t=g(),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{readFileSync as B,readdirSync as H}from"fs";import{join as x}from"path";var $=new Set(["node_modules",".kanonak",".git","_site","build",".stage"]);function K(u,e=[]){for(let t of H(u,{withFileTypes:!0}))t.isDirectory()?$.has(t.name)||K(x(u,t.name),e):t.name.endsWith(".kan.yml")&&e.push(x(u,t.name));return e}async function j(u,e=new f,t={}){let n=new A(e);for(let m of K(u))try{let l=e.parse(B(m,"utf-8")),h=l.metadata?.namespace_,p=h?.version;h&&p&&await n.saveDocumentAsync(l,`${h.publisher}/${h.package_}@${p.major}.${p.minor}.${p.patch}`)}catch{}let o=new y(g(),!0,e),s=new Map,a=t.httpCache??{getFromCache:(m,l,h)=>s.get(`${m}|${l}|${h}`)??null,onFetch:(m,l,h,p)=>{s.set(`${m}|${l}|${h}`,p)}},r=new v({getFromCache:a.getFromCache,onFetch:a.onFetch});return new D(n,o,r)}export{y as a,S as b,k as c,g as d,C as e,D as f,K as g,j as h};
@@ -0,0 +1,2 @@
1
+ import{a as u}from"./chunk-SC5M74NM.js";import{a as y}from"./chunk-TJPQETHV.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};
package/dist/index.d.ts CHANGED
@@ -31,4 +31,6 @@ export { LookRenderer, resolveDisplayValue } from './look/index.js';
31
31
  export type { ResolvedLook, DisplayValue } from './look/index.js';
32
32
  export { ViewMaterializer } from './view/index.js';
33
33
  export type { MaterializeOptions, MaterializeResult } from './view/index.js';
34
+ export { PackageBuilder, ImportBook, contentAddressedName, sanitizeName, ProducerRepository, EntitlementProducer, EntitlementDeniedError, allowAllPolicy, noopMeter, } from './producer/index.js';
35
+ export type { BuiltPackage, ImportEntry, IPackageProducer, ProduceResult, VersionRange, IEntitlementPolicy, IMeter, ProduceContext, PackageAddress, EntitlementDecision, RequestPrincipal, } from './producer/index.js';
34
36
  export { canonicalForm, canonicalHash } from './canonical/index.js';
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
- import{a as Qt,b as en,c as tn,d as nn,e as le}from"./chunk-FX7JDGL6.js";import{a as Jn,c as pe,e as xe,h as Ie,i as je,j as qn}from"./chunk-MCU5IAMS.js";import{a as Yt,b as Zt,c as Xt,d as T,e as V,f as c}from"./chunk-Y7TGQ7UF.js";import{a as Gn}from"./chunk-F5ANO7MJ.js";import"./chunk-QHABFCRC.js";import{a as Et,b as Rt,c as vt,d as $t,e as Kt,f as Tt,g as Vt,h as Ut}from"./chunk-OFSARZX6.js";import{b as xt,c as It,d as Bt}from"./chunk-HAR3BNTB.js";import{a as Ct}from"./chunk-4NO7MHS7.js";import{a as on,b as an,c as sn,d as cn}from"./chunk-GN2XODVC.js";import{a as ln,b as gn}from"./chunk-PEUTCG3B.js";import{a as pn}from"./chunk-PEJALHXK.js";import{a as jt}from"./chunk-SC5M74NM.js";import{A as Mn,B as Hn,C as zn,G as Wn,a as hn,b as kn,c as bn,d as Sn,e as wn,f as Pn,g as Cn,h as En,i as Rn,j as vn,k as $n,l as Kn,m as xn,n as In,o as jn,p as Bn,q as Tn,r as Vn,s as Un,t as On,u as Ln,v as Nn,w as _n,x as An,y as Dn,z as Fn}from"./chunk-RRODBYIK.js";import"./chunk-SHDHMKMJ.js";import{a as g,b as te,c as At,d as Gt,e as Jt,f as ce}from"./chunk-G2DKKSZ4.js";import{a as Q}from"./chunk-TJPQETHV.js";import{a as qt,b as un,c as dn,d as f,e as mn,f as fn,g as yn}from"./chunk-BGQKZBNE.js";import{f as B,j as S,k as ue,l as de,m as Ke}from"./chunk-CRKSKIAL.js";import{b as Dt,c as Ft,d as b,e as Mt,f as Ht,h as zt,j as Wt}from"./chunk-IOMNZBK4.js";import{a as Ot,b as ee,c as y,d as h,e as Nt,f as _t,g as ne,h as re,i as oe,j as ae,k as ie,l as se}from"./chunk-W6T7MOKY.js";import{a as Lt}from"./chunk-FUUTGGJS.js";import{a as yt,b as gt,c as I,d as ht,e as j,f as kt,g as bt,h as St,i as wt,j as Pt}from"./chunk-2ACBWC7K.js";import{a as rn}from"./chunk-ODIECDN7.js";import{VersionOperator as Ua}from"@kanonak-protocol/types/document/models/enums";import{existsSync as mr,readFileSync as fr}from"fs";import{homedir as yr}from"os";import{join as gr}from"path";import{execFile as Yn}from"child_process";import{promisify as Zn}from"util";var U=Zn(Yn),O="kanonak",L="/usr/bin/security",w=class{async get(e){let n=c(e);try{let{stdout:r}=await U(L,["find-generic-password","-s",O,"-a",n,"-w"],{timeout:1e4});try{return JSON.parse(r.trim())}catch{throw new Error(`Stored credential for '${n}' is corrupted (not valid JSON).
2
- Run 'kanonak logout ${n}' then 'kanonak login ${n}' to fix.`)}}catch(r){if(Be(r,44))return null;throw new Error(`macOS Keychain read failed for '${n}': ${N(r)}
1
+ import{a as ir,b as sr,c as cr,d as lr,e as fe}from"./chunk-FX7JDGL6.js";import{a as Qr,c as ke,e as Te,h as Ne,i as Oe,j as en}from"./chunk-MCU5IAMS.js";import{a as nr,b as or,c as ar,d as U,e as _,f as c}from"./chunk-Y7TGQ7UF.js";import{a as Xr}from"./chunk-F5ANO7MJ.js";import"./chunk-QHABFCRC.js";import{a as jt,b as Bt,c as At,d as Vt,e as Dt,f as _t,g as Lt,h as Ft}from"./chunk-ATH6636H.js";import{b as Tt,c as Nt,d as Ut}from"./chunk-LKBG2MK6.js";import{a as It}from"./chunk-4NO7MHS7.js";import{a as dr,b as pr,c as mr,d as fr}from"./chunk-GN2XODVC.js";import{a as yr,b as wr}from"./chunk-PEUTCG3B.js";import{a as hr}from"./chunk-PEJALHXK.js";import{a as Ot}from"./chunk-SC5M74NM.js";import{A as Jr,B as qr,C as Yr,G as Zr,a as Sr,b as Rr,c as vr,d as Er,e as Cr,f as xr,g as Kr,h as $r,i as Ir,j as jr,k as Br,l as Ar,m as Vr,n as Dr,o as Tr,p as Nr,q as Or,r as Ur,s as _r,t as Lr,u as Fr,v as Mr,w as Hr,x as zr,y as Wr,z as Gr}from"./chunk-RRODBYIK.js";import"./chunk-SHDHMKMJ.js";import{a as y,b as se,c as Gt,d as er,e as tr,f as v}from"./chunk-G2DKKSZ4.js";import{a as S}from"./chunk-TJPQETHV.js";import{a as rr,b as ye,c as gr,d as g,e as kr,f as br,g as Pr}from"./chunk-BGQKZBNE.js";import{f as O,j as E,k as ge,l as he,m as De}from"./chunk-CRKSKIAL.js";import{b as Jt,c as qt,d as R,e as Yt,f as Zt,h as Xt,j as Qt}from"./chunk-IOMNZBK4.js";import{a as Mt,b as ie,c as f,d as k,e as zt,f as Wt,g as ce,h as le,i as ue,j as de,k as pe,l as me}from"./chunk-W6T7MOKY.js";import{a as Ht}from"./chunk-FUUTGGJS.js";import{a as St,b as Rt,c as N,d as vt,e as h,f as Et,g as Ct,h as xt,i as Kt,j as $t}from"./chunk-2ACBWC7K.js";import{a as ur}from"./chunk-ODIECDN7.js";import{VersionOperator as ni}from"@kanonak-protocol/types/document/models/enums";import{existsSync as bn,readFileSync as Pn}from"fs";import{homedir as wn}from"os";import{join as Sn}from"path";import{execFile as tn}from"child_process";import{promisify as rn}from"util";var L=rn(tn),F="kanonak",M="/usr/bin/security",C=class{async get(e){let t=c(e);try{let{stdout:n}=await L(M,["find-generic-password","-s",F,"-a",t,"-w"],{timeout:1e4});try{return JSON.parse(n.trim())}catch{throw new Error(`Stored credential for '${t}' is corrupted (not valid JSON).
2
+ Run 'kanonak logout ${t}' then 'kanonak login ${t}' to fix.`)}}catch(n){if(Ue(n,44))return null;throw new Error(`macOS Keychain read failed for '${t}': ${H(n)}
3
3
  The Keychain may be locked or inaccessible.
4
- Try unlocking it via Keychain Access.app or running 'security unlock-keychain'.`)}}async store(e,n){let r=c(e),o=JSON.stringify(n);try{await U(L,["add-generic-password","-s",O,"-a",r,"-U","-w",o],{timeout:1e4})}catch(a){throw new Error(`macOS Keychain write failed for '${r}': ${N(a)}
4
+ Try unlocking it via Keychain Access.app or running 'security unlock-keychain'.`)}}async store(e,t){let n=c(e),o=JSON.stringify(t);try{await L(M,["add-generic-password","-s",F,"-a",n,"-U","-w",o],{timeout:1e4})}catch(a){throw new Error(`macOS Keychain write failed for '${n}': ${H(a)}
5
5
  Ensure the Keychain is unlocked and the CLI has write permission.
6
- On managed devices, your IT policy may block credential storage.`)}}async remove(e){let n=c(e);try{await U(L,["delete-generic-password","-s",O,"-a",n],{timeout:1e4})}catch(r){if(Be(r,44))return;console.warn(` Warning: macOS Keychain delete failed for '${n}': ${N(r)}
7
- The credential may not have been fully removed.`)}}async list(){try{let{stdout:e}=await U(L,["dump-keychain"],{timeout:1e4}),n=[],r=!1;for(let o of e.split(`
8
- `))if(o.includes(`"svce"<blob>="${O}"`)&&(r=!0),r&&o.includes('"acct"<blob>=')){let a=o.match(/"acct"<blob>="([^"]+)"/);a&&n.push(a[1]),r=!1}return n}catch(e){return console.warn(` Warning: Could not enumerate Keychain entries: ${N(e)}`),[]}}};function Be(t,e){return typeof t=="object"&&t!==null&&"code"in t&&t.code===e}function N(t){return t instanceof Error?t.message:String(t)}import{execFile as Xn}from"child_process";import{promisify as Qn}from"util";var er=Qn(Xn),_="kanonak:",P=class{async get(e){let n=_+c(e),r=`
9
- ${D}
6
+ On managed devices, your IT policy may block credential storage.`)}}async remove(e){let t=c(e);try{await L(M,["delete-generic-password","-s",F,"-a",t],{timeout:1e4})}catch(n){if(Ue(n,44))return;console.warn(` Warning: macOS Keychain delete failed for '${t}': ${H(n)}
7
+ The credential may not have been fully removed.`)}}async list(){try{let{stdout:e}=await L(M,["dump-keychain"],{timeout:1e4}),t=[],n=!1;for(let o of e.split(`
8
+ `))if(o.includes(`"svce"<blob>="${F}"`)&&(n=!0),n&&o.includes('"acct"<blob>=')){let a=o.match(/"acct"<blob>="([^"]+)"/);a&&t.push(a[1]),n=!1}return t}catch(e){return console.warn(` Warning: Could not enumerate Keychain entries: ${H(e)}`),[]}}};function Ue(r,e){return typeof r=="object"&&r!==null&&"code"in r&&r.code===e}function H(r){return r instanceof Error?r.message:String(r)}import{execFile as nn}from"child_process";import{promisify as on}from"util";var an=on(nn),z="kanonak:",x=class{async get(e){let t=z+c(e),n=`
9
+ ${G}
10
10
  $target = [Console]::In.ReadLine()
11
11
  $ptr = [IntPtr]::Zero
12
12
  $result = [CredMan]::CredRead($target, 1, 0, [ref]$ptr)
@@ -18,8 +18,8 @@ try {
18
18
  [System.Text.Encoding]::Unicode.GetString($bytes)
19
19
  } finally {
20
20
  [CredMan]::CredFree($ptr)
21
- }`;try{let{stdout:o}=await A(r,n),a=o.trim();return a?JSON.parse(a):null}catch{return null}}async store(e,n){let r=_+c(e),o=JSON.stringify(n),a=`
22
- ${D}
21
+ }`;try{let{stdout:o}=await W(n,t),a=o.trim();return a?JSON.parse(a):null}catch{return null}}async store(e,t){let n=z+c(e),o=JSON.stringify(t),a=`
22
+ ${G}
23
23
  $target = [Console]::In.ReadLine()
24
24
  $json = [Console]::In.ReadLine()
25
25
  $bytes = [System.Text.Encoding]::Unicode.GetBytes($json)
@@ -35,13 +35,13 @@ try {
35
35
  if (-not $result) { throw "CredWrite failed" }
36
36
  } finally {
37
37
  [System.Runtime.InteropServices.Marshal]::FreeHGlobal($cred.CredentialBlob)
38
- }`;try{await A(a,`${r}
39
- ${o}`)}catch(i){throw new Error(`Windows Credential Manager write failed: ${String(i)}`)}}async remove(e){let n=_+c(e),r=`
40
- ${D}
38
+ }`;try{await W(a,`${n}
39
+ ${o}`)}catch(i){throw new Error(`Windows Credential Manager write failed: ${String(i)}`)}}async remove(e){let t=z+c(e),n=`
40
+ ${G}
41
41
  $target = [Console]::In.ReadLine()
42
- [CredMan]::CredDelete($target, 1, 0) | Out-Null`;try{await A(r,n)}catch{}}async list(){let e=`
43
- ${D}
44
- ${tr}
42
+ [CredMan]::CredDelete($target, 1, 0) | Out-Null`;try{await W(n,t)}catch{}}async list(){let e=`
43
+ ${G}
44
+ ${sn}
45
45
  $prefix = [Console]::In.ReadLine()
46
46
  $count = 0
47
47
  $pCreds = [IntPtr]::Zero
@@ -55,8 +55,8 @@ if ([CredMan]::CredEnumerate($null, 0, [ref]$count, [ref]$pCreds)) {
55
55
  }
56
56
  }
57
57
  [CredMan]::CredFree($pCreds)
58
- }`;try{let{stdout:n}=await A(e,_);return n.trim().split(`
59
- `).map(r=>r.trim()).filter(Boolean)}catch{return[]}}};async function A(t,e){for(let n of["pwsh","powershell"])try{return await er(n,["-NoProfile","-NonInteractive","-Command",t],{timeout:15e3,...e!==void 0&&{input:e}})}catch(r){if(n==="powershell")throw r}throw new Error("Neither pwsh nor powershell found")}var D=`
58
+ }`;try{let{stdout:t}=await W(e,z);return t.trim().split(`
59
+ `).map(n=>n.trim()).filter(Boolean)}catch{return[]}}};async function W(r,e){for(let t of["pwsh","powershell"])try{return await an(t,["-NoProfile","-NonInteractive","-Command",r],{timeout:15e3,...e!==void 0&&{input:e}})}catch(n){if(t==="powershell")throw n}throw new Error("Neither pwsh nor powershell found")}var G=`
60
60
  Add-Type -TypeDefinition @"
61
61
  using System;
62
62
  using System.Runtime.InteropServices;
@@ -87,13 +87,13 @@ public class CredMan {
87
87
  [DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
88
88
  public static extern bool CredEnumerate(string filter, int flags, out int count, out IntPtr credentials);
89
89
  }
90
- "@`,tr="";import{execFile as nr,spawn as rr}from"child_process";import{promisify as or}from"util";var M=or(nr),F="kanonak",C=class{async get(e){let n=c(e);try{let{stdout:r}=await M("secret-tool",["lookup","service",F,"publisher",n],{timeout:1e4}),o=r.trim();return o?JSON.parse(o):null}catch{return null}}async store(e,n){let r=c(e),o=JSON.stringify(n);await new Promise((a,i)=>{let s=rr("secret-tool",["store","--label",`Kanonak: ${r}`,"service",F,"publisher",r],{stdio:["pipe","ignore","ignore"],timeout:1e4});s.stdin.write(o),s.stdin.end(),s.on("close",l=>{l===0?a():i(new Error(`secret-tool store exited with code ${l}`))}),s.on("error",i)})}async remove(e){let n=c(e);try{await M("secret-tool",["clear","service",F,"publisher",n],{timeout:1e4})}catch{}}async list(){try{let{stdout:e}=await M("secret-tool",["search","service",F],{timeout:1e4}),n=[];for(let r of e.split(`
91
- `)){let o=r.match(/attribute\.publisher\s*=\s*(.+)/);o&&n.push(o[1].trim())}return n}catch{return[]}}};async function me(){try{return await M("sh",["-c","command -v secret-tool"],{timeout:5e3}),!0}catch{return!1}}import{existsSync as Te,mkdirSync as Ve,readFileSync as Ue,writeFileSync as Oe}from"fs";import{createCipheriv as ar,createDecipheriv as ir,randomBytes as Le}from"crypto";import{homedir as sr}from"os";import{join as ge,dirname as Ne}from"path";var Ae=ge(sr(),".config","kanonak"),E=ge(Ae,"keyring.key"),H=ge(Ae,"credentials.enc"),_e="aes-256-gcm",fe=32,k=12,ye=16,R=class{async get(e){let n=this.loadStore(),r=c(e);return n[r]??null}async store(e,n){let r=this.loadStore(),o=c(e);r[o]=n,this.saveStore(r)}async remove(e){let n=this.loadStore(),r=c(e);delete n[r],this.saveStore(n)}async list(){let e=this.loadStore();return Object.keys(e)}loadStore(){if(!Te(H))return{};try{let e=this.getOrCreateKey(),n=Ue(H);if(n.length<k+ye)return{};let r=n.subarray(0,k),o=n.subarray(k,k+ye),a=n.subarray(k+ye),i=ir(_e,e,r);i.setAuthTag(o);let s=Buffer.concat([i.update(a),i.final()]);return JSON.parse(s.toString("utf-8"))}catch{return{}}}saveStore(e){let n=this.getOrCreateKey(),r=Le(k),o=ar(_e,n,r),a=Buffer.from(JSON.stringify(e),"utf-8"),i=Buffer.concat([o.update(a),o.final()]),s=o.getAuthTag(),l=Buffer.concat([r,s,i]);Ve(Ne(H),{recursive:!0}),Oe(H,l,{mode:384})}getOrCreateKey(){if(Te(E)){let n=Ue(E);if(n.length!==fe)throw new Error(`Credential keyring key is corrupted (expected ${fe} bytes, got ${n.length}). Delete ${E} and re-authenticate.`);return n}let e=Le(fe);return Ve(Ne(E),{recursive:!0}),Oe(E,e,{mode:384}),e}};import{execFile as cr}from"child_process";import{promisify as lr}from"util";var ur=lr(cr),De=3e4,v=class{constructor(e){this.helperPath=e}helperPath;async get(e){let n=c(e);try{let o=(await this.runHelper("get",{publisher:n})).trim();return o?JSON.parse(o):null}catch(r){throw new Error(`Credential helper '${this.helperPath}' failed to read credential for '${n}': ${z(r)}
90
+ "@`,sn="";import{execFile as cn,spawn as ln}from"child_process";import{promisify as un}from"util";var q=un(cn),J="kanonak",K=class{async get(e){let t=c(e);try{let{stdout:n}=await q("secret-tool",["lookup","service",J,"publisher",t],{timeout:1e4}),o=n.trim();return o?JSON.parse(o):null}catch{return null}}async store(e,t){let n=c(e),o=JSON.stringify(t);await new Promise((a,i)=>{let s=ln("secret-tool",["store","--label",`Kanonak: ${n}`,"service",J,"publisher",n],{stdio:["pipe","ignore","ignore"],timeout:1e4});s.stdin.write(o),s.stdin.end(),s.on("close",l=>{l===0?a():i(new Error(`secret-tool store exited with code ${l}`))}),s.on("error",i)})}async remove(e){let t=c(e);try{await q("secret-tool",["clear","service",J,"publisher",t],{timeout:1e4})}catch{}}async list(){try{let{stdout:e}=await q("secret-tool",["search","service",J],{timeout:1e4}),t=[];for(let n of e.split(`
91
+ `)){let o=n.match(/attribute\.publisher\s*=\s*(.+)/);o&&t.push(o[1].trim())}return t}catch{return[]}}};async function be(){try{return await q("sh",["-c","command -v secret-tool"],{timeout:5e3}),!0}catch{return!1}}import{existsSync as _e,mkdirSync as Le,readFileSync as Fe,writeFileSync as Me}from"fs";import{createCipheriv as dn,createDecipheriv as pn,randomBytes as He}from"crypto";import{homedir as mn}from"os";import{join as Se,dirname as ze}from"path";var Ge=Se(mn(),".config","kanonak"),$=Se(Ge,"keyring.key"),Y=Se(Ge,"credentials.enc"),We="aes-256-gcm",Pe=32,b=12,we=16,I=class{async get(e){let t=this.loadStore(),n=c(e);return t[n]??null}async store(e,t){let n=this.loadStore(),o=c(e);n[o]=t,this.saveStore(n)}async remove(e){let t=this.loadStore(),n=c(e);delete t[n],this.saveStore(t)}async list(){let e=this.loadStore();return Object.keys(e)}loadStore(){if(!_e(Y))return{};try{let e=this.getOrCreateKey(),t=Fe(Y);if(t.length<b+we)return{};let n=t.subarray(0,b),o=t.subarray(b,b+we),a=t.subarray(b+we),i=pn(We,e,n);i.setAuthTag(o);let s=Buffer.concat([i.update(a),i.final()]);return JSON.parse(s.toString("utf-8"))}catch{return{}}}saveStore(e){let t=this.getOrCreateKey(),n=He(b),o=dn(We,t,n),a=Buffer.from(JSON.stringify(e),"utf-8"),i=Buffer.concat([o.update(a),o.final()]),s=o.getAuthTag(),l=Buffer.concat([n,s,i]);Le(ze(Y),{recursive:!0}),Me(Y,l,{mode:384})}getOrCreateKey(){if(_e($)){let t=Fe($);if(t.length!==Pe)throw new Error(`Credential keyring key is corrupted (expected ${Pe} bytes, got ${t.length}). Delete ${$} and re-authenticate.`);return t}let e=He(Pe);return Le(ze($),{recursive:!0}),Me($,e,{mode:384}),e}};import{execFile as fn}from"child_process";import{promisify as yn}from"util";var gn=yn(fn),Je=3e4,j=class{constructor(e){this.helperPath=e}helperPath;async get(e){let t=c(e);try{let o=(await this.runHelper("get",{publisher:t})).trim();return o?JSON.parse(o):null}catch(n){throw new Error(`Credential helper '${this.helperPath}' failed to read credential for '${t}': ${Z(n)}
92
92
  Verify the helper binary exists, is executable, and implements the Kanonak credential helper protocol.
93
- Check the 'credentialHelper' path in ~/.kanonak/config.json.`)}}async store(e,n){let r=c(e);try{await this.runHelper("store",{publisher:r,credential:n})}catch(o){throw new Error(`Credential helper '${this.helperPath}' failed to store credential for '${r}': ${z(o)}
94
- Verify the helper binary supports the 'store' action.`)}}async remove(e){let n=c(e);try{await this.runHelper("erase",{publisher:n})}catch(r){console.warn(` Warning: Credential helper '${this.helperPath}' failed to erase credential for '${n}': ${z(r)}`)}}async list(){try{let e=await this.runHelper("list",void 0);return JSON.parse(e.trim())}catch(e){return console.warn(` Warning: Credential helper '${this.helperPath}' failed to list credentials: ${z(e)}`),[]}}async runHelper(e,n){try{let{stdout:r}=await ur(this.helperPath,[e],{...n&&{input:JSON.stringify(n)},timeout:De});return r}catch(r){throw dr(r)?new Error(`Credential helper not found at '${this.helperPath}'.
95
- Check the 'credentialHelper' path in ~/.kanonak/config.json.`):pr(r)?new Error(`Credential helper '${this.helperPath}' timed out after ${De/1e3}s on '${e}'.
96
- The helper may be waiting for authentication to an external vault.`):r}}};function z(t){return t instanceof Error?t.message:String(t)}function dr(t){return t instanceof Error&&"code"in t&&t.code==="ENOENT"}function pr(t){return t instanceof Error&&"killed"in t&&t.killed}var he=gr(yr(),".kanonak","config.json"),W=class{backend=null;backendReady=null;async getBackend(){if(this.backend)return this.backend;if(this.backendReady)return this.backendReady;this.backendReady=this.resolveBackend();try{return this.backend=await this.backendReady,this.backend}catch(e){throw this.backendReady=null,e}}async getToken(e){let n=hr(e);if(n)return n;let o=await(await this.getBackend()).get(e);return!o||!V(o)?null:o.accessToken??null}async getCredential(e){return(await this.getBackend()).get(e)}async store(e,n){return(await this.getBackend()).store(e,n)}async remove(e){return(await this.getBackend()).remove(e)}async list(){return(await this.getBackend()).list()}async resolveBackend(){let e=kr();return e.credentialHelper?new v(e.credentialHelper):process.platform==="darwin"?new w:process.platform==="win32"?new P:await me()?new C:new R}};function hr(t){let n="KANONAK_TOKEN_"+c(t).replace(/[.\-]/g,"_").toUpperCase();return process.env[n]??null}function kr(){if(!mr(he))return{};try{return JSON.parse(fr(he,"utf-8"))}catch(t){let e=t instanceof Error?t.message:String(t);return console.warn(` Warning: Failed to parse ${he}: ${e}
97
- Using default credential backend. Fix the JSON syntax or delete the file.`),{}}}import{createHash as br,createPrivateKey as Sr,generateKeyPairSync as wr,randomUUID as Pr,sign as Cr}from"crypto";function Me(){let{publicKey:t,privateKey:e}=wr("ec",{namedCurve:"P-256"});return{publicKey:t.export({format:"jwk"}),privateKey:e.export({format:"jwk"})}}function $(t,e,n,r,o,a){let i={alg:"ES256",typ:"dpop+jwt",jwk:{kty:e.kty,crv:e.crv,x:e.x,y:e.y}},s={jti:Pr(),htm:n.toUpperCase(),htu:r,iat:Math.floor(Date.now()/1e3)};return o&&(s.ath=br("sha256").update(o).digest("base64url")),a&&(s.nonce=a),Er(i,s,t)}function He(t){return!t||t.length===0?!1:t.some(e=>e.toUpperCase()==="ES256")}function Er(t,e,n){let r=Fe(JSON.stringify(t)),o=Fe(JSON.stringify(e)),a=`${r}.${o}`,i=Sr({key:n,format:"jwk"}),l=Cr("SHA256",Buffer.from(a),{key:i,dsaEncoding:"ieee-p1363"}).toString("base64url");return`${a}.${l}`}function Fe(t){return Buffer.from(t,"utf-8").toString("base64url")}function ze(t){let e=new Map;return async(n,r,o="GET")=>{if(!t)return fetch(n,{method:o});let a=await t.getCredential(r);if(!a?.accessToken)return fetch(n,{method:o});T(a)&&console.warn(` Warning: Access token for '${r}' is expired. Run 'kanonak login ${r}' to re-authenticate.`);let i={};if(a.dpopKeyPair){let l=e.get(r);try{let u=$(a.dpopKeyPair.privateKey,a.dpopKeyPair.publicKey,o,n,a.accessToken,l);i.Authorization=`DPoP ${a.accessToken}`,i.DPoP=u}catch(u){let d=u instanceof Error?u.message:String(u);console.error(` Error: Failed to create DPoP proof for '${r}': ${d}
98
- The stored key pair may be corrupted. Run 'kanonak login ${r}' to re-authenticate.`),i.Authorization=`Bearer ${a.accessToken}`}}else i.Authorization=`Bearer ${a.accessToken}`;let s=await fetch(n,{method:o,headers:i});if(s.status===401&&a.dpopKeyPair){let l=s.headers.get("DPoP-Nonce");if(l){e.set(r,l);try{let u=$(a.dpopKeyPair.privateKey,a.dpopKeyPair.publicKey,o,n,a.accessToken,l);i.DPoP=u,s=await fetch(n,{method:o,headers:i})}catch{}}}return s}}import{readFileSync as Rr,writeFileSync as vr,existsSync as $r}from"fs";import{createHash as Kr}from"crypto";import We from"js-yaml";var Ge="kanonak.lock",xr=`# This file is generated by Kanonak CLI. Do not edit manually.
99
- `;function Je(t=Ge){if(!$r(t))return null;let e=Rr(t,"utf-8"),n=We.load(e);return!n||typeof n!="object"||n.version!=="1"?null:{version:"1",lastUpdated:n.lastUpdated??new Date().toISOString(),packages:n.packages??{}}}function qe(t,e=Ge){t.lastUpdated=new Date().toISOString();let n={};for(let o of Object.keys(t.packages).sort())n[o]=t.packages[o];t.packages=n;let r=We.dump(t,{lineWidth:-1,sortKeys:!1,quotingType:'"'});vr(e,xr+r,"utf-8")}function Ye(t){return`sha256:${Kr("sha256").update(t).digest("hex")}`}import*as Se from"js-yaml";import{createHash as Ir}from"crypto";function ke(t){let e=[];for(let r of t)r instanceof y&&e.push(jr(r));return e.sort((r,o)=>r.uri<o.uri?-1:r.uri>o.uri?1:0),JSON.stringify({subjects:e})}function G(t){let e=ke(t);return`sha256:${Ir("sha256").update(e,"utf8").digest("hex")}`}function jr(t){let e=Lr(t),n=be(t.statement);return{uri:e,statements:n}}function be(t){let e=[];for(let n of t){let r=Br(n);r&&e.push(r)}return e.sort((n,r)=>n.predicate<r.predicate?-1:n.predicate>r.predicate?1:0),e}function Br(t){let e=Or(t);if(!e)return;let n=Tr(t);if(n)return Ur(e,n)}function Tr(t){if(t instanceof ne)return{type:"string",value:t.object};if(t instanceof re)return{type:"number",value:et(t.object)};if(t instanceof oe)return{type:"boolean",value:t.object};if(t instanceof ae)return{type:"ref",value:Xe(t.object)};if(t instanceof ie){let e=t.object;return Ze(e)}if(t instanceof se)return{type:"list",items:t.object.map(Vr)}}function Ze(t){let e=be(t.statement);return t.name&&t.name.length>0?{type:"embedded",name:t.name,statements:e}:{type:"embedded",statements:e}}function Vr(t){if(t instanceof h)return{type:"ref",value:Xe(t)};if(t instanceof g)return Ze(t);if(t instanceof te){let e=t.value;if(typeof e=="string")return{type:"string",value:e};if(typeof e=="number")return{type:"number",value:et(e)};if(typeof e=="boolean")return{type:"boolean",value:e}}if(t instanceof ee)return{type:"embedded",statements:be(t.statement)};throw new Error(`canonicalForm: list item of unrecognized kind (${t.constructor?.name??typeof t}); add canonicalization support before hashing data that contains it`)}function Ur(t,e){switch(e.type){case"string":return{predicate:t,type:"string",value:e.value};case"number":return{predicate:t,type:"number",value:e.value};case"boolean":return{predicate:t,type:"boolean",value:e.value};case"ref":return{predicate:t,type:"ref",value:e.value};case"embedded":return e.name!==void 0?{predicate:t,type:"embedded",name:e.name,statements:e.statements}:{predicate:t,type:"embedded",statements:e.statements};case"list":return{predicate:t,type:"list",items:e.items}}}function Or(t){let e=t.predicate;if(e)return Qe(e.subject)}function Lr(t){let e=t.namespace??"",n=t.name??"";return`${e}/${n}`}function Xe(t){return Qe(t.subject)}function Qe(t){let e=t.version;return e&&typeof e.major=="number"?`${t.publisher}/${t.package_}@${e.major}.${e.minor}.${e.patch}/${t.name}`:`${t.publisher}/${t.package_}/${t.name}`}function et(t){if(Number.isNaN(t))throw new Error("canonicalForm: NaN cannot be canonicalized");if(!Number.isFinite(t))throw new Error("canonicalForm: \xB1Infinity cannot be canonicalized");return Object.is(t,-0)?"0":String(t)}var p="kanonak.org",m="view",tt="core-kanonak",Nr={publisher:p,package_:m,name:"rootView"},_r={publisher:p,package_:m,name:"bind"},Ar={publisher:p,package_:m,name:"produces"},Dr={publisher:p,package_:m,name:"projections"},Fr={publisher:p,package_:m,name:"where"},Mr={publisher:p,package_:m,name:"value"},Hr={publisher:p,package_:m,name:"as"},nt="__view_probe__",J=class{constructor(e,n=new Q){this.repository=e;this.parser=n;this.objectParser=new ce(this.parser)}repository;parser;objectParser;async materialize(e,n={}){let r=await this.objectParser.parseKanonaks(this.repository),o=this.resolveView(r,e),a=S(o,_r);if(!a)throw new Error(`View ${o.namespace}/${o.name} declares no view.bind; cannot materialize.`);let i=S(o,Ar);if(!i)throw new Error(`View ${o.namespace}/${o.name} is a selection view (no view.produces). In-graph materialization of selection views is not yet supported \u2014 declare a view.produces output class to reshape the result.`);let s=zr(o),l=rt(r,p,tt),u=rt(r,p,m),d=new we,q=d.ensure(p,tt,l,"ck"),it=d.ensure(p,m,u,"v"),st=d.ref(i),ct=new je(this.repository,this.parser,this.objectParser),Pe=new xe(ct,r),lt=this.readProjections(r,o),ut=Jr(o,Fr),dt=this.findInstances(r,a,await this.reason(n)),K={},pt=new Set;for(let x of dt){if(!await this.passesWhere(Pe,r,ut,x))continue;let X={type:st};for(let ve of lt){let ft=await this.evaluateValue(Pe,r,ve.value,x),$e=ot(ft,d);$e!==void 0&&(X[d.ref(ve.as)]=$e)}let Re=f(x);Re&&(X[`${it}.derivedFrom`]=d.ref(Re)),K[this.rowName(x,pt)]=X}let Ce=d.toImports(),Y=await this.hashBody(s,Ce,K),Ee=`q-${Y.slice(7,23)}`,Z={type:"EphemeralPackage",publisher:s,imports:Ce,[`${q}.contentHash`]:Y};n.resolvedAt&&(Z[`${q}.resolvedAt`]=n.resolvedAt),n.invocationId&&(Z[`${q}.id`]=n.invocationId);let mt={[Ee]:Z,...K};return{yaml:Se.dump(mt,{lineWidth:-1}),contentHash:Y,packageName:Ee,publisher:s,rowCount:Object.keys(K).length}}resolveView(e,n){let r=B(e,n);if(!r)throw new Error(`View ${n.publisher}/${n.package_}/${n.name} not found in the catalog.`);let o=S(r,Nr);if(o){let a=B(e,o);if(!a)throw new Error(`ViewPackage ${n.name} names rootView ${o.name}, which is not in the catalog.`);return a}return r}readProjections(e,n){let r=[];for(let o of de(n,Dr)){let a=o instanceof g?o:o instanceof h?B(e,o.subject):void 0;if(!a)continue;let i=ue(a,Mr),s=S(a,Hr);i&&s&&r.push({value:i,as:s})}return r}async reason(e){return new le({profile:e.reasoningProfile??"owl-rl-classification"}).reason(this.repository)}findInstances(e,n,r){let o=Gr(e),a=[],i=new Set;for(let s of r.getInstancesOfClass(n)){if(i.has(s))continue;i.add(s);let l=o.get(s);l&&a.push(l)}return a.sort((s,l)=>{let u=b(f(s)),d=b(f(l));return u<d?-1:u>d?1:0}),a}async passesWhere(e,n,r,o){for(let a of r){let i=await this.evaluateValue(e,n,a,o);if(!qr(i))return!1}return!0}async evaluateValue(e,n,r,o){let a=Ie(r,"view-projection",{catalog:n,depth:0}),i=new Map([["input",o]]);return e.evaluate(a,i)}rowName(e,n){let r=at(e.name)||"row",o=r,a=2;for(;n.has(o);)o=`${r}-${a++}`;return n.add(o),o}async hashBody(e,n,r){let o={[nt]:{type:"EphemeralPackage",publisher:e,imports:n},...r},a=this.parser.parse(Se.dump(o,{lineWidth:-1})),i=a.metadata.namespace_?.toString(),l=(await this.objectParser.parseKanonaks(new Ke(a,this.repository))).filter(u=>u instanceof y&&u.namespace===i&&u.name!==nt);for(let u of l)u.namespace="ephemeral";return G(l)}},we=class{byKey=new Map;aliases=new Set;ensure(e,n,r,o){let a=`${e}/${n}@${r}`,i=this.byKey.get(a);if(i)return i.alias;let s=this.uniqueAlias(o);return this.byKey.set(a,{publisher:e,package_:n,version:r,alias:s}),s}ref(e){if(!e.version||typeof e.version.major!="number")throw new Error(`Cannot serialize a reference to ${e.publisher}/${e.package_}/${e.name} without a version.`);return`${this.ensure(e.publisher,e.package_,j(e.version),e.package_)}.${e.name}`}toImports(){let e=new Map;for(let r of this.byKey.values()){let o=e.get(r.publisher)??[];o.push(r),e.set(r.publisher,o)}return[...e.keys()].sort().map(r=>({publisher:r,packages:e.get(r).sort((o,a)=>o.package_<a.package_?-1:1).map(o=>({package:o.package_,match:"^",version:o.version,alias:o.alias}))}))}uniqueAlias(e){let n=at(e)||"pkg",r=n,o=2;for(;this.aliases.has(r);)r=`${n}${o++}`;return this.aliases.add(r),r}};function ot(t,e){if(t!=null){if(typeof t=="string"||typeof t=="number"||typeof t=="boolean")return t;if(pe(t))return t.value;if(t instanceof h)return e.ref(t.subject);if(Array.isArray(t)){let n=t.map(r=>ot(r,e)).filter(r=>r!==void 0);return n.length>0?n:void 0}if(t instanceof g)throw new Error("Embedded projection values are not yet supported by the in-graph materializer. Project a literal or a reference, or compose the embedded shape into the produces class.");if(Yr(t))throw new Error(`Projection produced a bare URI without a version (${t.publisher}/${t.package_}/${t.name}); cannot serialize it as a reference.`)}}function zr(t){let e=f(t);if(!e)throw new Error(`Could not derive a publisher from view ${t.namespace}/${t.name}.`);return e.publisher}function rt(t,e,n){let r=Wr(t,e,n);if(!r)throw new Error(`Package ${e}/${n} is not in the catalog; it must be importable to materialize a view.`);return r}function Wr(t,e,n){let r;for(let o of t){if(!(o instanceof y))continue;let a=f(o);!a||a.publisher!==e||a.package_!==n||!a.version||(!r||I(a.version,r)>0)&&(r=a.version)}return r?j(r):void 0}function Gr(t){let e=new Map,n=new Map;for(let r of t){if(!(r instanceof y))continue;let o=f(r);if(!o||!o.version)continue;let a=b(o),i=n.get(a);(!i||I(o.version,i)>0)&&(n.set(a,o.version),e.set(a,r))}return e}function Jr(t,e){let n=ue(t,e);return n?[n]:de(t,e).filter(r=>r instanceof g)}function at(t){return t.replace(/[^A-Za-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}function qr(t){return t===!0?!0:t===!1||t===void 0||t===null?!1:typeof t=="string"?t.length>0:typeof t=="number"?t!==0:pe(t)?t.value.length>0:Array.isArray(t)?t.length>0:!!t}function Yr(t){return typeof t=="object"&&t!==null&&typeof t.publisher=="string"&&typeof t.package_=="string"&&typeof t.name=="string"}export{Nn as AmbiguousReferenceRule,oe as BooleanStatement,Hn as ClassDefinitionRule,xn as ClassHierarchyCycleRule,vt as CompositeKanonakDocumentRepository,W as CredentialStore,ee as DefinedKanonak,On as DefinitionPropertyReferenceRule,Rt as DocumentLocation,Zt as EdgeType,g as EmbeddedKanonak,vn as EmbeddedKanonakTypeRule,ie as EmbeddedStatement,Et as FileSystemKanonakDocumentRepository,rn as GitIgnoreFilter,Xt as GraphBuilder,Bt as HttpKanonakDocumentRepository,$n as ImportExistenceRule,Ct as InMemoryKanonakDocumentRepository,Un as InstancePropertyReferenceRule,Ot as Kanonak,an as KanonakDocumentPositions,ce as KanonakObjectParser,Wn as KanonakObjectValidator,Q as KanonakParser,Lt as KanonakUri,ln as KanonakUriBuilder,pn as KanonakUrlResolver,Wt as KanonakVocabulary,se as ListStatement,te as LiteralKanonak,Tt as LocalFirstRepository,qn as LookRenderer,zn as MarkdownLinkRule,At as MarkdownStatement,Vn as NamespaceImportCycleRule,Pn as NamespacePrefixRule,Yt as NodeType,re as NumberStatement,tn as OWL_RL_CLASSIFICATION_RULES,An as ObjectPropertyImportRule,Dn as ObjectPropertyValueValidationRule,bn as OntologyValidationError,hn as OntologyValidationResult,Fn as PropertyDomainRule,In as PropertyHierarchyCycleRule,on as PropertyMetadata,_n as PropertyRangeReferenceRule,jn as PropertyRangeRequiredRule,En as PropertyTypeSpecificityRule,Mn as PropertyValueTypeRule,xt as PublisherConfigResolver,It as PublisherIndex,en as RDFS_RULES,le as Reasoner,nn as ReasoningResult,h as ReferenceKanonak,ae as ReferenceStatement,Kt as RepositoryFactory,Cn as ResourceNamingRule,Dt as ResourceResolver,qt as ResourceTypeClassifier,_t as ScalarStatement,Nt as Statement,ne as StringStatement,Bn as SubClassOfReferenceRule,Tn as SubPropertyOfReferenceRule,y as SubjectKanonak,Rn as SubjectKanonakTypeRequiredRule,Qt as TripleStore,Ft as TypeResolver,Kn as UnresolvedReferenceRule,wn as ValidationCache,Sn as ValidationContext,kn as ValidationSeverity,Ua as VersionOperator,J as ViewMaterializer,Ln as XsdImportRule,jt as assertPackageIdentity,Ut as buildLocalFirstRepository,ke as canonicalForm,G as canonicalHash,Vt as collectKanonakFiles,I as compareVersions,Ye as computeIntegrity,yn as contextTypesOf,ze as createAuthenticatedFetch,$ as createDPoPProof,kt as createVersion,Jt as extractMarkdownLinks,Gn as findDerivation,gn as findInstancesByType,Gt as findMalformedReferences,cn as findMarkdownLinkAt,dn as formatKanonakAddress,j as formatVersion,Me as generateDPoPKeyPair,$t as getGlobalCachePath,V as hasValidToken,St as isCompatibleVersion,T as isExpired,wt as isMajorCompatible,Je as loadLockFile,Mt as makeUriKey,c as normalizeHost,un as parseKanonakAddress,bt as parseVersionString,sn as parseWithPositions,Pt as pickHighestDocument,mn as propertiesInScope,Jn as resolveDisplayValue,fn as resolvePropertyStep,qe as saveLockFile,He as serverSupportsDPoP,f as subjectUri,Ht as tripleKey,b as uriKey,zt as uriTriple,yt as versionOperatorFromChar,gt as versionOperatorToChar,ht as versionsEqual};
93
+ Check the 'credentialHelper' path in ~/.kanonak/config.json.`)}}async store(e,t){let n=c(e);try{await this.runHelper("store",{publisher:n,credential:t})}catch(o){throw new Error(`Credential helper '${this.helperPath}' failed to store credential for '${n}': ${Z(o)}
94
+ Verify the helper binary supports the 'store' action.`)}}async remove(e){let t=c(e);try{await this.runHelper("erase",{publisher:t})}catch(n){console.warn(` Warning: Credential helper '${this.helperPath}' failed to erase credential for '${t}': ${Z(n)}`)}}async list(){try{let e=await this.runHelper("list",void 0);return JSON.parse(e.trim())}catch(e){return console.warn(` Warning: Credential helper '${this.helperPath}' failed to list credentials: ${Z(e)}`),[]}}async runHelper(e,t){try{let{stdout:n}=await gn(this.helperPath,[e],{...t&&{input:JSON.stringify(t)},timeout:Je});return n}catch(n){throw hn(n)?new Error(`Credential helper not found at '${this.helperPath}'.
95
+ Check the 'credentialHelper' path in ~/.kanonak/config.json.`):kn(n)?new Error(`Credential helper '${this.helperPath}' timed out after ${Je/1e3}s on '${e}'.
96
+ The helper may be waiting for authentication to an external vault.`):n}}};function Z(r){return r instanceof Error?r.message:String(r)}function hn(r){return r instanceof Error&&"code"in r&&r.code==="ENOENT"}function kn(r){return r instanceof Error&&"killed"in r&&r.killed}var Re=Sn(wn(),".kanonak","config.json"),X=class{backend=null;backendReady=null;async getBackend(){if(this.backend)return this.backend;if(this.backendReady)return this.backendReady;this.backendReady=this.resolveBackend();try{return this.backend=await this.backendReady,this.backend}catch(e){throw this.backendReady=null,e}}async getToken(e){let t=Rn(e);if(t)return t;let o=await(await this.getBackend()).get(e);return!o||!_(o)?null:o.accessToken??null}async getCredential(e){return(await this.getBackend()).get(e)}async store(e,t){return(await this.getBackend()).store(e,t)}async remove(e){return(await this.getBackend()).remove(e)}async list(){return(await this.getBackend()).list()}async resolveBackend(){let e=vn();return e.credentialHelper?new j(e.credentialHelper):process.platform==="darwin"?new C:process.platform==="win32"?new x:await be()?new K:new I}};function Rn(r){let t="KANONAK_TOKEN_"+c(r).replace(/[.\-]/g,"_").toUpperCase();return process.env[t]??null}function vn(){if(!bn(Re))return{};try{return JSON.parse(Pn(Re,"utf-8"))}catch(r){let e=r instanceof Error?r.message:String(r);return console.warn(` Warning: Failed to parse ${Re}: ${e}
97
+ Using default credential backend. Fix the JSON syntax or delete the file.`),{}}}import{createHash as En,createPrivateKey as Cn,generateKeyPairSync as xn,randomUUID as Kn,sign as $n}from"crypto";function Ye(){let{publicKey:r,privateKey:e}=xn("ec",{namedCurve:"P-256"});return{publicKey:r.export({format:"jwk"}),privateKey:e.export({format:"jwk"})}}function B(r,e,t,n,o,a){let i={alg:"ES256",typ:"dpop+jwt",jwk:{kty:e.kty,crv:e.crv,x:e.x,y:e.y}},s={jti:Kn(),htm:t.toUpperCase(),htu:n,iat:Math.floor(Date.now()/1e3)};return o&&(s.ath=En("sha256").update(o).digest("base64url")),a&&(s.nonce=a),In(i,s,r)}function Ze(r){return!r||r.length===0?!1:r.some(e=>e.toUpperCase()==="ES256")}function In(r,e,t){let n=qe(JSON.stringify(r)),o=qe(JSON.stringify(e)),a=`${n}.${o}`,i=Cn({key:t,format:"jwk"}),l=$n("SHA256",Buffer.from(a),{key:i,dsaEncoding:"ieee-p1363"}).toString("base64url");return`${a}.${l}`}function qe(r){return Buffer.from(r,"utf-8").toString("base64url")}function Xe(r){let e=new Map;return async(t,n,o="GET")=>{if(!r)return fetch(t,{method:o});let a=await r.getCredential(n);if(!a?.accessToken)return fetch(t,{method:o});U(a)&&console.warn(` Warning: Access token for '${n}' is expired. Run 'kanonak login ${n}' to re-authenticate.`);let i={};if(a.dpopKeyPair){let l=e.get(n);try{let u=B(a.dpopKeyPair.privateKey,a.dpopKeyPair.publicKey,o,t,a.accessToken,l);i.Authorization=`DPoP ${a.accessToken}`,i.DPoP=u}catch(u){let d=u instanceof Error?u.message:String(u);console.error(` Error: Failed to create DPoP proof for '${n}': ${d}
98
+ The stored key pair may be corrupted. Run 'kanonak login ${n}' to re-authenticate.`),i.Authorization=`Bearer ${a.accessToken}`}}else i.Authorization=`Bearer ${a.accessToken}`;let s=await fetch(t,{method:o,headers:i});if(s.status===401&&a.dpopKeyPair){let l=s.headers.get("DPoP-Nonce");if(l){e.set(n,l);try{let u=B(a.dpopKeyPair.privateKey,a.dpopKeyPair.publicKey,o,t,a.accessToken,l);i.DPoP=u,s=await fetch(t,{method:o,headers:i})}catch{}}}return s}}import{readFileSync as jn,writeFileSync as Bn,existsSync as An}from"fs";import{createHash as Vn}from"crypto";import Qe from"js-yaml";var et="kanonak.lock",Dn=`# This file is generated by Kanonak CLI. Do not edit manually.
99
+ `;function tt(r=et){if(!An(r))return null;let e=jn(r,"utf-8"),t=Qe.load(e);return!t||typeof t!="object"||t.version!=="1"?null:{version:"1",lastUpdated:t.lastUpdated??new Date().toISOString(),packages:t.packages??{}}}function rt(r,e=et){r.lastUpdated=new Date().toISOString();let t={};for(let o of Object.keys(r.packages).sort())t[o]=r.packages[o];r.packages=t;let n=Qe.dump(r,{lineWidth:-1,sortKeys:!1,quotingType:'"'});Bn(e,Dn+n,"utf-8")}function nt(r){return`sha256:${Vn("sha256").update(r).digest("hex")}`}import*as Ce from"js-yaml";import{createHash as Tn}from"crypto";function ve(r){let e=[];for(let n of r)n instanceof f&&e.push(Nn(n));return e.sort((n,o)=>n.uri<o.uri?-1:n.uri>o.uri?1:0),JSON.stringify({subjects:e})}function Q(r){let e=ve(r);return`sha256:${Tn("sha256").update(e,"utf8").digest("hex")}`}function Nn(r){let e=Mn(r),t=Ee(r.statement);return{uri:e,statements:t}}function Ee(r){let e=[];for(let t of r){let n=On(t);n&&e.push(n)}return e.sort((t,n)=>t.predicate<n.predicate?-1:t.predicate>n.predicate?1:0),e}function On(r){let e=Fn(r);if(!e)return;let t=Un(r);if(t)return Ln(e,t)}function Un(r){if(r instanceof ce)return{type:"string",value:r.object};if(r instanceof le)return{type:"number",value:st(r.object)};if(r instanceof ue)return{type:"boolean",value:r.object};if(r instanceof de)return{type:"ref",value:at(r.object)};if(r instanceof pe){let e=r.object;return ot(e)}if(r instanceof me)return{type:"list",items:r.object.map(_n)}}function ot(r){let e=Ee(r.statement);return r.name&&r.name.length>0?{type:"embedded",name:r.name,statements:e}:{type:"embedded",statements:e}}function _n(r){if(r instanceof k)return{type:"ref",value:at(r)};if(r instanceof y)return ot(r);if(r instanceof se){let e=r.value;if(typeof e=="string")return{type:"string",value:e};if(typeof e=="number")return{type:"number",value:st(e)};if(typeof e=="boolean")return{type:"boolean",value:e}}if(r instanceof ie)return{type:"embedded",statements:Ee(r.statement)};throw new Error(`canonicalForm: list item of unrecognized kind (${r.constructor?.name??typeof r}); add canonicalization support before hashing data that contains it`)}function Ln(r,e){switch(e.type){case"string":return{predicate:r,type:"string",value:e.value};case"number":return{predicate:r,type:"number",value:e.value};case"boolean":return{predicate:r,type:"boolean",value:e.value};case"ref":return{predicate:r,type:"ref",value:e.value};case"embedded":return e.name!==void 0?{predicate:r,type:"embedded",name:e.name,statements:e.statements}:{predicate:r,type:"embedded",statements:e.statements};case"list":return{predicate:r,type:"list",items:e.items}}}function Fn(r){let e=r.predicate;if(e)return it(e.subject)}function Mn(r){let e=r.namespace??"",t=r.name??"";return`${e}/${t}`}function at(r){return it(r.subject)}function it(r){let e=r.version;return e&&typeof e.major=="number"?`${r.publisher}/${r.package_}@${e.major}.${e.minor}.${e.patch}/${r.name}`:`${r.publisher}/${r.package_}/${r.name}`}function st(r){if(Number.isNaN(r))throw new Error("canonicalForm: NaN cannot be canonicalized");if(!Number.isFinite(r))throw new Error("canonicalForm: \xB1Infinity cannot be canonicalized");return Object.is(r,-0)?"0":String(r)}var P=class{constructor(e,t=new S,n){this.repository=e;this.parser=t;this.objectParser=n??new v(this.parser)}repository;parser;objectParser;imports(){return new A}serializeValue(e,t){return ut(e,t)}async buildContentAddressed(e){let t=e.book.toImports(),n=await this.hashBody(e.publisher,t,e.body),o=xe(n),a={type:"EphemeralPackage",publisher:e.publisher,imports:t};e.contentHashProperty&&(a[e.contentHashProperty]=n),Object.assign(a,e.header??{});let i={[o]:a,...e.body},s=this.dump(i);return{yaml:s,byteCount:lt(s),contentHash:n,packageName:o,publisher:e.publisher,resourceCount:Object.keys(e.body).length}}async buildNamed(e){let t=e.book.toImports(),n={type:e.type??"Package",publisher:e.publisher,version:e.version,imports:t},o;e.contentHashProperty&&(o=await this.hashBody(e.publisher,t,e.body),n[e.contentHashProperty]=o),Object.assign(n,e.header??{});let a={[e.name]:n,...e.body},i=this.dump(a),s={yaml:i,byteCount:lt(i),packageName:e.name,publisher:e.publisher,resourceCount:Object.keys(e.body).length};return o!==void 0&&(s.contentHash=o),s}dump(e){return Ce.dump(e,{lineWidth:-1})}async hashBody(e,t,n){let o={[ct]:{type:"EphemeralPackage",publisher:e,imports:t},...n},a=this.parser.parse(Ce.dump(o,{lineWidth:-1})),i=a.metadata.namespace_?.toString(),l=(await this.objectParser.parseKanonaks(new De(a,this.repository))).filter(u=>u instanceof f&&u.namespace===i&&u.name!==ct);for(let u of l)u.namespace="ephemeral";return Q(l)}},ct="__pkgbuilder_probe__";function lt(r){return new TextEncoder().encode(r).length}function xe(r){let e="sha256:",t=r.startsWith(e)?e.length:0;return`q-${r.slice(t,t+16)}`}var A=class{byKey=new Map;aliases=new Set;ensure(e,t,n,o){let a=`${e}/${t}@${n}`,i=this.byKey.get(a);if(i)return i.alias;let s=this.uniqueAlias(o);return this.byKey.set(a,{publisher:e,package_:t,version:n,alias:s}),s}ref(e){if(!e.version||typeof e.version.major!="number")throw new Error(`Cannot serialize a reference to ${e.publisher}/${e.package_}/${e.name} without a version.`);return`${this.ensure(e.publisher,e.package_,h(e.version),e.package_)}.${e.name}`}toImports(){let e=new Map;for(let n of this.byKey.values()){let o=e.get(n.publisher)??[];o.push(n),e.set(n.publisher,o)}return[...e.keys()].sort().map(n=>({publisher:n,packages:e.get(n).sort((o,a)=>o.package_<a.package_?-1:1).map(o=>({package:o.package_,match:"^",version:o.version,alias:o.alias}))}))}uniqueAlias(e){let t=V(e)||"pkg",n=t,o=2;for(;this.aliases.has(n);)n=`${t}${o++}`;return this.aliases.add(n),n}};function ut(r,e){if(r!=null){if(typeof r=="string"||typeof r=="number"||typeof r=="boolean")return r;if(r instanceof k)return e.ref(r.subject);if(Array.isArray(r)){let t=r.map(n=>ut(n,e)).filter(n=>n!==void 0);return t.length>0?t:void 0}if(r instanceof y)throw new Error("Embedded values are not yet supported by PackageBuilder. Produce a literal or a reference, or compose the embedded shape into the output class.");if(Hn(r))throw new Error(`Value produced a bare URI without a version (${r.publisher}/${r.package_}/${r.name}); cannot serialize it as a reference.`)}}function V(r){return r.replace(/[^A-Za-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")}function Hn(r){return typeof r=="object"&&r!==null&&typeof r.publisher=="string"&&typeof r.package_=="string"&&typeof r.name=="string"}var ee=class{constructor(e){this.producers=e}producers;produced=new Map;producerFor(e,t){return this.producers.find(n=>n.canProduce(e,t))}async produceCached(e,t,n,o){let a=`${t}/${n}@${h(o)}`,i=this.produced.get(a);if(i)return i;let{document:s}=await e.produce(t,n,o);return this.produced.set(a,s),s}async getHighestCompatibleVersionAsync(e,t){let n=this.producerFor(e,t.packageName);if(!n)return null;let o={operator:t.versionOperator,version:t.version},a=await n.resolveVersion(e,t.packageName,o);return a?this.produceCached(n,e,t.packageName,a):null}async getDocumentAsync(e){let t;try{t=ye(e)}catch{return null}if(t.kind!=="package"||!t.version)return null;let n=this.producerFor(t.publisher,t.package_);return n?this.produceCached(n,t.publisher,t.package_,t.version):null}async getDocumentsByNamespaceAsync(e,t){return Array.from(this.produced.values()).filter(n=>{let o=n.metadata.namespace_;return o!=null&&o.publisher===e&&o.package_===t})}async getAllDocumentsAsync(){return Array.from(this.produced.values())}async saveDocumentAsync(e,t){throw new Error("ProducerRepository is read-only: a producer is a source, not a store.")}async deleteDocumentAsync(e){throw new Error("ProducerRepository is read-only: a producer is a source, not a store.")}async clearNamespaceAsync(e,t){throw new Error("ProducerRepository is read-only: a producer is a source, not a store.")}async getAllDocumentReferencesAsync(){return[]}async getDocumentContentAsync(e){return null}async getDocumentUriAsync(e){return null}};var Ke={async authorize(){return{allowed:!0}}},$e={async record(){}},D=class extends Error{constructor(t,n){let o=`${t.publisher}/${t.package_}${t.version?`@${t.version.major}.${t.version.minor}.${t.version.patch}`:""}`;super(`Not entitled to produce ${o}${n?`: ${n}`:""}`);this.address=t;this.reason=n;this.name="EntitlementDeniedError"}address;reason},te=class{inner;ctx;policy;meter;constructor(e,t,n=Ke,o=$e){this.inner=e,this.ctx=t,this.policy=n,this.meter=o}canProduce(e,t){return this.inner.canProduce(e,t)}async resolveVersion(e,t,n){return await this.assertAllowed({publisher:e,package_:t,version:n.version}),this.inner.resolveVersion(e,t,n)}async produce(e,t,n){let o={publisher:e,package_:t,version:n};await this.assertAllowed(o);let a=await this.inner.produce(e,t,n);return await this.meter.record(this.ctx,o,a),a}async assertAllowed(e){let t=await this.policy.authorize(this.ctx,e);if(!t.allowed)throw new D(e,t.reason)}};var p="kanonak.org",m="view",dt="core-kanonak",zn={publisher:p,package_:m,name:"rootView"},Wn={publisher:p,package_:m,name:"bind"},Gn={publisher:p,package_:m,name:"produces"},Jn={publisher:p,package_:m,name:"projections"},qn={publisher:p,package_:m,name:"where"},Yn={publisher:p,package_:m,name:"value"},Zn={publisher:p,package_:m,name:"as"},re=class{constructor(e,t=new S){this.repository=e;this.parser=t;this.objectParser=new v(this.parser),this.builder=new P(this.repository,this.parser,this.objectParser)}repository;parser;objectParser;builder;async materialize(e,t={}){let n=await this.objectParser.parseKanonaks(this.repository),o=this.resolveView(n,e),a=E(o,Wn);if(!a)throw new Error(`View ${o.namespace}/${o.name} declares no view.bind; cannot materialize.`);let i=E(o,Gn);if(!i)throw new Error(`View ${o.namespace}/${o.name} is a selection view (no view.produces). In-graph materialization of selection views is not yet supported \u2014 declare a view.produces output class to reshape the result.`);let s=Xn(o),l=pt(n,p,dt),u=pt(n,p,m),d=this.builder.imports(),ne=d.ensure(p,dt,l,"ck"),ft=d.ensure(p,m,u,"v"),yt=d.ref(i),gt=new Oe(this.repository,this.parser,this.objectParser),Ie=new Te(gt,n),ht=this.readProjections(n,o),kt=to(o,qn),bt=this.findInstances(n,a,await this.reason(t)),je={},Pt=new Set;for(let T of bt){if(!await this.passesWhere(Ie,n,kt,T))continue;let ae={type:yt};for(let Ae of ht){let wt=await this.evaluateValue(Ie,n,Ae.value,T),Ve=this.builder.serializeValue(mt(wt),d);Ve!==void 0&&(ae[d.ref(Ae.as)]=Ve)}let Be=g(T);Be&&(ae[`${ft}.derivedFrom`]=d.ref(Be)),je[this.rowName(T,Pt)]=ae}let oe={};t.resolvedAt&&(oe[`${ne}.resolvedAt`]=t.resolvedAt),t.invocationId&&(oe[`${ne}.id`]=t.invocationId);let w=await this.builder.buildContentAddressed({publisher:s,book:d,body:je,contentHashProperty:`${ne}.contentHash`,header:oe});return{yaml:w.yaml,contentHash:w.contentHash,packageName:w.packageName,publisher:w.publisher,rowCount:w.resourceCount}}resolveView(e,t){let n=O(e,t);if(!n)throw new Error(`View ${t.publisher}/${t.package_}/${t.name} not found in the catalog.`);let o=E(n,zn);if(o){let a=O(e,o);if(!a)throw new Error(`ViewPackage ${t.name} names rootView ${o.name}, which is not in the catalog.`);return a}return n}readProjections(e,t){let n=[];for(let o of he(t,Jn)){let a=o instanceof y?o:o instanceof k?O(e,o.subject):void 0;if(!a)continue;let i=ge(a,Yn),s=E(a,Zn);i&&s&&n.push({value:i,as:s})}return n}async reason(e){return new fe({profile:e.reasoningProfile??"owl-rl-classification"}).reason(this.repository)}findInstances(e,t,n){let o=eo(e),a=[],i=new Set;for(let s of n.getInstancesOfClass(t)){if(i.has(s))continue;i.add(s);let l=o.get(s);l&&a.push(l)}return a.sort((s,l)=>{let u=R(g(s)),d=R(g(l));return u<d?-1:u>d?1:0}),a}async passesWhere(e,t,n,o){for(let a of n){let i=await this.evaluateValue(e,t,a,o);if(!ro(i))return!1}return!0}async evaluateValue(e,t,n,o){let a=Ne(n,"view-projection",{catalog:t,depth:0}),i=new Map([["input",o]]);return e.evaluate(a,i)}rowName(e,t){let n=V(e.name)||"row",o=n,a=2;for(;t.has(o);)o=`${n}-${a++}`;return t.add(o),o}};function mt(r){return ke(r)?r.value:Array.isArray(r)?r.map(mt):r}function Xn(r){let e=g(r);if(!e)throw new Error(`Could not derive a publisher from view ${r.namespace}/${r.name}.`);return e.publisher}function pt(r,e,t){let n=Qn(r,e,t);if(!n)throw new Error(`Package ${e}/${t} is not in the catalog; it must be importable to materialize a view.`);return n}function Qn(r,e,t){let n;for(let o of r){if(!(o instanceof f))continue;let a=g(o);!a||a.publisher!==e||a.package_!==t||!a.version||(!n||N(a.version,n)>0)&&(n=a.version)}return n?h(n):void 0}function eo(r){let e=new Map,t=new Map;for(let n of r){if(!(n instanceof f))continue;let o=g(n);if(!o||!o.version)continue;let a=R(o),i=t.get(a);(!i||N(o.version,i)>0)&&(t.set(a,o.version),e.set(a,n))}return e}function to(r,e){let t=ge(r,e);return t?[t]:he(r,e).filter(n=>n instanceof y)}function ro(r){return r===!0?!0:r===!1||r===void 0||r===null?!1:typeof r=="string"?r.length>0:typeof r=="number"?r!==0:ke(r)?r.value.length>0:Array.isArray(r)?r.length>0:!!r}export{Mr as AmbiguousReferenceRule,ue as BooleanStatement,qr as ClassDefinitionRule,Vr as ClassHierarchyCycleRule,At as CompositeKanonakDocumentRepository,X as CredentialStore,ie as DefinedKanonak,Lr as DefinitionPropertyReferenceRule,Bt as DocumentLocation,or as EdgeType,y as EmbeddedKanonak,jr as EmbeddedKanonakTypeRule,pe as EmbeddedStatement,D as EntitlementDeniedError,te as EntitlementProducer,jt as FileSystemKanonakDocumentRepository,ur as GitIgnoreFilter,ar as GraphBuilder,Ut as HttpKanonakDocumentRepository,A as ImportBook,Br as ImportExistenceRule,It as InMemoryKanonakDocumentRepository,_r as InstancePropertyReferenceRule,Mt as Kanonak,pr as KanonakDocumentPositions,v as KanonakObjectParser,Zr as KanonakObjectValidator,S as KanonakParser,Ht as KanonakUri,yr as KanonakUriBuilder,hr as KanonakUrlResolver,Qt as KanonakVocabulary,me as ListStatement,se as LiteralKanonak,_t as LocalFirstRepository,en as LookRenderer,Yr as MarkdownLinkRule,Gt as MarkdownStatement,Ur as NamespaceImportCycleRule,xr as NamespacePrefixRule,nr as NodeType,le as NumberStatement,cr as OWL_RL_CLASSIFICATION_RULES,zr as ObjectPropertyImportRule,Wr as ObjectPropertyValueValidationRule,vr as OntologyValidationError,Sr as OntologyValidationResult,P as PackageBuilder,ee as ProducerRepository,Gr as PropertyDomainRule,Dr as PropertyHierarchyCycleRule,dr as PropertyMetadata,Hr as PropertyRangeReferenceRule,Tr as PropertyRangeRequiredRule,$r as PropertyTypeSpecificityRule,Jr as PropertyValueTypeRule,Tt as PublisherConfigResolver,Nt as PublisherIndex,sr as RDFS_RULES,fe as Reasoner,lr as ReasoningResult,k as ReferenceKanonak,de as ReferenceStatement,Dt as RepositoryFactory,Kr as ResourceNamingRule,Jt as ResourceResolver,rr as ResourceTypeClassifier,Wt as ScalarStatement,zt as Statement,ce as StringStatement,Nr as SubClassOfReferenceRule,Or as SubPropertyOfReferenceRule,f as SubjectKanonak,Ir as SubjectKanonakTypeRequiredRule,ir as TripleStore,qt as TypeResolver,Ar as UnresolvedReferenceRule,Cr as ValidationCache,Er as ValidationContext,Rr as ValidationSeverity,ni as VersionOperator,re as ViewMaterializer,Fr as XsdImportRule,Ke as allowAllPolicy,Ot as assertPackageIdentity,Ft as buildLocalFirstRepository,ve as canonicalForm,Q as canonicalHash,Lt as collectKanonakFiles,N as compareVersions,nt as computeIntegrity,xe as contentAddressedName,Pr as contextTypesOf,Xe as createAuthenticatedFetch,B as createDPoPProof,Et as createVersion,tr as extractMarkdownLinks,Xr as findDerivation,wr as findInstancesByType,er as findMalformedReferences,fr as findMarkdownLinkAt,gr as formatKanonakAddress,h as formatVersion,Ye as generateDPoPKeyPair,Vt as getGlobalCachePath,_ as hasValidToken,xt as isCompatibleVersion,U as isExpired,Kt as isMajorCompatible,tt as loadLockFile,Yt as makeUriKey,$e as noopMeter,c as normalizeHost,ye as parseKanonakAddress,Ct as parseVersionString,mr as parseWithPositions,$t as pickHighestDocument,kr as propertiesInScope,Qr as resolveDisplayValue,br as resolvePropertyStep,V as sanitizeName,rt as saveLockFile,Ze as serverSupportsDPoP,g as subjectUri,Zt as tripleKey,R as uriKey,Xt as uriTriple,St as versionOperatorFromChar,Rt as versionOperatorToChar,vt as versionsEqual};
@@ -0,0 +1,75 @@
1
+ import type { Version } from '@kanonak-protocol/types/document/models/types';
2
+ import type { IPackageProducer, ProduceResult, VersionRange } from './IPackageProducer.js';
3
+ /**
4
+ * The entitlement + metering seam for package producers. The SDK ships the
5
+ * *wrapper* and these *interfaces* with no-op defaults; the platform supplies
6
+ * the *policy* (e.g. Cedar/IAM), the *meter* (billing), and the credential /
7
+ * egress layer — none of which appear in the SDK. Composing
8
+ * {@link EntitlementProducer} around an {@link IPackageProducer} gates access
9
+ * to a produced package without changing the bare producer contract, so an
10
+ * in-process producer needs none of this.
11
+ *
12
+ * Invariant the wrapper preserves: it gates *access to* a deterministic
13
+ * artifact — it never parameterizes the artifact. The produced body stays a
14
+ * pure function of the address; the principal must not leak into the body or
15
+ * its content hash.
16
+ */
17
+ /**
18
+ * The authenticated caller, resolved by the host from the inbound request's
19
+ * credential. Opaque to the SDK — the platform resolves it to its own
20
+ * principal model. `null` is an anonymous / unauthenticated caller.
21
+ */
22
+ export type RequestPrincipal = Record<string, unknown>;
23
+ /** The request context threaded to the entitlement layer. */
24
+ export interface ProduceContext {
25
+ readonly principal: RequestPrincipal | null;
26
+ }
27
+ /** The address an entitlement decision is made about. `version` is absent at version-resolution time. */
28
+ export interface PackageAddress {
29
+ readonly publisher: string;
30
+ readonly package_: string;
31
+ readonly version?: Version;
32
+ }
33
+ /** A policy's verdict. A deny is fail-closed; `reason` is for diagnostics/audit. */
34
+ export interface EntitlementDecision {
35
+ readonly allowed: boolean;
36
+ readonly reason?: string;
37
+ }
38
+ /** Authorizes a caller for an address. The platform implements this (Cedar/IAM/…). */
39
+ export interface IEntitlementPolicy {
40
+ authorize(ctx: ProduceContext, address: PackageAddress): Promise<EntitlementDecision>;
41
+ }
42
+ /** Records a usage event for a produced package. The platform implements this (billing). */
43
+ export interface IMeter {
44
+ record(ctx: ProduceContext, address: PackageAddress, result: ProduceResult): Promise<void>;
45
+ }
46
+ /** Allow-all policy — the default when a host wires no entitlement. */
47
+ export declare const allowAllPolicy: IEntitlementPolicy;
48
+ /** No-op meter — the default when a host wires no metering. */
49
+ export declare const noopMeter: IMeter;
50
+ /** Thrown when a policy denies a caller. The origin maps this to 403 (or 404 to avoid disclosure). */
51
+ export declare class EntitlementDeniedError extends Error {
52
+ readonly address: PackageAddress;
53
+ readonly reason?: string | undefined;
54
+ constructor(address: PackageAddress, reason?: string | undefined);
55
+ }
56
+ /**
57
+ * Decorates an {@link IPackageProducer} so each `resolveVersion` / `produce`
58
+ * is authorized for the bound caller before the inner producer runs, and each
59
+ * `produce` is metered after. A denied call throws {@link EntitlementDeniedError}
60
+ * and never invokes the inner producer (fail-closed). One instance is bound to
61
+ * one request's {@link ProduceContext} — the host constructs it per request
62
+ * after resolving the caller's principal — so the principal stays out of the
63
+ * producer signature and out of the produced bytes.
64
+ */
65
+ export declare class EntitlementProducer implements IPackageProducer {
66
+ private readonly inner;
67
+ private readonly ctx;
68
+ private readonly policy;
69
+ private readonly meter;
70
+ constructor(inner: IPackageProducer, ctx: ProduceContext, policy?: IEntitlementPolicy, meter?: IMeter);
71
+ canProduce(publisher: string, package_: string): boolean;
72
+ resolveVersion(publisher: string, package_: string, range: VersionRange): Promise<Version | null>;
73
+ produce(publisher: string, package_: string, version: Version): Promise<ProduceResult>;
74
+ private assertAllowed;
75
+ }
@@ -0,0 +1,59 @@
1
+ import type { KanonakDocument } from '@kanonak-protocol/types/document/models/types';
2
+ import type { Version } from '@kanonak-protocol/types/document/models/types';
3
+ import type { VersionOperator } from '@kanonak-protocol/types/document/models/enums';
4
+ /**
5
+ * A version request a producer resolves: an operator and the version it
6
+ * qualifies (`= 1.2.0`, `^ 1.0.0`, `~ 1.1.0`, or `*` where the version is
7
+ * ignored). Deliberately minimal — decoupled from the parser's full `Import`
8
+ * — so a producer interprets only what it needs.
9
+ */
10
+ export interface VersionRange {
11
+ operator: VersionOperator;
12
+ version: Version;
13
+ }
14
+ /**
15
+ * What a producer hands back for one produced package: the parsed document,
16
+ * its canonical `.kan.yml` source text, and the source's UTF-8 byte size.
17
+ * `source` is what an HTTP origin serves verbatim (so a consumer that fetches
18
+ * raw YAML gets byte-identical content); `document` is what the resolution
19
+ * layer consumes; `byteCount` is captured here so a meter bills per-byte
20
+ * without re-serializing.
21
+ */
22
+ export interface ProduceResult {
23
+ document: KanonakDocument;
24
+ source: string;
25
+ byteCount: number;
26
+ }
27
+ /**
28
+ * A package producer generates a valid Kanonak Package on demand for a URI it
29
+ * is authoritative for, instead of serving an authored, on-disk `.kan.yml`.
30
+ * It is the seam a data adapter (market data, DynamoDB, a SQL warehouse)
31
+ * implements: the SDK resolves a package through {@link IPackageProducer}
32
+ * exactly as it would through any repository, and the producer projects its
33
+ * external store into Kanonak form.
34
+ *
35
+ * Resolution is two steps so a range never forces enumeration of every
36
+ * version: {@link resolveVersion} answers "which concrete version does this
37
+ * range mean" (consulting the backend — e.g. the latest `updated_at` ordinal
38
+ * for `*`), and {@link produce} generates only that one. A producer typically
39
+ * builds its document with `PackageBuilder`.
40
+ *
41
+ * The contract carries no auth: entitlement and metering are layered as an
42
+ * injected decorator around a producer (see the package-producer design),
43
+ * so an in-process producer needs none. The produced body MUST be a pure
44
+ * function of `(publisher, package, version)` — the requesting principal may
45
+ * gate access and may appear in the address, but must never shape the bytes,
46
+ * or content-addressing, lockfiles, and caching break.
47
+ */
48
+ export interface IPackageProducer {
49
+ /** Whether this producer is authoritative for `publisher/package`. */
50
+ canProduce(publisher: string, package_: string): boolean;
51
+ /**
52
+ * Resolve a version range to the concrete version this producer would serve
53
+ * — the latest snapshot ordinal for `*`, an exact pin verbatim, the highest
54
+ * in range for `^`/`~`. Returns `null` when nothing satisfies the range.
55
+ */
56
+ resolveVersion(publisher: string, package_: string, range: VersionRange): Promise<Version | null>;
57
+ /** Generate the package for a concrete, already-resolved version. */
58
+ produce(publisher: string, package_: string, version: Version): Promise<ProduceResult>;
59
+ }
@@ -0,0 +1,130 @@
1
+ import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
2
+ import { KanonakParser } from '../parsing/KanonakParser.js';
3
+ import { KanonakObjectParser } from '../parsing/KanonakObjectParser.js';
4
+ import type { KanonakUri } from '../resolution/KanonakUri.js';
5
+ /**
6
+ * The producer-side toolkit for constructing a valid, canonical Kanonak
7
+ * Package document from data — the surface a package producer (an in-graph
8
+ * materializer, or an external data adapter) builds on instead of hand-
9
+ * rolling YAML and re-implementing the object model.
10
+ *
11
+ * It owns the four pieces every producer needs and must get right
12
+ * identically: import/alias bookkeeping ({@link ImportBook}), value
13
+ * serialization (literals vs. `alias.name` references, fail-loud on the
14
+ * unrepresentable), content-hash identity over the canonical (parsed) body,
15
+ * and a deterministic YAML dump. `ViewMaterializer` is its first client.
16
+ *
17
+ * Two assembly modes:
18
+ * - {@link buildContentAddressed} — a versionless, content-hashed package
19
+ * whose name is derived from the hash (`q-<hex16>`). For per-invocation /
20
+ * deterministic-query output.
21
+ * - {@link buildNamed} — an ordinary named, versioned package (e.g. a data
22
+ * adapter's `quotes-aapl@<epoch>.0.0` snapshot), optionally recording a
23
+ * `contentHash` for dedup.
24
+ *
25
+ * The SDK never reads the clock or invents identity; the caller supplies any
26
+ * provenance (`resolvedAt`, `id`) via `header`, and it lives outside the
27
+ * hashed body so two identical productions share a content hash.
28
+ */
29
+ export declare class PackageBuilder {
30
+ private readonly repository;
31
+ private readonly parser;
32
+ private readonly objectParser;
33
+ /**
34
+ * @param repository resolution context for the body's import closure —
35
+ * the same role it plays for any parse; used to canonicalize the body
36
+ * when content-hashing.
37
+ * @param parser the shared Kanonak parser.
38
+ * @param objectParser optional reuse of an existing object parser.
39
+ */
40
+ constructor(repository: IKanonakDocumentRepository, parser?: KanonakParser, objectParser?: KanonakObjectParser);
41
+ /** A fresh import/alias ledger to allocate references against while building the body. */
42
+ imports(): ImportBook;
43
+ /**
44
+ * Serialize one body value: primitives pass through; a `ReferenceKanonak`
45
+ * becomes an `alias.name` string (allocating the import via `book`); a list
46
+ * recurses. An embedded object or a bare unversioned URI is unrepresentable
47
+ * here and throws rather than silently dropping or guessing.
48
+ */
49
+ serializeValue(value: unknown, book: ImportBook): unknown;
50
+ /**
51
+ * Assemble a versionless, content-addressed package. The body is hashed in
52
+ * canonical form (name-independent), the package name is derived from the
53
+ * hash, and `header` carries any out-of-body provenance.
54
+ */
55
+ buildContentAddressed(args: {
56
+ publisher: string;
57
+ book: ImportBook;
58
+ body: Record<string, unknown>;
59
+ /** Extra header fields (e.g. `ck.contentHash`, `ck.resolvedAt`, `ck.id`). */
60
+ header?: Record<string, unknown>;
61
+ /** Property key under which to record the content hash (e.g. `ck.contentHash`). */
62
+ contentHashProperty?: string;
63
+ }): Promise<BuiltPackage>;
64
+ /**
65
+ * Assemble an ordinary named, versioned package — the mode a data adapter
66
+ * uses for a stable or snapshot-versioned artifact (`quotes-aapl@<epoch>.0.0`).
67
+ * Optionally records a `contentHash` for dedup; the package's identity is
68
+ * its `name@version`, not the hash.
69
+ */
70
+ buildNamed(args: {
71
+ publisher: string;
72
+ name: string;
73
+ /** Version string, e.g. `1.0.0` or an epoch ordinal `1717000000000.0.0`. */
74
+ version: string;
75
+ book: ImportBook;
76
+ body: Record<string, unknown>;
77
+ type?: string;
78
+ header?: Record<string, unknown>;
79
+ /** Property key under which to record the content hash, if any. */
80
+ contentHashProperty?: string;
81
+ }): Promise<BuiltPackage>;
82
+ /** Deterministic YAML serialization of an assembled document. */
83
+ dump(doc: Record<string, unknown>): string;
84
+ /**
85
+ * Content hash of the body, independent of the package's own (possibly
86
+ * not-yet-assigned) name. Parses the body under a fixed probe header,
87
+ * neutralizes each body subject's namespace to a constant, and hashes the
88
+ * canonical form — so the same projected data always yields the same
89
+ * `sha256:` regardless of which package name it ends up under.
90
+ */
91
+ hashBody(publisher: string, imports: unknown[], body: Record<string, unknown>): Promise<string>;
92
+ }
93
+ /** The result of assembling a package: the `.kan.yml` text plus its identity. */
94
+ export interface BuiltPackage {
95
+ /** The package as `.kan.yml` text. */
96
+ yaml: string;
97
+ /** UTF-8 byte length of `yaml` — the on-the-wire size, for metering. */
98
+ byteCount: number;
99
+ /** `sha256:` content hash of the body, when one was computed. */
100
+ contentHash?: string;
101
+ /** The package name (content-addressed `q-<hex16>` or the caller's name). */
102
+ packageName: string;
103
+ /** Publisher the package is minted under. */
104
+ publisher: string;
105
+ /** Number of body resources produced. */
106
+ resourceCount: number;
107
+ }
108
+ /** Address-safe package name (`q-<hex16>`) derived from a `sha256:` content hash. */
109
+ export declare function contentAddressedName(contentHash: string): string;
110
+ export interface ImportEntry {
111
+ publisher: string;
112
+ package_: string;
113
+ version: string;
114
+ alias: string;
115
+ }
116
+ /**
117
+ * Allocates import aliases and emits the package's `imports` block. Aliases
118
+ * are unique within the package; the same `publisher/package@version` reuses
119
+ * its alias. Holding this while building the body lets value serialization
120
+ * mint `alias.name` references that the emitted `imports` exactly covers.
121
+ */
122
+ export declare class ImportBook {
123
+ private readonly byKey;
124
+ private readonly aliases;
125
+ ensure(publisher: string, package_: string, version: string, preferred: string): string;
126
+ ref(uri: KanonakUri): string;
127
+ toImports(): unknown[];
128
+ private uniqueAlias;
129
+ }
130
+ export declare function sanitizeName(raw: string): string;
@@ -0,0 +1,44 @@
1
+ import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
2
+ import type { KanonakDocument, Import, DocumentReference } from '@kanonak-protocol/types/document/models/types';
3
+ import type { IPackageProducer } from './IPackageProducer.js';
4
+ /**
5
+ * Composes one or more {@link IPackageProducer}s into the resolution chain as
6
+ * an ordinary read-only `IKanonakDocumentRepository` — the same shape
7
+ * `HttpKanonakDocumentRepository` realizes, so a producer drops into a
8
+ * `CompositeKanonakDocumentRepository`, `kanonak serve`, or any consumer
9
+ * without special-casing. `getHighestCompatibleVersionAsync` is
10
+ * `resolveVersion` then `produce`; writes throw (a producer is a source, not
11
+ * a store).
12
+ *
13
+ * Producers are tried in registration order; the first whose `canProduce`
14
+ * matches wins (explicit registration — a host wires its producers up front).
15
+ * Produced documents are deterministic per `(publisher, package, version)`,
16
+ * so they are cached by that key and never re-produced. The repository never
17
+ * enumerates a producer's version history (it would be unbounded for a
18
+ * snapshot feed): namespace/all-document queries return only what has already
19
+ * been produced this session.
20
+ */
21
+ export declare class ProducerRepository implements IKanonakDocumentRepository {
22
+ private readonly producers;
23
+ private readonly produced;
24
+ constructor(producers: IPackageProducer[]);
25
+ private producerFor;
26
+ private produceCached;
27
+ getHighestCompatibleVersionAsync(publisher: string, import_: Import): Promise<KanonakDocument | null>;
28
+ /**
29
+ * Produce a specific package by identifier. A producer must be told which
30
+ * snapshot to make, so the identifier must carry a version
31
+ * (`publisher/package@version`); a versionless or non-package identifier
32
+ * returns `null` — callers resolve ranges through
33
+ * {@link getHighestCompatibleVersionAsync}, not here.
34
+ */
35
+ getDocumentAsync(identifier: string): Promise<KanonakDocument | null>;
36
+ getDocumentsByNamespaceAsync(publisher: string, package_: string): Promise<KanonakDocument[]>;
37
+ getAllDocumentsAsync(): Promise<KanonakDocument[]>;
38
+ saveDocumentAsync(_document: KanonakDocument, _identifier: string): Promise<void>;
39
+ deleteDocumentAsync(_identifier: string): Promise<void>;
40
+ clearNamespaceAsync(_publisher: string, _package: string): Promise<void>;
41
+ getAllDocumentReferencesAsync(): Promise<DocumentReference[]>;
42
+ getDocumentContentAsync(_identifier: string): Promise<string | null>;
43
+ getDocumentUriAsync(_identifier: string): Promise<string | null>;
44
+ }
@@ -0,0 +1,6 @@
1
+ export { PackageBuilder, ImportBook, contentAddressedName, sanitizeName } from './PackageBuilder.js';
2
+ export type { BuiltPackage, ImportEntry } from './PackageBuilder.js';
3
+ export { ProducerRepository } from './ProducerRepository.js';
4
+ export type { IPackageProducer, ProduceResult, VersionRange } from './IPackageProducer.js';
5
+ export { EntitlementProducer, EntitlementDeniedError, allowAllPolicy, noopMeter, } from './Entitlement.js';
6
+ export type { IEntitlementPolicy, IMeter, ProduceContext, PackageAddress, EntitlementDecision, RequestPrincipal, } from './Entitlement.js';
@@ -15,6 +15,26 @@ export declare class HttpKanonakDocumentRepository implements IKanonakDocumentRe
15
15
  fetchFn?: AuthenticatedFetchFn;
16
16
  });
17
17
  getHighestCompatibleVersionAsync(publisher: string, import_: Import): Promise<KanonakDocument | null>;
18
+ /**
19
+ * Resolve against a live producer origin (`config.resolveByRedirect`): fetch
20
+ * the package source and follow the latest→pinned redirect, instead of
21
+ * downloading and filtering an index. An exact pin fetches the pinned URL;
22
+ * any range fetches the bare-name "latest" pointer (`/{package}.kan.yml`),
23
+ * which the origin 302s to the resolved pinned source. The resolved version
24
+ * is read from the returned document.
25
+ *
26
+ * A range resolves to the origin's LATEST — correct for a snapshot feed,
27
+ * where `^`/`~` are inert on the time axis; range-constrained resolution
28
+ * over redirect would need the range encoded in the request (future work).
29
+ */
30
+ private resolveByRedirect;
31
+ /**
32
+ * Fetch a URL following 301/302 redirects explicitly — so an authenticated
33
+ * `fetchFn` re-signs each hop (and plain fetch doesn't transparently swallow
34
+ * the redirect). Returns null on 404; throws on other non-OK statuses or a
35
+ * redirect loop.
36
+ */
37
+ private fetchFollowing;
18
38
  getAllDocumentsAsync(): Promise<KanonakDocument[]>;
19
39
  getDocumentAsync(identifier: string): Promise<KanonakDocument | null>;
20
40
  getDocumentsByNamespaceAsync(publisher: string, package_: string): Promise<KanonakDocument[]>;
@@ -14,6 +14,16 @@ export interface PublisherConfig {
14
14
  * through `parseKanonakAddress`, not string-matched.
15
15
  */
16
16
  render?: string[];
17
+ /**
18
+ * When true, this is a LIVE producer origin: it resolves version ranges
19
+ * server-side and 302-redirects a "latest" request to the pinned source,
20
+ * rather than publishing an enumerable `index.txt`. A consumer then resolves
21
+ * by fetching the package URL and following the redirect, instead of
22
+ * downloading and filtering the index — essential for a snapshot feed whose
23
+ * version history is unbounded. ABSENT/false means an ordinary static
24
+ * publisher (resolve via `index.txt`), which is the unchanged default.
25
+ */
26
+ resolveByRedirect?: boolean;
17
27
  }
18
28
  /**
19
29
  * The explicit, self-describing config a publisher advertises at
@@ -1,5 +1,5 @@
1
1
  import type { Import } from '@kanonak-protocol/types/document/models/types';
2
- import { PublisherConfigResolver } from './PublisherConfig.js';
2
+ import { PublisherConfigResolver, type PublisherConfig } from './PublisherConfig.js';
3
3
  import type { AuthenticatedFetchFn } from '../auth/index.js';
4
4
  export declare class PublisherIndex {
5
5
  private readonly indexCache;
@@ -24,6 +24,8 @@ export declare class PublisherIndex {
24
24
  version: string;
25
25
  }[]>;
26
26
  getPackageUrl(publisher: string, packageName: string, version: string): Promise<string>;
27
+ /** The publisher's `.well-known` config — e.g. to check `resolveByRedirect`. */
28
+ getConfig(publisher: string): Promise<PublisherConfig>;
27
29
  private getPackageVersions;
28
30
  /**
29
31
  * Resolve the publisher's index, de-duplicating concurrent fetches by
@@ -1 +1 @@
1
- import{b as e,c as r,d as n}from"../chunk-HAR3BNTB.js";import{a as o}from"../chunk-4NO7MHS7.js";import"../chunk-SC5M74NM.js";import"../chunk-TJPQETHV.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-LKBG2MK6.js";import{a as o}from"../chunk-4NO7MHS7.js";import"../chunk-SC5M74NM.js";import"../chunk-TJPQETHV.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}from"../chunk-OFSARZX6.js";import{a as g,b as h,c as i,d as j}from"../chunk-HAR3BNTB.js";import{a}from"../chunk-4NO7MHS7.js";import"../chunk-SC5M74NM.js";import"../chunk-TJPQETHV.js";import"../chunk-2ACBWC7K.js";export{d as CompositeKanonakDocumentRepository,c as DocumentLocation,b as FileSystemKanonakDocumentRepository,j as HttpKanonakDocumentRepository,a as InMemoryKanonakDocumentRepository,k as LocalFirstRepository,h as PublisherConfigResolver,i as PublisherIndex,f as RepositoryFactory,m as buildLocalFirstRepository,l 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}from"../chunk-ATH6636H.js";import{a as g,b as h,c as i,d as j}from"../chunk-LKBG2MK6.js";import{a}from"../chunk-4NO7MHS7.js";import"../chunk-SC5M74NM.js";import"../chunk-TJPQETHV.js";import"../chunk-2ACBWC7K.js";export{d as CompositeKanonakDocumentRepository,c as DocumentLocation,b as FileSystemKanonakDocumentRepository,j as HttpKanonakDocumentRepository,a as InMemoryKanonakDocumentRepository,k as LocalFirstRepository,h as PublisherConfigResolver,i as PublisherIndex,f as RepositoryFactory,m as buildLocalFirstRepository,l as collectKanonakFiles,g as defaultPublisherConfig,e as getGlobalCachePath};
@@ -1,5 +1,6 @@
1
1
  import type { Kanonak } from '../kanonaks/index.js';
2
2
  import type { LookRenderer } from '../look/index.js';
3
+ import type { IPackageProducer } from '../producer/index.js';
3
4
  import type { ServerModel } from './types.js';
4
5
  /**
5
6
  * Build the route-facing indexes for a {@link ServerModel} from an already-built
@@ -18,4 +19,5 @@ export declare function assembleServerModel(params: {
18
19
  lookRenderer: LookRenderer;
19
20
  localNamespaces: Set<string>;
20
21
  rawByNsKey: Map<string, string>;
22
+ producers?: readonly IPackageProducer[];
21
23
  }): ServerModel;
@@ -1,3 +1,3 @@
1
- import{j as O}from"../chunk-MCU5IAMS.js";import"../chunk-QHABFCRC.js";import{a as z,d as j,f as Z,g as V}from"../chunk-OFSARZX6.js";import{a as Q,b as X,c as F,d as I}from"../chunk-HAR3BNTB.js";import{a as J}from"../chunk-4NO7MHS7.js";import"../chunk-PEUTCG3B.js";import{a as te}from"../chunk-PEJALHXK.js";import"../chunk-SC5M74NM.js";import"../chunk-SHDHMKMJ.js";import{f as N}from"../chunk-G2DKKSZ4.js";import{a as K}from"../chunk-TJPQETHV.js";import{b as L}from"../chunk-BGQKZBNE.js";import"../chunk-CRKSKIAL.js";import"../chunk-IOMNZBK4.js";import{c as ee}from"../chunk-W6T7MOKY.js";import"../chunk-FUUTGGJS.js";import{c as C,g as Y}from"../chunk-2ACBWC7K.js";import{readFileSync as ce,existsSync as le,readdirSync as pe,writeFileSync as ue,mkdirSync as de}from"fs";import{join as W}from"path";function re(a){let e=a.metadata?.namespace_;return e?`${e.publisher}/${e.package_}`:void 0}async function A(a,e){let r=new Set,t=[...a];for(;t.length>0;){let n=t.shift(),u=re(n);if(!u||r.has(u))continue;r.add(u);let d=n.metadata?.imports;if(d)for(let[i,g]of Object.entries(d))for(let f of g)try{let p=await e.getHighestCompatibleVersionAsync(i,f);p&&t.push(p)}catch{}}return r}var D=class{constructor(e,r){this.inner=e;this.scope=r}inner;scope;async getAllDocumentsAsync(){return(await this.inner.getAllDocumentsAsync()).filter(r=>{let t=re(r);return t!==void 0&&this.scope.has(t)})}getDocumentAsync(e){return this.inner.getDocumentAsync(e)}getDocumentsByNamespaceAsync(e,r){return this.inner.getDocumentsByNamespaceAsync(e,r)}getHighestCompatibleVersionAsync(e,r){return this.inner.getHighestCompatibleVersionAsync(e,r)}saveDocumentAsync(e,r){return this.inner.saveDocumentAsync(e,r)}deleteDocumentAsync(e){return this.inner.deleteDocumentAsync(e)}clearNamespaceAsync(e,r){return this.inner.clearNamespaceAsync(e,r)}getAllDocumentReferencesAsync(){return this.inner.getAllDocumentReferencesAsync()}getDocumentContentAsync(e){return this.inner.getDocumentContentAsync(e)}getDocumentUriAsync(e){return this.inner.getDocumentUriAsync(e)}};var ne=[{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 M(a){let e=a?.render;if(e&&e.length>0){let r=[];for(let t of e)try{let n=L(t);n.kind==="package"?r.push({publisher:n.publisher,package_:n.package_}):n.kind==="resource"&&r.push({publisher:n.uri.publisher,package_:n.uri.package_})}catch{}if(r.length>0)return r}return ne}function B(a){return`${a.publisher}/${a.package_}`}function E(a){let{publisher:e,availablePublishers:r,catalog:t,lookRenderer:n,localNamespaces:u,rawByNsKey:d}=a,i=new Map,g=new Map,f=new Map,p=new Set;for(let o of t){if(!(o instanceof ee))continue;let m=o.namespace||"";if(!u.has(m))continue;i.set(`${m}/${o.name}`,o);let k=m.split("/")[1]??"",[v,$]=k.split("@");if(!v||!$)continue;let c=Y($);c&&(p.has(k)||(p.add(k),g.has(v)||g.set(v,[]),g.get(v).push({verStr:$,version:c})),o.name===v&&f.set(k,o))}for(let o of g.values())o.sort((m,k)=>C(k.version,m.version));return{publisher:e,availablePublishers:r,catalog:t,lookRenderer:n,localNamespaces:u,rawByNsKey:d,bySubject:i,pkgVersions:g,pkgSelfByVer:f}}async function H(a,e={}){let r=new K,t=new J(r),n=[],u=[];for(let c of V(a)){let R;try{R=ce(c,"utf-8")}catch{continue}let b;try{b=r.parse(R).metadata?.namespace_}catch{continue}if(!b?.version)continue;let x=b.version;u.push({publisher:b.publisher,package_:b.package_,verStr:`${x.major}.${x.minor}.${x.patch}`,version:x,source:R})}u.sort((c,R)=>C(R.version,c.version));for(let c of u)await t.saveDocumentAsync(r.parse(c.source),`${c.publisher}/${c.package_}@${c.verStr}`),n.push({publisher:c.publisher,package_:c.package_,verStr:c.verStr,source:c.source});let d=[...new Set(n.map(c=>c.publisher))].sort(),i=e.publisher;if(i){if(!d.includes(i))throw new Error(`Publisher "${i}" not found in workspace. Available: ${d.join(", ")||"(none)"}`)}else if(d.length===1)i=d[0];else throw d.length===0?new Error(`No Kanonak packages found under ${a}`):new Error(`Workspace has multiple publishers (${d.join(", ")}). Pass --publisher <domain> to choose which one to serve.`);let g=new Set,f=new Map;for(let c of n)c.publisher===i&&(g.add(`${c.publisher}/${c.package_}@${c.verStr}`),f.set(`${c.package_}@${c.verStr}`,c.source));let p=new z(j(),!0,r),o=e.repository??new Z(t,p,new I(e.httpCache?{getFromCache:e.httpCache.getFromCache,onFetch:e.httpCache.onFetch}:void 0)),m=M(void 0);if(!e.repository){let c=j(),R=s=>{let h=W(c,s);return le(h)?new Set(pe(h).filter(y=>y.endsWith(".kan.yml")).map(y=>y.split("@")[0])):new Set},b=(s,h)=>n.some(y=>y.publisher===s&&y.package_===h),x=new F,l=new Map;for(let s of m)if(l.has(s.publisher)||l.set(s.publisher,R(s.publisher)),!(l.get(s.publisher).has(s.package_)||b(s.publisher,s.package_)))try{let h=await x.getHighestVersion(s.publisher,s.package_);if(!h)continue;let y=await x.getPackageUrl(s.publisher,s.package_,h),P=await fetch(y);if(!P.ok)continue;let ie=await P.text(),G=W(c,s.publisher);de(G,{recursive:!0}),ue(W(G,`${s.package_}@${h}.kan.yml`),ie,"utf-8")}catch{}}let k=o;if(!e.repository){let c=(await t.getAllDocumentsAsync()).filter(b=>b.metadata.namespace_?.publisher===i),R=await A(c,o);for(let b of m)R.add(B(b));k=new D(o,R)}let v=await new N(r).parseKanonaks(k),$=new O(v);return E({publisher:i,availablePublishers:d,catalog:v,lookRenderer:$,localNamespaces:g,rawByNsKey:f})}import{existsSync as me,readFileSync as ge,writeFileSync as fe,mkdirSync as he}from"fs";import{join as oe}from"path";async function q(a,e={}){let r=new K,t=L(a),n=t.kind==="resource"?t.uri.publisher:t.publisher,u=e.cacheRoot??j(),d=(l,s,h)=>oe(u,l,`${s}@${h}.kan.yml`),i=new I({getFromCache:(l,s,h)=>{let y=d(l,s,h);return me(y)?ge(y,"utf-8"):null},onFetch:(l,s,h,y)=>{let P=oe(u,l);he(P,{recursive:!0}),fe(d(l,s,h),y,"utf-8")},...e.fetchFn?{fetchFn:e.fetchFn}:{}}),g=new F(e.fetchFn?{fetchFn:e.fetchFn}:void 0),f;if(t.kind==="resource"){let l=t.uri.version;f=[l?{package_:t.uri.package_,version:`${l.major}.${l.minor}.${l.patch}`}:{package_:t.uri.package_}]}else if(t.kind==="package"){let l=t.version;f=[l?{package_:t.package_,version:`${l.major}.${l.minor}.${l.patch}`}:{package_:t.package_}]}else f=(await g.listLatestPackages(n)).map(s=>({package_:s.packageName}));let p=async(l,s,h)=>{try{let y=h?r.buildImport(s,"=",h,l):r.buildImport(s,"*","0.0.0",l);return await i.getHighestCompatibleVersionAsync(l,y)}catch{return null}},o=[];for(let l of f){let s=await p(n,l.package_,l.version);s&&o.push(s)}if(o.length===0)throw new Error(`Could not fetch any package for address "${a}" from publisher "${n}".`);let m=await new X().getConfig(n).catch(()=>{}),k=[];for(let l of M(m)){let s=await p(l.publisher,l.package_,void 0);s&&k.push(s)}let v=await A([...o,...k],i),$=new D(i,v),c=await new N(r).parseKanonaks($),R=new O(c),b=new Set,x=new Map;for(let l of await i.getAllDocumentsAsync()){let s=l.metadata.namespace_;if(!s||s.publisher!==n)continue;let h=`${s.version.major}.${s.version.minor}.${s.version.patch}`,y=`${s.publisher}/${s.package_}@${h}`;b.add(y);let P=await i.getDocumentContentAsync(y);P!==null&&x.set(`${s.package_}@${h}`,P)}return E({publisher:n,availablePublishers:[n],catalog:c,lookRenderer:R,localNamespaces:b,rawByNsKey:x})}var w={".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"},S=(a,e,r,t)=>({status:a,headers:{"Content-Type":e,...t||{}},body:r}),_=a=>S(404,w[".html"],`<!doctype html><meta charset=utf-8><title>404</title><h1>404</h1><p>Not found: ${a}</p>`),ke=a=>({status:301,headers:{Location:a},body:""});function se(a,e,r){let t=a.pkgVersions.get(e);if(!t||t.length===0)return null;switch(r.kind){case"any":return t[0].verStr;case"major-pin":return t.find(n=>n.version.major===r.major)?.verStr??null;case"minor-pin":return t.find(n=>n.version.major===r.major&&n.version.minor===r.minor)?.verStr??null;case"exact":return t.find(n=>n.version.major===r.major&&n.version.minor===r.minor&&n.version.patch===r.patch)?.verStr??null;default:return null}}async function T(a,e,r=""){let{lookRenderer:t,publisher:n}=a;if(e==="/.well-known/kanonak.json")return S(200,w[".json"],JSON.stringify(Q(n),null,2));if(e==="/index.txt"){let o=[...a.localNamespaces].map(m=>m.split("/")[1].replace("@","/")).sort();return S(200,w[".txt"],o.join(`
1
+ import{j as E}from"../chunk-MCU5IAMS.js";import"../chunk-QHABFCRC.js";import{a as Z,d as A,f as te,g as N}from"../chunk-ATH6636H.js";import{a as ee,b as re,c as V,d as I}from"../chunk-LKBG2MK6.js";import{a as X}from"../chunk-4NO7MHS7.js";import"../chunk-PEUTCG3B.js";import{a as oe}from"../chunk-PEJALHXK.js";import"../chunk-SC5M74NM.js";import"../chunk-SHDHMKMJ.js";import{f as L}from"../chunk-G2DKKSZ4.js";import{a as D}from"../chunk-TJPQETHV.js";import{b as O}from"../chunk-BGQKZBNE.js";import"../chunk-CRKSKIAL.js";import"../chunk-IOMNZBK4.js";import{c as ne}from"../chunk-W6T7MOKY.js";import"../chunk-FUUTGGJS.js";import{c as F,e as z,f as K,g as Q}from"../chunk-2ACBWC7K.js";import{readFileSync as ue,existsSync as de,readdirSync as me,writeFileSync as ge,mkdirSync as fe}from"fs";import{join as q}from"path";function se(n){let e=n.metadata?.namespace_;return e?`${e.publisher}/${e.package_}`:void 0}async function M(n,e){let t=new Set,r=[...n];for(;r.length>0;){let o=r.shift(),a=se(o);if(!a||t.has(a))continue;t.add(a);let d=o.metadata?.imports;if(d)for(let[c,f]of Object.entries(d))for(let g of f)try{let l=await e.getHighestCompatibleVersionAsync(c,g);l&&r.push(l)}catch{}}return t}var j=class{constructor(e,t){this.inner=e;this.scope=t}inner;scope;async getAllDocumentsAsync(){return(await this.inner.getAllDocumentsAsync()).filter(t=>{let r=se(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 ie=[{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 C(n){let e=n?.render;if(e&&e.length>0){let t=[];for(let r of e)try{let o=O(r);o.kind==="package"?t.push({publisher:o.publisher,package_:o.package_}):o.kind==="resource"&&t.push({publisher:o.uri.publisher,package_:o.uri.package_})}catch{}if(t.length>0)return t}return ie}function H(n){return`${n.publisher}/${n.package_}`}function B(n){let{publisher:e,availablePublishers:t,catalog:r,lookRenderer:o,localNamespaces:a,rawByNsKey:d,producers:c}=n,f=new Map,g=new Map,l=new Map,i=new Set;for(let m of r){if(!(m instanceof ne))continue;let y=m.namespace||"";if(!a.has(y))continue;f.set(`${y}/${m.name}`,m);let v=y.split("/")[1]??"",[x,p]=v.split("@");if(!x||!p)continue;let b=Q(p);b&&(i.has(v)||(i.add(v),g.has(x)||g.set(x,[]),g.get(x).push({verStr:p,version:b})),m.name===x&&l.set(v,m))}for(let m of g.values())m.sort((y,v)=>F(v.version,y.version));return{publisher:e,availablePublishers:t,catalog:r,lookRenderer:o,localNamespaces:a,rawByNsKey:d,bySubject:f,pkgVersions:g,pkgSelfByVer:l,...c?{producers:c}:{}}}async function T(n,e={}){let t=new D,r=new X(t),o=[],a=[];for(let p of N(n)){let b;try{b=ue(p,"utf-8")}catch{continue}let S;try{S=t.parse(b).metadata?.namespace_}catch{continue}if(!S?.version)continue;let $=S.version;a.push({publisher:S.publisher,package_:S.package_,verStr:`${$.major}.${$.minor}.${$.patch}`,version:$,source:b})}a.sort((p,b)=>F(b.version,p.version));for(let p of a)await r.saveDocumentAsync(t.parse(p.source),`${p.publisher}/${p.package_}@${p.verStr}`),o.push({publisher:p.publisher,package_:p.package_,verStr:p.verStr,source:p.source});let d=[...new Set(o.map(p=>p.publisher))].sort(),c=e.publisher;if(c){if(!d.includes(c))throw new Error(`Publisher "${c}" not found in workspace. Available: ${d.join(", ")||"(none)"}`)}else if(d.length===1)c=d[0];else throw d.length===0?new Error(`No Kanonak packages found under ${n}`):new Error(`Workspace has multiple publishers (${d.join(", ")}). Pass --publisher <domain> to choose which one to serve.`);let f=new Set,g=new Map;for(let p of o)p.publisher===c&&(f.add(`${p.publisher}/${p.package_}@${p.verStr}`),g.set(`${p.package_}@${p.verStr}`,p.source));let l=new Z(A(),!0,t),i=e.repository??new te(r,l,new I(e.httpCache?{getFromCache:e.httpCache.getFromCache,onFetch:e.httpCache.onFetch}:void 0)),m=C(void 0);if(!e.repository){let p=A(),b=s=>{let h=q(p,s);return de(h)?new Set(me(h).filter(k=>k.endsWith(".kan.yml")).map(k=>k.split("@")[0])):new Set},S=(s,h)=>o.some(k=>k.publisher===s&&k.package_===h),$=new V,u=new Map;for(let s of m)if(u.has(s.publisher)||u.set(s.publisher,b(s.publisher)),!(u.get(s.publisher).has(s.package_)||S(s.publisher,s.package_)))try{let h=await $.getHighestVersion(s.publisher,s.package_);if(!h)continue;let k=await $.getPackageUrl(s.publisher,s.package_,h),_=await fetch(k);if(!_.ok)continue;let le=await _.text(),J=q(p,s.publisher);fe(J,{recursive:!0}),ge(q(J,`${s.package_}@${h}.kan.yml`),le,"utf-8")}catch{}}let y=i;if(!e.repository){let p=(await r.getAllDocumentsAsync()).filter(S=>S.metadata.namespace_?.publisher===c),b=await M(p,i);for(let S of m)b.add(H(S));y=new j(i,b)}let v=await new L(t).parseKanonaks(y),x=new E(v);return B({publisher:c,availablePublishers:d,catalog:v,lookRenderer:x,localNamespaces:f,rawByNsKey:g})}import{existsSync as he,readFileSync as ke,writeFileSync as ye,mkdirSync as ve}from"fs";import{join as ae}from"path";async function U(n,e={}){let t=new D,r=O(n),o=r.kind==="resource"?r.uri.publisher:r.publisher,a=e.cacheRoot??A(),d=(u,s,h)=>ae(a,u,`${s}@${h}.kan.yml`),c=new I({getFromCache:(u,s,h)=>{let k=d(u,s,h);return he(k)?ke(k,"utf-8"):null},onFetch:(u,s,h,k)=>{let _=ae(a,u);ve(_,{recursive:!0}),ye(d(u,s,h),k,"utf-8")},...e.fetchFn?{fetchFn:e.fetchFn}:{}}),f=new V(e.fetchFn?{fetchFn:e.fetchFn}:void 0),g;if(r.kind==="resource"){let u=r.uri.version;g=[u?{package_:r.uri.package_,version:`${u.major}.${u.minor}.${u.patch}`}:{package_:r.uri.package_}]}else if(r.kind==="package"){let u=r.version;g=[u?{package_:r.package_,version:`${u.major}.${u.minor}.${u.patch}`}:{package_:r.package_}]}else g=(await f.listLatestPackages(o)).map(s=>({package_:s.packageName}));let l=async(u,s,h)=>{try{let k=h?t.buildImport(s,"=",h,u):t.buildImport(s,"*","0.0.0",u);return await c.getHighestCompatibleVersionAsync(u,k)}catch{return null}},i=[];for(let u of g){let s=await l(o,u.package_,u.version);s&&i.push(s)}if(i.length===0)throw new Error(`Could not fetch any package for address "${n}" from publisher "${o}".`);let m=await new re().getConfig(o).catch(()=>{}),y=[];for(let u of C(m)){let s=await l(u.publisher,u.package_,void 0);s&&y.push(s)}let v=await M([...i,...y],c),x=new j(c,v),p=await new L(t).parseKanonaks(x),b=new E(p),S=new Set,$=new Map;for(let u of await c.getAllDocumentsAsync()){let s=u.metadata.namespace_;if(!s||s.publisher!==o)continue;let h=`${s.version.major}.${s.version.minor}.${s.version.patch}`,k=`${s.publisher}/${s.package_}@${h}`;S.add(k);let _=await c.getDocumentContentAsync(k);_!==null&&$.set(`${s.package_}@${h}`,_)}return B({publisher:o,availablePublishers:[o],catalog:p,lookRenderer:b,localNamespaces:S,rawByNsKey:$})}import{VersionOperator as W}from"@kanonak-protocol/types/document/models/enums";var w={".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"},R=(n,e,t,r)=>({status:n,headers:{"Content-Type":e,...r||{}},body:t}),P=n=>R(404,w[".html"],`<!doctype html><meta charset=utf-8><title>404</title><h1>404</h1><p>Not found: ${n}</p>`),be=n=>({status:301,headers:{Location:n},body:""}),Se=n=>({status:302,headers:{Location:n},body:""});function we(n){switch(n.kind){case"exact":return{operator:W.Exact,version:K(n.major,n.minor,n.patch)};case"minor-pin":return{operator:W.Compatible,version:K(n.major,n.minor,0)};case"major-pin":return{operator:W.Major,version:K(n.major,0,0)};default:return{operator:W.Any,version:K(0,0,0)}}}async function Re(n,e,t,r){if(!r)return null;let o=n.producers?.find(f=>f.canProduce(n.publisher,e));if(!o)return null;let a=await o.resolveVersion(n.publisher,e,we(t));if(!a)return null;let d=z(a);if(t.kind!=="exact")return Se(`/${e}/${d}.kan.yml`);let{source:c}=await o.produce(n.publisher,e,a);return R(200,w[".kan.yml"],c)}function ce(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(o=>o.version.major===t.major)?.verStr??null;case"minor-pin":return r.find(o=>o.version.major===t.major&&o.version.minor===t.minor)?.verStr??null;case"exact":return r.find(o=>o.version.major===t.major&&o.version.minor===t.minor&&o.version.patch===t.patch)?.verStr??null;default:return null}}async function G(n,e,t=""){let{lookRenderer:r,publisher:o}=n;if(e==="/.well-known/kanonak.json"){let i=ee(o);return n.producers&&n.producers.length>0&&(i.resolveByRedirect=!0),R(200,w[".json"],JSON.stringify(i,null,2))}if(e==="/index.txt"){let i=[...n.localNamespaces].map(m=>m.split("/")[1].replace("@","/")).sort();return R(200,w[".txt"],i.join(`
2
2
  `)+`
3
- `)}if(e==="/"||e==="/index.html"||e==="/index.css"){let o=t.publisherSubject(n);return e==="/index.css"?S(200,w[".css"],t.renderStylesheet(o)):S(200,w[".html"],t.renderDocument(o,{rootIndex:!0}))}let u=".html",d=!1,i=e;for(let o of[".kan.yml",".css",".svg",".md",".html"])if(e.endsWith(o)){u=o,d=!0,i=e.slice(0,-o.length);break}let g=!d&&/application\/yaml|text\/yaml/i.test(r),f=i.endsWith("/");f&&i!=="/"&&(i=i.slice(0,-1));let p=te.parse(i,n);if(!p)return _(e);if(p.kind==="package"){let o=se(a,p.package_,p.versionSpec);if(!o)return _(e);if(u===".kan.yml"||g){let v=a.rawByNsKey.get(`${p.package_}@${o}`);return v!==void 0?S(200,w[".kan.yml"],v):_(e)}let m=a.pkgSelfByVer.get(`${p.package_}@${o}`);if(!m)return _(e);if(u===".css")return S(200,w[".css"],t.renderStylesheet(m));if(!f)return ke(i+"/");let k=p.versionSpec.kind==="any";if(k&&!t.hasDeclaredView(m)){let v=(a.pkgVersions.get(p.package_)||[]).map($=>$.verStr);return S(200,w[".html"],t.renderPackageVersionList(p.package_,v,m))}return S(200,w[".html"],t.renderDocument(m,k?{bareOverview:!0}:void 0))}if(p.kind==="resource"){let o=se(a,p.package_,p.versionSpec);if(!o)return _(e);let m=a.bySubject.get(`${n}/${p.package_}@${o}/${p.name}`);if(!m)return _(e);switch(u){case".css":return S(200,w[".css"],t.renderStylesheet(m));case".svg":return S(200,w[".svg"],await t.renderSvg(m));case".md":{let k=t.renderRawMarkdown(m);return k===void 0?_(e):S(200,w[".md"],k)}default:return S(200,w[".html"],t.renderDocument(m))}}return _(e)}import{readFileSync as ye}from"fs";var U=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,r=new Set;if(this.options.root!==void 0){let t=new K;for(let n of V(this.options.root))try{let u=t.parse(ye(n,"utf-8")).metadata?.namespace_;if(!u?.version)continue;let d=u.version;e.add(`${u.publisher}/${u.package_}@${d.major}.${d.minor}.${d.patch}`),r.add(`${u.publisher}/${u.package_}`)}catch{}}return this.workspaceIndex={exact:e,pkgs:r},this.workspaceIndex}async modelFor(e,r,t){let n=this.getWorkspaceIndex(),u=this.options.fetchFn?{fetchFn:this.options.fetchFn}:{},d=r?t?n.exact.has(`${e}/${r}@${t}`):n.pkgs.has(`${e}/${r}`):[...n.pkgs].some(o=>o.startsWith(`${e}/`)),i,g;if(d&&this.options.root!==void 0){let o=this.options.root;i=`ws:${e}`,g=()=>H(o,{publisher:e})}else{let o=r?t?`${e}/${r}@${t}`:`${e}/${r}`:e;i=`rm:${o}`,g=()=>q(o,u)}let f=this.models.get(i);if(f)return f;let p=await g();return p.lookRenderer.setLinkMode("open-world"),this.models.set(i,p),p}async handle(e,r=""){let t=e.split("/").filter(Boolean);if(t.length===0)return{status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:ae()};let n=t[0];if(!n.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 u=t.length>=2&&(t[1]==="index.html"||t[1]==="index.css"||t[1]==="index.txt"||t[1]===".well-known"),d=!u&&t.length>=2?t[1]:void 0,i=!u&&t.length>=3&&/^\d+\.\d+\.\d+$/.test(t[2])?t[2]:void 0,g=await this.modelFor(n,d,i),f=e.endsWith("/")&&t.length>1?"/":"",p="/"+t.slice(1).join("/")+f,o=await T(g,p,r);return o.headers.Location?{...o,headers:{...o.headers,Location:`/${n}${o.headers.Location}`}}:o}};function ae(){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{D as ClosureScopedRepository,U as RequestRouter,ne as UNIVERSAL_RENDER_BASE,A as deriveImportClosure,ae as landingPage,q as loadResourceModel,H as loadServerModel,B as renderRefKey,M as resolveRenderContract,T as route};
3
+ `)}if(e==="/"||e==="/index.html"||e==="/index.css"){let i=r.publisherSubject(o);return e==="/index.css"?R(200,w[".css"],r.renderStylesheet(i)):R(200,w[".html"],r.renderDocument(i,{rootIndex:!0}))}let a=".html",d=!1,c=e;for(let i of[".kan.yml",".css",".svg",".md",".html"])if(e.endsWith(i)){a=i,d=!0,c=e.slice(0,-i.length);break}let f=!d&&/application\/yaml|text\/yaml/i.test(t),g=c.endsWith("/");g&&c!=="/"&&(c=c.slice(0,-1));let l=oe.parse(c,o);if(!l)return P(e);if(l.kind==="package"){let i=ce(n,l.package_,l.versionSpec);if(!i)return await Re(n,l.package_,l.versionSpec,a===".kan.yml"||f)??P(e);if(a===".kan.yml"||f){let v=n.rawByNsKey.get(`${l.package_}@${i}`);return v!==void 0?R(200,w[".kan.yml"],v):P(e)}let m=n.pkgSelfByVer.get(`${l.package_}@${i}`);if(!m)return P(e);if(a===".css")return R(200,w[".css"],r.renderStylesheet(m));if(!g)return be(c+"/");let y=l.versionSpec.kind==="any";if(y&&!r.hasDeclaredView(m)){let v=(n.pkgVersions.get(l.package_)||[]).map(x=>x.verStr);return R(200,w[".html"],r.renderPackageVersionList(l.package_,v,m))}return R(200,w[".html"],r.renderDocument(m,y?{bareOverview:!0}:void 0))}if(l.kind==="resource"){let i=ce(n,l.package_,l.versionSpec);if(!i)return P(e);let m=n.bySubject.get(`${o}/${l.package_}@${i}/${l.name}`);if(!m)return P(e);switch(a){case".css":return R(200,w[".css"],r.renderStylesheet(m));case".svg":return R(200,w[".svg"],await r.renderSvg(m));case".md":{let y=r.renderRawMarkdown(m);return y===void 0?P(e):R(200,w[".md"],y)}default:return R(200,w[".html"],r.renderDocument(m))}}return P(e)}import{readFileSync as xe}from"fs";var Y=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 D;for(let o of N(this.options.root))try{let a=r.parse(xe(o,"utf-8")).metadata?.namespace_;if(!a?.version)continue;let d=a.version;e.add(`${a.publisher}/${a.package_}@${d.major}.${d.minor}.${d.patch}`),t.add(`${a.publisher}/${a.package_}`)}catch{}}return this.workspaceIndex={exact:e,pkgs:t},this.workspaceIndex}async modelFor(e,t,r){let o=this.getWorkspaceIndex(),a=this.options.fetchFn?{fetchFn:this.options.fetchFn}:{},d=t?r?o.exact.has(`${e}/${t}@${r}`):o.pkgs.has(`${e}/${t}`):[...o.pkgs].some(i=>i.startsWith(`${e}/`)),c,f;if(d&&this.options.root!==void 0){let i=this.options.root;c=`ws:${e}`,f=()=>T(i,{publisher:e})}else{let i=t?r?`${e}/${t}@${r}`:`${e}/${t}`:e;c=`rm:${i}`,f=()=>U(i,a)}let g=this.models.get(c);if(g)return g;let l=await f();return l.lookRenderer.setLinkMode("open-world"),this.models.set(c,l),l}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:pe()};let o=r[0];if(!o.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"),d=!a&&r.length>=2?r[1]:void 0,c=!a&&r.length>=3&&/^\d+\.\d+\.\d+$/.test(r[2])?r[2]:void 0,f=await this.modelFor(o,d,c),g=e.endsWith("/")&&r.length>1?"/":"",l="/"+r.slice(1).join("/")+g,i=await G(f,l,t);return i.headers.Location?{...i,headers:{...i.headers,Location:`/${o}${i.headers.Location}`}}:i}};function pe(){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{j as ClosureScopedRepository,Y as RequestRouter,ie as UNIVERSAL_RENDER_BASE,M as deriveImportClosure,pe as landingPage,U as loadResourceModel,T as loadServerModel,H as renderRefKey,C as resolveRenderContract,G 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 { IPackageProducer } from '../producer/index.js';
7
8
  /** A package version present in the served workspace. */
8
9
  export interface PackageVersion {
9
10
  /** "major.minor.patch" string form. */
@@ -36,6 +37,14 @@ export interface ServerModel {
36
37
  readonly pkgVersions: Map<string, PackageVersion[]>;
37
38
  /** `pkg@ver` → the package self-resource subject. */
38
39
  readonly pkgSelfByVer: Map<string, SubjectKanonak>;
40
+ /**
41
+ * Package producers this origin hosts (optional). When a requested package
42
+ * is not preloaded but a producer claims it, `route` generates the package
43
+ * on demand: a range request 302-redirects to the resolved pinned source,
44
+ * an exact `.kan.yml` request is produced and served. Compose
45
+ * `EntitlementProducer` here for a gated origin.
46
+ */
47
+ readonly producers?: readonly IPackageProducer[];
39
48
  }
40
49
  /** A routed response. `body` is always a string (HTML/CSS/SVG/MD/YAML/JSON). */
41
50
  export interface RouteResponse {
@@ -52,6 +52,7 @@ export declare class ViewMaterializer {
52
52
  private readonly repository;
53
53
  private readonly parser;
54
54
  private readonly objectParser;
55
+ private readonly builder;
55
56
  constructor(repository: IKanonakDocumentRepository, parser?: KanonakParser);
56
57
  materialize(viewRef: EntityUri, opts?: MaterializeOptions): Promise<MaterializeResult>;
57
58
  private resolveView;
@@ -61,11 +62,4 @@ export declare class ViewMaterializer {
61
62
  private passesWhere;
62
63
  private evaluateValue;
63
64
  private rowName;
64
- /**
65
- * Content hash of the body, independent of the EphemeralPackage's own
66
- * (not-yet-assigned) name. Parses the rows under a fixed probe header,
67
- * neutralizes each body subject's namespace to a constant, and hashes —
68
- * so the same projected data always yields the same `sha256:`.
69
- */
70
- private hashBody;
71
65
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kanonak-protocol/sdk",
3
- "version": "3.71.0",
3
+ "version": "3.72.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",
@@ -122,7 +122,7 @@
122
122
  "yaml-parser"
123
123
  ],
124
124
  "dependencies": {
125
- "@kanonak-protocol/types": "^3.71.0",
125
+ "@kanonak-protocol/types": "^3.72.0",
126
126
  "ignore": "^7.0.5",
127
127
  "js-yaml": "^4.1.0",
128
128
  "yaml": "^2.7.0"
@@ -1,2 +0,0 @@
1
- import{a as f}from"./chunk-SC5M74NM.js";import{a as d}from"./chunk-TJPQETHV.js";var k="https://{publisher}/index.txt",x="https://{publisher}/{package}/{version}.kan.yml",v={version:1};function F(a){return{version:1,index:k.replaceAll("{publisher}",a),package:x.replaceAll("{publisher}",a),auth:"none"}}var h=class{cache=new Map;getConfig(n){let e=this.cache.get(n);return e||(e=this.fetchConfig(n),this.cache.set(n,e),e.catch(()=>{this.cache.get(n)===e&&this.cache.delete(n)})),e}async fetchConfig(n){let e=`https://${n}/.well-known/kanonak.json`,r;try{r=await fetch(e)}catch{return v}if(r.status===404)return v;if(!r.ok)throw new Error(`Failed to fetch publisher config: ${e} (${r.status} ${r.statusText})`);let t=await r.json();if(typeof t.version!="number")throw new Error(`Invalid publisher config at ${e}: 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),s}resolveIndexUrl(n,e){let r=e.index??k;return y(r,{publisher:n})}resolvePackageUrl(n,e,r,t){let s=t.package??x;return y(s,{publisher:n,package:e,version:r})}};function y(a,n){let e=a;for(let[t,s]of Object.entries(n))e=e.replaceAll(`{${t}}`,s);let r=e.match(/\{[a-z]+\}/);if(r)throw new Error(`Unresolved variable ${r[0]} in URL template: ${a}`);return e}import{VersionOperator as l}from"@kanonak-protocol/types/document/models/enums";var g=class a{indexCache=new Map;configResolver;fetchFn;constructor(n){this.configResolver=n?.configResolver??new h,this.fetchFn=n?.fetchFn}async resolveVersion(n,e){let r=await this.getPackageVersions(n,e.packageName);if(r.length===0)return null;let t=r.filter(s=>this.isVersionCompatible(s,e.version,e.versionOperator));return t.length===0?null:(t.sort((s,i)=>this.compareVersionStrings(i,s)),t[0])}async getHighestVersion(n,e){let r=await this.getPackageVersions(n,e);return r.length===0?null:[...r].sort((s,i)=>this.compareVersionStrings(i,s))[0]}async listLatestPackages(n){let e=await this.getIndex(n),r=[];for(let[t,s]of e){if(s.length===0)continue;let i=[...s].sort((o,c)=>this.compareVersionStrings(c,o));r.push({packageName:t,version:i[0]})}return r.sort((t,s)=>t.packageName.localeCompare(s.packageName)),r}async getPackageUrl(n,e,r){let t=await this.configResolver.getConfig(n);return this.configResolver.resolvePackageUrl(n,e,r,t)}async getPackageVersions(n,e){return(await this.getIndex(n)).get(e)??[]}getIndex(n){let e=this.indexCache.get(n);return e||(e=this.fetchIndex(n),this.indexCache.set(n,e),e.catch(()=>{this.indexCache.get(n)===e&&this.indexCache.delete(n)})),e}async fetchIndex(n){let e=await this.configResolver.getConfig(n),r=this.configResolver.resolveIndexUrl(n,e),t=this.fetchFn?await this.fetchFn(r,n):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 a.parseIndex(s)}static parseIndex(n){let e=new Map;for(let r of n.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 c=e.get(i);c?c.push(o):e.set(i,[o])}return e}isVersionCompatible(n,e,r){let t=a.parseVersion(n);if(!t)return!1;switch(r){case l.Any:return!0;case l.Exact:return t.major===e.major&&t.minor===e.minor&&t.patch===e.patch;case l.Compatible:return t.major===e.major&&t.minor===e.minor&&t.patch>=e.patch;case l.Major:return t.major!==e.major?!1:t.minor>e.minor?!0:t.minor===e.minor?t.patch>=e.patch:!1;default:return!1}}static parseVersion(n){let e=n.split(".");if(e.length<2)return null;let r=parseInt(e[0],10),t=parseInt(e[1],10),s=e.length>=3?parseInt(e[2],10):0;return isNaN(r)||isNaN(t)||isNaN(s)?null:{major:r,minor:t,patch:s}}compareVersionStrings(n,e){let r=a.parseVersion(n),t=a.parseVersion(e);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}};var P=class{parser=new d;publisherIndex;documents=new Map;contentCache=new Map;fetchFn;onFetch;getFromCache;constructor(n){this.onFetch=n?.onFetch,this.getFromCache=n?.getFromCache,this.fetchFn=n?.fetchFn,this.publisherIndex=n?.fetchFn?new g({fetchFn:n.fetchFn}):new g}async getHighestCompatibleVersionAsync(n,e){let r=await this.publisherIndex.resolveVersion(n,e);if(!r)return null;let t=`${n}/${e.packageName}@${r}`,s=this.documents.get(t);if(s)return s;if(this.getFromCache){let m=this.getFromCache(n,e.packageName,r);if(m){let p=this.parser.parse(m);return f(p,n,e.packageName,r),this.documents.set(t,p),this.contentCache.set(t,m),p}}let i=await this.publisherIndex.getPackageUrl(n,e.packageName,r),o=this.fetchFn?await this.fetchFn(i,n):await fetch(i);if(!o.ok)throw new Error(`Failed to fetch Kanonak package: ${i} (${o.status} ${o.statusText})`);let c=await o.text(),u=this.parser.parse(c);return f(u,n,e.packageName,r),this.onFetch&&this.onFetch(n,e.packageName,r,c),this.documents.set(t,u),this.contentCache.set(t,c),u}async getAllDocumentsAsync(){return Array.from(this.documents.values())}async getDocumentAsync(n){return this.documents.get(n)??null}async getDocumentsByNamespaceAsync(n,e){return Array.from(this.documents.values()).filter(r=>{let t=r.metadata.namespace_;return t&&t.publisher===n&&t.package_===e})}async saveDocumentAsync(n,e){throw new Error("HttpKanonakDocumentRepository is read-only")}async deleteDocumentAsync(n){throw new Error("HttpKanonakDocumentRepository is read-only")}async clearNamespaceAsync(n,e){throw new Error("HttpKanonakDocumentRepository is read-only")}async getAllDocumentReferencesAsync(){return[]}async getDocumentContentAsync(n){return this.contentCache.get(n)??null}async getDocumentUriAsync(n){let e=n.match(/^(.+?)\/(.+?)@(.+)$/);if(!e)return null;let[,r,t,s]=e;return this.publisherIndex.getPackageUrl(r,t,s)}};export{F as a,h as b,g as c,P as d};