@kanonak-protocol/sdk 3.71.0 → 3.73.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/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-X5TYWQRA.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-C7RZIMEH.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};
@@ -165,55 +165,26 @@ export declare class LookRenderer {
165
165
  */
166
166
  private evaluateTier;
167
167
  /**
168
- * Apply {{...}} placeholders to a slot SVG template.
168
+ * Evaluate a band path carrier — a `tx.Expression` (e.g. `metricPath`,
169
+ * `statPath`, `labelPath`) — against `node`, which is bound to the
170
+ * `input` variable. Returns the scalar text result, or undefined when
171
+ * the carrier is absent or evaluates to nothing. This is the structured,
172
+ * object-model-resolved replacement for the old `/`-separated path DSL:
173
+ * every property reference inside the expression resolves through the
174
+ * import closure and validates at `kanonak validate` time.
169
175
  *
170
- * Specials (label, firstLetter, uri) substitute from the pre-computed
171
- * `specials` map. Anything else is a property path expression: one or
172
- * more `/`-separated steps; each step reads a property by local name
173
- * (alias prefix is ignored `wv.confidence` and `confidence` are
174
- * equivalent). Mid-path values that are references or embeddeds are
175
- * followed; the final value is rendered as text (strings/numbers
176
- * verbatim, references as the target's rdfs.label).
177
- *
178
- * Examples `{{wv.confidence/est.estimateMean}}` reads the embedded
179
- * value then its number; `{{wv.status/rdfs.label}}` resolves the
180
- * reference and reads its label.
181
- */
182
- private applyPlaceholders;
183
- /**
184
- * Whether a placeholder expression resolves to a non-empty value — the
185
- * condition for an optional `{{#expr}}…{{/expr}}` section. Uses the same
186
- * resolution as inline substitution (specials, delta/svg functions, property
187
- * paths), so a section guards exactly what its inner `{{expr}}` would print.
188
- */
189
- private placeholderResolves;
190
- /**
191
- * The change in a `/`-path metric vs the previous version of THIS
192
- * resource (highest version below the current). Undefined when there is
193
- * no prior version or the metric doesn't resolve on both.
194
- */
195
- private metricDelta;
196
- /**
197
- * Resolve a `/`-separated property path starting from `instance`. Each
198
- * step matches a statement by predicate local name (alias prefix in
199
- * the step is ignored for readability — `wv.confidence` and
200
- * `confidence` both match). Returns the final value as a string, or
201
- * undefined when the path doesn't resolve.
202
- */
203
- private resolvePath;
204
- /**
205
- * Walk a `/`-separated property path from `current`. At a reference step
206
- * the target may carry the remaining property via an open-world
207
- * augmentation merged onto a *specific* parsed version, so we try every
208
- * version of the referenced resource and return the first that yields a
209
- * value — same multi-version tolerance the look/SVG cascades use. Picking
210
- * a single version (findResourceByUri) can land on an un-augmented copy.
211
- */
212
- private resolvePathSteps;
213
- /** All text values of a final-step statement: a reference → its display
214
- * label; a literal → its value; a list → each member's text; an embedded →
215
- * none (not text). Version-tolerant on reference labels. */
216
- private finalStatementTexts;
176
+ * `fragment` is read off the band/spec/channel subject with
177
+ * `readEmbeddedCarrier`. A single field is a `tx.PropertyRead`; a
178
+ * reference step composes `tx.Traverse` with a nested `tx.PropertyRead`.
179
+ * Multi-valued properties join with ", " (matching the old DSL).
180
+ */
181
+ private evaluateCarrier;
182
+ /** Numeric form of `evaluateCarrier` NaN when absent or non-numeric. */
183
+ private evaluateCarrierNum;
184
+ /** Read a band path carrier (an embedded `tx.Expression`) off a subject
185
+ * by its property URI, or undefined when the property is absent or not
186
+ * an embedded value. */
187
+ private readEmbeddedCarrier;
217
188
  /** A reference's display label, tolerant of open-world augmentations landing
218
189
  * on a specific parsed version (tries every version, falls back to the URI
219
190
  * name). */
@@ -238,7 +209,7 @@ export declare class LookRenderer {
238
209
  /**
239
210
  * Render the instance as body-only HTML using its cascaded look.
240
211
  */
241
- renderHtml(instance: SubjectKanonak): string;
212
+ renderHtml(instance: SubjectKanonak): Promise<string>;
242
213
  /**
243
214
  * Wrap a band's HTML in a float container when it declares `look.placement`
244
215
  * (floatLeft / floatRight) so the FOLLOWING band's prose flows around it —
@@ -294,7 +265,7 @@ export declare class LookRenderer {
294
265
  renderDocument(instance: SubjectKanonak, opts?: {
295
266
  bareOverview?: boolean;
296
267
  rootIndex?: boolean;
297
- }): string;
268
+ }): Promise<string>;
298
269
  /**
299
270
  * True if the instance's class chain declares a `derivation.derivations`
300
271
  * binding whose `derivation.format` is `kanonak.org/formats/svg`. Used by
@@ -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
+ }