@kanonak-protocol/sdk 4.0.0 → 4.2.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 +1 -1
- package/dist/canonical/index.d.ts +1 -1
- package/dist/{chunk-V3YPCUA6.js → chunk-5DXJ5B5T.js} +1 -1
- package/dist/chunk-CEFXZIHB.js +1 -0
- package/dist/{chunk-4OSNT57C.js → chunk-HJQGBT7M.js} +1 -1
- package/dist/{chunk-ZRMF5QLN.js → chunk-JE4ZJ3OB.js} +1 -1
- package/dist/{chunk-YI5GLYMB.js → chunk-JSHJ4ZDB.js} +1 -1
- package/dist/chunk-MJZSHLWI.js +2 -0
- package/dist/{chunk-6I4BYZVA.js → chunk-O27W3OKK.js} +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +26 -26
- package/dist/parsing/index.js +1 -1
- package/dist/reasoning/index.js +1 -1
- package/dist/search/index.js +1 -1
- package/dist/server/index.js +1 -1
- package/dist/transformations/index.js +1 -1
- package/dist/validation/index.js +1 -1
- package/package.json +7 -3
- package/vectors/decode.mjs +115 -0
- package/vectors/full-form-vectors.json +254 -0
- package/vectors/lexical-vectors.json +81 -0
- package/dist/chunk-VNKX52D5.js +0 -2
- package/dist/chunk-WUAKDYY6.js +0 -1
package/dist/search/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as g}from"../chunk-
|
|
1
|
+
import{a as g}from"../chunk-JE4ZJ3OB.js";import"../chunk-QHABFCRC.js";import"../chunk-4NO7MHS7.js";import"../chunk-PEUTCG3B.js";import"../chunk-PEJALHXK.js";import"../chunk-SC5M74NM.js";import"../chunk-SHDHMKMJ.js";import"../chunk-CEFXZIHB.js";import"../chunk-ZYAABYDS.js";import{d as m,h as S}from"../chunk-NC3FSY3R.js";import{a as p,f as E}from"../chunk-PBNVHBS3.js";import"../chunk-XYEY6HUC.js";import{c as v}from"../chunk-T3JR2SV6.js";import"../chunk-FUUTGGJS.js";import{c as x}from"../chunk-2ACBWC7K.js";import{homedir as P}from"os";import{join as d}from"path";import{existsSync as M,mkdirSync as D,readFileSync as j,writeFileSync as O}from"fs";import{createHash as C}from"crypto";import{pathToFileURL as B}from"url";var h="Xenova/all-MiniLM-L6-v2",w="q8",b=32;async function F(r){let{pipeline:e,env:t}=r.transformers;t.cacheDir=r.modelCacheDir??d(P(),".kanonak","models");let n=await e("feature-extraction",h,{dtype:w});return async s=>(await n(s,{pooling:"mean",normalize:!0})).tolist()}async function z(r){let e=d(r,"node_modules","@huggingface","transformers"),t=JSON.parse(j(d(e,"package.json"),"utf-8")),n=I(t);if(!n)throw new Error(`@huggingface/transformers at ${e} exposes no resolvable ESM entry.`);let s=await import(B(d(e,n)).href);return typeof s.pipeline=="function"?s:s.default}function I(r){let e=r.exports,t=n=>typeof n=="string"?n:n?.default;return typeof e=="string"?e:t(e?.node?.import)??t(e?.import)??t(e?.default)??r.module??r.main}var y=null;async function U(){return y||(y=(async()=>{let r;try{r=await import("@huggingface/transformers")}catch(e){throw new Error(`Semantic search requires the embedding runtime, which is an optional dependency.
|
|
2
2
|
Install it with:
|
|
3
3
|
npm install @huggingface/transformers
|
|
4
4
|
(underlying import error: ${e.message})`)}return F({transformers:r})})()),y}function H(r,e){let t=0;for(let n=0;n<r.length;n++)t+=r[n]*e[n];return t}function R(r,e){return e?r.version?e.version?x(r.version,e.version)>0:!0:!1:!0}function K(r,e){let t=g(r,e),n=[t.label],s=S(e);if(s.length>0){let i=E(r,s[0]),a=i?g(r,i).label:s[0].name;a&&n.push(`\u2014 a ${a}.`)}return t.summary&&n.push(t.summary),n.join(" ")}function q(r){let e=new Map;for(let t of r){if(!(t instanceof v))continue;let n=m(t);if(!n)continue;let s=p(n),i=e.get(s);(!i||R(n,m(i)))&&e.set(s,t)}return[...e.values()].sort((t,n)=>{let s=m(t)?p(m(t)):t.name,i=m(n)?p(m(n)):n.name;return s.localeCompare(i)})}var k=class{entries=[];embedder;constructor(e={}){this.embedder=e.embedder}resolveEmbedder(){return this.embedder?Promise.resolve(this.embedder):U()}get size(){return this.entries.length}async build(e,t={}){let n=q(e);if(t.include&&(n=n.filter(t.include)),n.length===0)return this.entries=[],{size:0,cached:!1};let s=n.map(o=>K(e,o)),i=t.cacheDir,a;if(i){let o=C("sha256").update(h+"|"+w+`
|
package/dist/server/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{j as E}from"../chunk-
|
|
1
|
+
import{j as E}from"../chunk-JE4ZJ3OB.js";import"../chunk-QHABFCRC.js";import{a as Z,d as A,f as te,g as N}from"../chunk-YWUKDEZA.js";import{a as ee,b as re,c as V,d as I}from"../chunk-YCV4H6H5.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{i as L}from"../chunk-CEFXZIHB.js";import{a as D}from"../chunk-ZYAABYDS.js";import{b as O}from"../chunk-NC3FSY3R.js";import"../chunk-PBNVHBS3.js";import"../chunk-XYEY6HUC.js";import{c as ne}from"../chunk-T3JR2SV6.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(),i=se(o);if(!i||t.has(i))continue;t.add(i);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 ae=[{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 ae}function H(n){return`${n.publisher}/${n.package_}`}function B(n){let{publisher:e,availablePublishers:t,catalog:r,lookRenderer:o,localNamespaces:i,rawByNsKey:d,producers:c}=n,f=new Map,g=new Map,l=new Map,a=new Set;for(let m of r){if(!(m instanceof ne))continue;let y=m.namespace||"";if(!i.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&&(a.has(v)||(a.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:i,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=[],i=[];for(let p of N(n)){let b;try{b=ue(p,"utf-8")}catch{continue}let w;try{w=t.parse(b).metadata?.namespace_}catch{continue}if(!w?.version)continue;let $=w.version;i.push({publisher:w.publisher,package_:w.package_,verStr:`${$.major}.${$.minor}.${$.patch}`,version:$,source:b})}i.sort((p,b)=>F(b.version,p.version));for(let p of i)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),a=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},w=(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_)||w(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=a;if(!e.repository){let p=(await r.getAllDocumentsAsync()).filter(w=>w.metadata.namespace_?.publisher===c),b=await M(p,a);for(let w of m)b.add(H(w));y=new j(a,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 ie}from"path";async function U(n,e={}){let t=new D,r=O(n),o=r.kind==="resource"?r.uri.publisher:r.publisher,i=e.cacheRoot??A(),d=(u,s,h)=>ie(i,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 _=ie(i,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}},a=[];for(let u of g){let s=await l(o,u.package_,u.version);s&&a.push(s)}if(a.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([...a,...y],c),x=new j(c,v),p=await new L(t).parseKanonaks(x),b=new E(p),w=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}`;w.add(k);let _=await c.getDocumentContentAsync(k);_!==null&&$.set(`${s.package_}@${h}`,_)}return B({publisher:o,availablePublishers:[o],catalog:p,lookRenderer:b,localNamespaces:w,rawByNsKey:$})}import{VersionOperator as W}from"@kanonak-protocol/types/document/models/enums";var S={".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,S[".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:""}),we=n=>({status:302,headers:{Location:n},body:""});function Se(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 i=await o.resolveVersion(n.publisher,e,Se(t));if(!i)return null;let d=z(i);if(t.kind!=="exact")return we(`/${e}/${d}.kan.yml`);let{source:c}=await o.produce(n.publisher,e,i);return R(200,S[".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 a=ee(o);return n.producers&&n.producers.length>0&&(a.resolveByRedirect=!0),R(200,S[".json"],JSON.stringify(a,null,2))}if(e==="/index.txt"){let a=[...n.localNamespaces].map(m=>m.split("/")[1].replace("@","/")).sort();return R(200,S[".txt"],a.join(`
|
|
2
2
|
`)+`
|
|
3
3
|
`)}if(e==="/"||e==="/index.html"||e==="/index.css"){let a=r.publisherSubject(o);return e==="/index.css"?R(200,S[".css"],r.renderStylesheet(a)):R(200,S[".html"],await r.renderDocument(a,{rootIndex:!0}))}let i=".html",d=!1,c=e;for(let a of[".kan.yml",".css",".svg",".md",".html"])if(e.endsWith(a)){i=a,d=!0,c=e.slice(0,-a.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 a=ce(n,l.package_,l.versionSpec);if(!a)return await Re(n,l.package_,l.versionSpec,i===".kan.yml"||f)??P(e);if(i===".kan.yml"||f){let v=n.rawByNsKey.get(`${l.package_}@${a}`);return v!==void 0?R(200,S[".kan.yml"],v):P(e)}let m=n.pkgSelfByVer.get(`${l.package_}@${a}`);if(!m)return P(e);if(i===".css")return R(200,S[".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,S[".html"],r.renderPackageVersionList(l.package_,v,m))}return R(200,S[".html"],await r.renderDocument(m,y?{bareOverview:!0}:void 0))}if(l.kind==="resource"){let a=ce(n,l.package_,l.versionSpec);if(!a)return P(e);let m=n.bySubject.get(`${o}/${l.package_}@${a}/${l.name}`);if(!m)return P(e);switch(i){case".css":return R(200,S[".css"],r.renderStylesheet(m));case".svg":return R(200,S[".svg"],await r.renderSvg(m));case".md":{let y=r.renderRawMarkdown(m);return y===void 0?P(e):R(200,S[".md"],y)}default:return R(200,S[".html"],await 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 i=r.parse(xe(o,"utf-8")).metadata?.namespace_;if(!i?.version)continue;let d=i.version;e.add(`${i.publisher}/${i.package_}@${d.major}.${d.minor}.${d.patch}`),t.add(`${i.publisher}/${i.package_}`)}catch{}}return this.workspaceIndex={exact:e,pkgs:t},this.workspaceIndex}async modelFor(e,t,r){let o=this.getWorkspaceIndex(),i=this.options.fetchFn?{fetchFn:this.options.fetchFn}:{},d=t?r?o.exact.has(`${e}/${t}@${r}`):o.pkgs.has(`${e}/${t}`):[...o.pkgs].some(a=>a.startsWith(`${e}/`)),c,f;if(d&&this.options.root!==void 0){let a=this.options.root;c=`ws:${e}`,f=()=>T(a,{publisher:e})}else{let a=t?r?`${e}/${t}@${r}`:`${e}/${t}`:e;c=`rm:${a}`,f=()=>U(a,i)}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 i=r.length>=2&&(r[1]==="index.html"||r[1]==="index.css"||r[1]==="index.txt"||r[1]===".well-known"),d=!i&&r.length>=2?r[1]:void 0,c=!i&&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,a=await G(f,l,t);return a.headers.Location?{...a,headers:{...a.headers,Location:`/${o}${a.headers.Location}`}}:a}};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,ae 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};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{b as Y,c as An,d as Sn,e as ce,f as Te,g as O,h as wn,i as X,j as q}from"../chunk-
|
|
1
|
+
import{b as Y,c as An,d as Sn,e as ce,f as Te,g as O,h as wn,i as X,j as q}from"../chunk-JE4ZJ3OB.js";import{a as se}from"../chunk-HJQGBT7M.js";import"../chunk-QHABFCRC.js";import"../chunk-4NO7MHS7.js";import"../chunk-JSHJ4ZDB.js";import"../chunk-PEJALHXK.js";import{a as kn,b as bn,c as hn,d as Dn}from"../chunk-SHDHMKMJ.js";import{i as ie}from"../chunk-CEFXZIHB.js";import{a as ae}from"../chunk-ZYAABYDS.js";import{b as L,c as A,f as S}from"../chunk-PBNVHBS3.js";import"../chunk-XYEY6HUC.js";import{b as N,c as D,d as K,g as M,h as P,i as F,j as W,l as H}from"../chunk-T3JR2SV6.js";import"../chunk-FUUTGGJS.js";import{g as oe}from"../chunk-2ACBWC7K.js";var $e="kanonak.org",Ue="document-ast",i=e=>({publisher:$e,package_:Ue,name:e}),m={Document:i("Document"),Block:i("Block"),Inline:i("Inline"),StructuredValue:i("StructuredValue"),Heading:i("Heading"),Paragraph:i("Paragraph"),RawBlock:i("RawBlock"),Text:i("Text"),StructuredMap:i("StructuredMap"),StructuredEntry:i("StructuredEntry"),StructuredList:i("StructuredList"),StringScalar:i("StringScalar"),IntegerScalar:i("IntegerScalar"),EscapeHint:i("EscapeHint"),MediaType:i("MediaType"),metadata:i("metadata"),children:i("children"),level:i("level"),inlines:i("inlines"),text:i("text"),entries:i("entries"),key:i("key"),value:i("value"),escapeHint:i("escapeHint"),items:i("items"),stringValue:i("stringValue"),integerValue:i("integerValue"),rawContent:i("rawContent"),mediaType:i("mediaType"),mimeType:i("mimeType"),ESC_RAW:i("esc-raw"),ESC_YAML_SAFE:i("esc-yaml-safe"),ESC_TOML_STRING:i("esc-toml-string"),ESC_TOML_MULTILINE:i("esc-toml-multiline"),ESC_JSON:i("esc-json"),ESC_DYNAMODB_BOOL:i("esc-dynamodb-bool"),ESC_DYNAMODB_NUMBER:i("esc-dynamodb-number"),ESC_DYNAMODB_NULL:i("esc-dynamodb-null"),TEXT_PLAIN:i("text-plain"),TEXT_MARKDOWN:i("text-markdown"),TEXT_HTML:i("text-html"),TEXT_CSS:i("text-css"),APPLICATION_JSON:i("application-json"),TEXT_YAML:i("text-yaml"),IMAGE_SVG_XML:i("image-svg-xml"),ResourceLink:i("ResourceLink"),target:i("target"),linkLabel:i("linkLabel"),PropertyList:i("PropertyList"),propertyEntries:i("propertyEntries"),PropertyEntry:i("PropertyEntry"),propertyKey:i("propertyKey"),propertyValue:i("propertyValue"),Table:i("Table"),tableColumnLabels:i("tableColumnLabels"),tableRows:i("tableRows"),TableRow:i("TableRow"),tableCells:i("tableCells")};function ue(e,n){return e.publisher===n.publisher&&e.package_===n.package_&&e.name===n.name}var j=class{backendUri="kanonak.org/transformations/markdown-with-frontmatter";render(n,t){let r=xe(n.metadata,t),o=Le(n.children),s=["---",...r,"---","",o].join(`
|
|
2
2
|
`);return t?.trailingNewline&&(s.endsWith(`
|
|
3
3
|
`)||(s+=`
|
|
4
4
|
`)),s}};function xe(e,n){if(!e)return[];let t=new Map;for(let c of e.entries)t.set(I(c.key),c);let r=new Map;if(n?.metadataRenames)for(let[c,u]of n.metadataRenames)r.set(I(c),u);let a=(n?.metadataKeys??e.entries.map(c=>c.key)).map(I),s=[];for(let c of a){let u=t.get(c);if(!u)continue;let f=r.get(c),l=I(f??c),d=me(u.value,u.escapeHint);d!==void 0&&s.push(`${l}: ${d}`)}return s}function I(e){let n=e.lastIndexOf(".");return n===-1?e:e.substring(n+1)||e}function me(e,n){switch(e.kind){case"StringScalar":return Ve(e.stringValue,n);case"IntegerScalar":return String(e.integerValue);case"StructuredList":{let t=[];for(let r of e.items){let o=me(r,n);o!==void 0&&t.push(o)}return t.join(", ")}case"StructuredMap":return;default:return}}function Ve(e,n){return!n||ue(n,m.ESC_RAW)?e:ue(n,m.ESC_YAML_SAFE)?ve(e):e}function ve(e){return e.includes(`
|
package/dist/validation/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A,B,C,D,E,F,G,H,K as I,L as J,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}from"../chunk-
|
|
1
|
+
import{A,B,C,D,E,F,G,H,K as I,L as J,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}from"../chunk-5DXJ5B5T.js";import"../chunk-SHDHMKMJ.js";import"../chunk-CEFXZIHB.js";import"../chunk-ZYAABYDS.js";import"../chunk-NC3FSY3R.js";import"../chunk-PBNVHBS3.js";import"../chunk-XYEY6HUC.js";import"../chunk-T3JR2SV6.js";import"../chunk-FUUTGGJS.js";import"../chunk-2ACBWC7K.js";export{v as AmbiguousReferenceRule,B as ClassDefinitionRule,m as ClassHierarchyCycleRule,t as DefinitionPropertyReferenceRule,I as DiamondNameClashRule,D as DisplayLensScopeRule,j as EmbeddedKanonakTypeRule,k as ImportExistenceRule,s as InstancePropertyReferenceRule,J as KanonakObjectValidator,E as LookSemanticSvgPathRule,C as MarkdownLinkRule,r as NamespaceImportCycleRule,f as NamespacePrefixRule,x as ObjectPropertyImportRule,y as ObjectPropertyValueValidationRule,c as OntologyValidationError,a as OntologyValidationResult,H as OwlOneOfRule,z as PropertyDomainRule,n as PropertyHierarchyCycleRule,w as PropertyRangeReferenceRule,o as PropertyRangeRequiredRule,h as PropertyTypeSpecificityRule,A as PropertyValueTypeRule,g as ResourceNamingRule,G as ShaclShapeRule,p as SubClassOfReferenceRule,q as SubPropertyOfReferenceRule,i as SubjectKanonakTypeRequiredRule,F as TxExpressionPathRule,l as UnresolvedReferenceRule,e as ValidationCache,d as ValidationContext,b as ValidationSeverity,u as XsdImportRule};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanonak-protocol/sdk",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.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",
|
|
@@ -89,10 +89,14 @@
|
|
|
89
89
|
"./browser": {
|
|
90
90
|
"types": "./dist/browser.d.ts",
|
|
91
91
|
"default": "./dist/browser.js"
|
|
92
|
-
}
|
|
92
|
+
},
|
|
93
|
+
"./vectors/lexical-vectors.json": "./vectors/lexical-vectors.json",
|
|
94
|
+
"./vectors/full-form-vectors.json": "./vectors/full-form-vectors.json",
|
|
95
|
+
"./vectors/decode.mjs": "./vectors/decode.mjs"
|
|
93
96
|
},
|
|
94
97
|
"files": [
|
|
95
98
|
"dist/**/*",
|
|
99
|
+
"vectors/**/*",
|
|
96
100
|
"README.md"
|
|
97
101
|
],
|
|
98
102
|
"scripts": {
|
|
@@ -122,7 +126,7 @@
|
|
|
122
126
|
"yaml-parser"
|
|
123
127
|
],
|
|
124
128
|
"dependencies": {
|
|
125
|
-
"@kanonak-protocol/types": "^4.
|
|
129
|
+
"@kanonak-protocol/types": "^4.2.0",
|
|
126
130
|
"ignore": "^7.0.5",
|
|
127
131
|
"js-yaml": "^4.1.0",
|
|
128
132
|
"yaml": "^2.7.0"
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decoder for the canonical-form full-form vectors' typed-value INPUT model
|
|
3
|
+
* (issue #55, option 1). The input is language-neutral and carries datatype
|
|
4
|
+
* explicitly, so a port tests canonicalization in isolation (no parser needed):
|
|
5
|
+
*
|
|
6
|
+
* subject := { uri, statements: [ { predicate, value } ] }
|
|
7
|
+
* value := { lit, datatype } typed scalar — raw lexical token + datatype URI
|
|
8
|
+
* | { raw } untyped/open-world scalar (no carrier, raw token)
|
|
9
|
+
* | { ref } reference to an entity (full canonical URI)
|
|
10
|
+
* | { embed: { name?, statements } } embedded node
|
|
11
|
+
* | { list: [ value ] } ordered list
|
|
12
|
+
*
|
|
13
|
+
* It builds the SDK object model the same way the parser's range-directed
|
|
14
|
+
* typing does (carrier from the datatype URI via `carrierOf`), so
|
|
15
|
+
* `canonicalForm`/`canonicalHash` over the result is the authoritative output.
|
|
16
|
+
* This file is also the reference each `kanonak-canonical` port mirrors to map
|
|
17
|
+
* the input model into its own representation.
|
|
18
|
+
*/
|
|
19
|
+
import {
|
|
20
|
+
SubjectKanonak,
|
|
21
|
+
ReferenceKanonak,
|
|
22
|
+
EmbeddedKanonak,
|
|
23
|
+
LiteralKanonak,
|
|
24
|
+
StringStatement,
|
|
25
|
+
ReferenceStatement,
|
|
26
|
+
EmbeddedStatement,
|
|
27
|
+
ListStatement,
|
|
28
|
+
carrierOf,
|
|
29
|
+
} from '@kanonak-protocol/sdk';
|
|
30
|
+
|
|
31
|
+
/** "publisher/package@ver/name" or "publisher/package/name" → { publisher, package_, name }. */
|
|
32
|
+
function entityUri(uriStr) {
|
|
33
|
+
const idx = uriStr.lastIndexOf('/');
|
|
34
|
+
const name = uriStr.slice(idx + 1);
|
|
35
|
+
const head = uriStr.slice(0, idx); // publisher/package@ver
|
|
36
|
+
const publisher = head.slice(0, head.indexOf('/'));
|
|
37
|
+
const pkg = head.slice(head.indexOf('/') + 1).split('@')[0];
|
|
38
|
+
return { publisher, package_: pkg, name };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* A scalar statement. canonicalForm reads `(carrier, lexical)` off any
|
|
43
|
+
* ScalarStatement, so a single StringStatement faithfully represents every
|
|
44
|
+
* scalar carrier — the canonical output depends on the carrier+lexical, not the
|
|
45
|
+
* statement class.
|
|
46
|
+
*/
|
|
47
|
+
function scalar(predicateUri, carrier, lexical) {
|
|
48
|
+
const s = new StringStatement();
|
|
49
|
+
s.predicate = ReferenceKanonak.parse(predicateUri);
|
|
50
|
+
s.object = lexical;
|
|
51
|
+
if (carrier) {
|
|
52
|
+
s.carrier = carrier;
|
|
53
|
+
s.lexical = lexical;
|
|
54
|
+
}
|
|
55
|
+
return s;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function buildEmbedded(e) {
|
|
59
|
+
const emb = new EmbeddedKanonak();
|
|
60
|
+
if (e.name) emb.name = e.name;
|
|
61
|
+
emb.statement = (e.statements ?? []).map((st) => buildStatement(st.predicate, st.value));
|
|
62
|
+
return emb;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function buildItem(v) {
|
|
66
|
+
if ('ref' in v) return ReferenceKanonak.parse(v.ref);
|
|
67
|
+
if ('embed' in v) return buildEmbedded(v.embed);
|
|
68
|
+
const lit = new LiteralKanonak();
|
|
69
|
+
if ('lit' in v) {
|
|
70
|
+
lit.value = v.lit;
|
|
71
|
+
lit.carrier = carrierOf(entityUri(v.datatype));
|
|
72
|
+
lit.lexical = v.lit;
|
|
73
|
+
} else if ('raw' in v) {
|
|
74
|
+
lit.value = v.raw;
|
|
75
|
+
} else {
|
|
76
|
+
throw new Error(`decode: unknown list item shape ${JSON.stringify(v)}`);
|
|
77
|
+
}
|
|
78
|
+
return lit;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function buildStatement(predicateUri, v) {
|
|
82
|
+
if ('lit' in v) return scalar(predicateUri, carrierOf(entityUri(v.datatype)), v.lit);
|
|
83
|
+
if ('raw' in v) return scalar(predicateUri, undefined, v.raw);
|
|
84
|
+
if ('ref' in v) {
|
|
85
|
+
const s = new ReferenceStatement();
|
|
86
|
+
s.predicate = ReferenceKanonak.parse(predicateUri);
|
|
87
|
+
s.object = ReferenceKanonak.parse(v.ref);
|
|
88
|
+
return s;
|
|
89
|
+
}
|
|
90
|
+
if ('embed' in v) {
|
|
91
|
+
const s = new EmbeddedStatement();
|
|
92
|
+
s.predicate = ReferenceKanonak.parse(predicateUri);
|
|
93
|
+
s.object = buildEmbedded(v.embed);
|
|
94
|
+
return s;
|
|
95
|
+
}
|
|
96
|
+
if ('list' in v) {
|
|
97
|
+
const s = new ListStatement();
|
|
98
|
+
s.predicate = ReferenceKanonak.parse(predicateUri);
|
|
99
|
+
s.object = v.list.map(buildItem);
|
|
100
|
+
return s;
|
|
101
|
+
}
|
|
102
|
+
throw new Error(`decode: unknown value shape ${JSON.stringify(v)}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Build the SubjectKanonak[] the canonical form consumes from a vector's `input`. */
|
|
106
|
+
export function decodeSubjects(input) {
|
|
107
|
+
return input.subjects.map((s) => {
|
|
108
|
+
const subj = new SubjectKanonak();
|
|
109
|
+
const idx = s.uri.lastIndexOf('/');
|
|
110
|
+
subj.namespace = s.uri.slice(0, idx);
|
|
111
|
+
subj.name = s.uri.slice(idx + 1);
|
|
112
|
+
subj.statement = (s.statements ?? []).map((st) => buildStatement(st.predicate, st.value));
|
|
113
|
+
return subj;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
{
|
|
2
|
+
"canonicalFormVersion": "1",
|
|
3
|
+
"hashAlgorithm": "sha256",
|
|
4
|
+
"description": "Golden conformance vectors for canonicalForm/canonicalHash over the typed-value input model (issue #55). input -> expectedCanonicalForm (exact UTF-8 JSON bytes) -> expectedHash. The same file drives every kanonak-canonical port. See decode.mjs for the input-model decoder. Expected values are authoritative.",
|
|
5
|
+
"vectors": [
|
|
6
|
+
{
|
|
7
|
+
"id": "typed-scalars-mixed",
|
|
8
|
+
"description": "One subject with integer/decimal/boolean/dateTime/string/anyURI properties — the typed blob in a full form; statements emitted in predicate UTF-8 byte order.",
|
|
9
|
+
"input": {
|
|
10
|
+
"subjects": [
|
|
11
|
+
{
|
|
12
|
+
"uri": "example.org/data@1.0.0/Tick",
|
|
13
|
+
"statements": [
|
|
14
|
+
{
|
|
15
|
+
"predicate": "example.org/data@1.0.0/qty",
|
|
16
|
+
"value": {
|
|
17
|
+
"lit": "0100",
|
|
18
|
+
"datatype": "kanonak.org/core-xsd/integer"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"predicate": "example.org/data@1.0.0/price",
|
|
23
|
+
"value": {
|
|
24
|
+
"lit": "1.230",
|
|
25
|
+
"datatype": "kanonak.org/core-xsd/decimal"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"predicate": "example.org/data@1.0.0/active",
|
|
30
|
+
"value": {
|
|
31
|
+
"lit": "1",
|
|
32
|
+
"datatype": "kanonak.org/core-xsd/boolean"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"predicate": "example.org/data@1.0.0/at",
|
|
37
|
+
"value": {
|
|
38
|
+
"lit": "2026-05-31T13:00:00+01:00",
|
|
39
|
+
"datatype": "kanonak.org/core-xsd/dateTime"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"predicate": "example.org/data@1.0.0/label",
|
|
44
|
+
"value": {
|
|
45
|
+
"lit": "hello",
|
|
46
|
+
"datatype": "kanonak.org/core-xsd/string"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
"expectedCanonicalForm": "{\"subjects\":[{\"uri\":\"example.org/data@1.0.0/Tick\",\"statements\":[{\"predicate\":\"example.org/data@1.0.0/active\",\"type\":\"typed\",\"carrier\":\"boolean\",\"value\":\"true\"},{\"predicate\":\"example.org/data@1.0.0/at\",\"type\":\"typed\",\"carrier\":\"dateTime\",\"value\":\"2026-05-31T12:00:00Z\"},{\"predicate\":\"example.org/data@1.0.0/label\",\"type\":\"typed\",\"carrier\":\"string\",\"value\":\"hello\"},{\"predicate\":\"example.org/data@1.0.0/price\",\"type\":\"typed\",\"carrier\":\"decimal\",\"value\":\"1.23\"},{\"predicate\":\"example.org/data@1.0.0/qty\",\"type\":\"typed\",\"carrier\":\"integer\",\"value\":\"100\"}]}]}",
|
|
54
|
+
"expectedHash": "sha256:e55ab7be11235de58360a8c8b069c8c19f21bb5fcde7c4638abd2f731ea8b704"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"id": "decimal-five",
|
|
58
|
+
"description": "A decimal-valued 5.0 — distinct identity from the integer 5 below (carrier tag differs).",
|
|
59
|
+
"input": {
|
|
60
|
+
"subjects": [
|
|
61
|
+
{
|
|
62
|
+
"uri": "example.org/data@1.0.0/N",
|
|
63
|
+
"statements": [
|
|
64
|
+
{
|
|
65
|
+
"predicate": "example.org/data@1.0.0/v",
|
|
66
|
+
"value": {
|
|
67
|
+
"lit": "5.0",
|
|
68
|
+
"datatype": "kanonak.org/core-xsd/decimal"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
"expectedCanonicalForm": "{\"subjects\":[{\"uri\":\"example.org/data@1.0.0/N\",\"statements\":[{\"predicate\":\"example.org/data@1.0.0/v\",\"type\":\"typed\",\"carrier\":\"decimal\",\"value\":\"5\"}]}]}",
|
|
76
|
+
"expectedHash": "sha256:705b20070647ddf964b713b5e68207c4c1767ba83be597ccfdf8d7e55a183c94"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"id": "integer-five",
|
|
80
|
+
"description": "An integer-valued 5 — same lexical \"5\" as decimal-five but a different carrier, so a different hash.",
|
|
81
|
+
"input": {
|
|
82
|
+
"subjects": [
|
|
83
|
+
{
|
|
84
|
+
"uri": "example.org/data@1.0.0/N",
|
|
85
|
+
"statements": [
|
|
86
|
+
{
|
|
87
|
+
"predicate": "example.org/data@1.0.0/v",
|
|
88
|
+
"value": {
|
|
89
|
+
"lit": "5",
|
|
90
|
+
"datatype": "kanonak.org/core-xsd/integer"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
"expectedCanonicalForm": "{\"subjects\":[{\"uri\":\"example.org/data@1.0.0/N\",\"statements\":[{\"predicate\":\"example.org/data@1.0.0/v\",\"type\":\"typed\",\"carrier\":\"integer\",\"value\":\"5\"}]}]}",
|
|
98
|
+
"expectedHash": "sha256:f32b37ab13e5ccb84afc2a1c6ce3fd2ee13dcf53dda0dc17fa1d4a0bc798c7e3"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"id": "long-hundred",
|
|
102
|
+
"description": "xsd:long 0100 — collapses to the integer carrier, equal identity to integer-hundred.",
|
|
103
|
+
"input": {
|
|
104
|
+
"subjects": [
|
|
105
|
+
{
|
|
106
|
+
"uri": "example.org/data@1.0.0/N",
|
|
107
|
+
"statements": [
|
|
108
|
+
{
|
|
109
|
+
"predicate": "example.org/data@1.0.0/v",
|
|
110
|
+
"value": {
|
|
111
|
+
"lit": "0100",
|
|
112
|
+
"datatype": "kanonak.org/core-xsd/long"
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
},
|
|
119
|
+
"expectedCanonicalForm": "{\"subjects\":[{\"uri\":\"example.org/data@1.0.0/N\",\"statements\":[{\"predicate\":\"example.org/data@1.0.0/v\",\"type\":\"typed\",\"carrier\":\"integer\",\"value\":\"100\"}]}]}",
|
|
120
|
+
"expectedHash": "sha256:653ec69910e2f7022208305c0ff44915f6eddf0163771a38f4af26161476caa4"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"id": "integer-hundred",
|
|
124
|
+
"description": "xsd:integer 100 — same carrier+value as long-hundred, so an identical hash.",
|
|
125
|
+
"input": {
|
|
126
|
+
"subjects": [
|
|
127
|
+
{
|
|
128
|
+
"uri": "example.org/data@1.0.0/N",
|
|
129
|
+
"statements": [
|
|
130
|
+
{
|
|
131
|
+
"predicate": "example.org/data@1.0.0/v",
|
|
132
|
+
"value": {
|
|
133
|
+
"lit": "100",
|
|
134
|
+
"datatype": "kanonak.org/core-xsd/integer"
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
"expectedCanonicalForm": "{\"subjects\":[{\"uri\":\"example.org/data@1.0.0/N\",\"statements\":[{\"predicate\":\"example.org/data@1.0.0/v\",\"type\":\"typed\",\"carrier\":\"integer\",\"value\":\"100\"}]}]}",
|
|
142
|
+
"expectedHash": "sha256:653ec69910e2f7022208305c0ff44915f6eddf0163771a38f4af26161476caa4"
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"id": "extra-untyped-raw-token",
|
|
146
|
+
"description": "An untyped/open-world scalar (no datatype): the raw token \"1.10\" is preserved verbatim, NOT decimal-collapsed to \"1.1\" — the open-world tier.",
|
|
147
|
+
"input": {
|
|
148
|
+
"subjects": [
|
|
149
|
+
{
|
|
150
|
+
"uri": "example.org/data@1.0.0/N",
|
|
151
|
+
"statements": [
|
|
152
|
+
{
|
|
153
|
+
"predicate": "example.org/data@1.0.0/x",
|
|
154
|
+
"value": {
|
|
155
|
+
"raw": "1.10"
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
},
|
|
162
|
+
"expectedCanonicalForm": "{\"subjects\":[{\"uri\":\"example.org/data@1.0.0/N\",\"statements\":[{\"predicate\":\"example.org/data@1.0.0/x\",\"type\":\"string\",\"value\":\"1.10\"}]}]}",
|
|
163
|
+
"expectedHash": "sha256:0b48e715952fb38d57d944b6bcbda77932f424b49868fce687728b3fa212e3e8"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"id": "list-order-preserved",
|
|
167
|
+
"description": "A list of references keeps source order [B, A] (lists carry semantic order).",
|
|
168
|
+
"input": {
|
|
169
|
+
"subjects": [
|
|
170
|
+
{
|
|
171
|
+
"uri": "example.org/data@1.0.0/L",
|
|
172
|
+
"statements": [
|
|
173
|
+
{
|
|
174
|
+
"predicate": "example.org/data@1.0.0/items",
|
|
175
|
+
"value": {
|
|
176
|
+
"list": [
|
|
177
|
+
{
|
|
178
|
+
"ref": "example.org/data@1.0.0/B"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"ref": "example.org/data@1.0.0/A"
|
|
182
|
+
}
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
},
|
|
190
|
+
"expectedCanonicalForm": "{\"subjects\":[{\"uri\":\"example.org/data@1.0.0/L\",\"statements\":[{\"predicate\":\"example.org/data@1.0.0/items\",\"type\":\"list\",\"items\":[{\"type\":\"ref\",\"value\":\"example.org/data@1.0.0/B\"},{\"type\":\"ref\",\"value\":\"example.org/data@1.0.0/A\"}]}]}]}",
|
|
191
|
+
"expectedHash": "sha256:ea18909364cd74f16e1537d9796964508cc3821fbe530993a9f6784bf79afc0c"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"id": "ref-and-embedded",
|
|
195
|
+
"description": "A reference property and an embedded node property.",
|
|
196
|
+
"input": {
|
|
197
|
+
"subjects": [
|
|
198
|
+
{
|
|
199
|
+
"uri": "example.org/data@1.0.0/R",
|
|
200
|
+
"statements": [
|
|
201
|
+
{
|
|
202
|
+
"predicate": "example.org/data@1.0.0/owner",
|
|
203
|
+
"value": {
|
|
204
|
+
"ref": "example.org/data@1.0.0/Alice"
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"predicate": "example.org/data@1.0.0/meta",
|
|
209
|
+
"value": {
|
|
210
|
+
"embed": {
|
|
211
|
+
"name": "m",
|
|
212
|
+
"statements": [
|
|
213
|
+
{
|
|
214
|
+
"predicate": "example.org/data@1.0.0/n",
|
|
215
|
+
"value": {
|
|
216
|
+
"lit": "7",
|
|
217
|
+
"datatype": "kanonak.org/core-xsd/integer"
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
]
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
]
|
|
225
|
+
}
|
|
226
|
+
]
|
|
227
|
+
},
|
|
228
|
+
"expectedCanonicalForm": "{\"subjects\":[{\"uri\":\"example.org/data@1.0.0/R\",\"statements\":[{\"predicate\":\"example.org/data@1.0.0/meta\",\"type\":\"embedded\",\"name\":\"m\",\"statements\":[{\"predicate\":\"example.org/data@1.0.0/n\",\"type\":\"typed\",\"carrier\":\"integer\",\"value\":\"7\"}]},{\"predicate\":\"example.org/data@1.0.0/owner\",\"type\":\"ref\",\"value\":\"example.org/data@1.0.0/Alice\"}]}]}",
|
|
229
|
+
"expectedHash": "sha256:fd4700f77a5825ba362394c328c25b3eefd795926101aa18bf0af1804432908f"
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"id": "nfc-normalization",
|
|
233
|
+
"description": "A string property whose value is authored as NFD (e + combining acute) canonicalizes to NFC.",
|
|
234
|
+
"input": {
|
|
235
|
+
"subjects": [
|
|
236
|
+
{
|
|
237
|
+
"uri": "example.org/data@1.0.0/N",
|
|
238
|
+
"statements": [
|
|
239
|
+
{
|
|
240
|
+
"predicate": "example.org/data@1.0.0/label",
|
|
241
|
+
"value": {
|
|
242
|
+
"lit": "é",
|
|
243
|
+
"datatype": "kanonak.org/core-xsd/string"
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
]
|
|
247
|
+
}
|
|
248
|
+
]
|
|
249
|
+
},
|
|
250
|
+
"expectedCanonicalForm": "{\"subjects\":[{\"uri\":\"example.org/data@1.0.0/N\",\"statements\":[{\"predicate\":\"example.org/data@1.0.0/label\",\"type\":\"typed\",\"carrier\":\"string\",\"value\":\"é\"}]}]}",
|
|
251
|
+
"expectedHash": "sha256:25b63ea3f42aa11307cbe4793caa56009be337707db7254fa64f7b6ae8b06cce"
|
|
252
|
+
}
|
|
253
|
+
]
|
|
254
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"canonicalFormVersion": "1",
|
|
3
|
+
"description": "Golden conformance vectors for per-carrier canonical lexical forms (issue #55). Language-neutral: each vector is (carrier, input raw token) -> expected canonical lexical string, OR (carrier, input) -> expectError for inputs that must fail loud. Every kanonak-canonical port asserts canonicalScalarLexical(carrier, input) === expected for these. Expected values are authoritative — they define the form.",
|
|
4
|
+
"vectors": [
|
|
5
|
+
{ "id": "integer-plain", "carrier": "integer", "input": "100", "expected": "100" },
|
|
6
|
+
{ "id": "integer-leading-zeros", "carrier": "integer", "input": "0100", "expected": "100" },
|
|
7
|
+
{ "id": "integer-explicit-plus", "carrier": "integer", "input": "+100", "expected": "100" },
|
|
8
|
+
{ "id": "integer-negative", "carrier": "integer", "input": "-42", "expected": "-42" },
|
|
9
|
+
{ "id": "integer-negative-zero", "carrier": "integer", "input": "-0", "expected": "0" },
|
|
10
|
+
{ "id": "integer-zero", "carrier": "integer", "input": "0", "expected": "0" },
|
|
11
|
+
{ "id": "integer-epoch-nanos-beyond-2^53", "carrier": "integer", "input": "1770000000000000001", "expected": "1770000000000000001" },
|
|
12
|
+
{ "id": "integer-rejects-decimal-point", "carrier": "integer", "input": "1.0", "expectError": true },
|
|
13
|
+
{ "id": "integer-rejects-exponent", "carrier": "integer", "input": "1e3", "expectError": true },
|
|
14
|
+
|
|
15
|
+
{ "id": "decimal-trailing-zero", "carrier": "decimal", "input": "1.10", "expected": "1.1" },
|
|
16
|
+
{ "id": "decimal-all-fraction-zeros", "carrier": "decimal", "input": "1.00", "expected": "1" },
|
|
17
|
+
{ "id": "decimal-leading-fraction-zero", "carrier": "decimal", "input": "0.10", "expected": "0.1" },
|
|
18
|
+
{ "id": "decimal-integer-valued", "carrier": "decimal", "input": "100", "expected": "100" },
|
|
19
|
+
{ "id": "decimal-integer-dot-zero", "carrier": "decimal", "input": "100.0", "expected": "100" },
|
|
20
|
+
{ "id": "decimal-negative-zero", "carrier": "decimal", "input": "-0.00", "expected": "0" },
|
|
21
|
+
{ "id": "decimal-bare-fraction", "carrier": "decimal", "input": ".5", "expected": "0.5" },
|
|
22
|
+
{ "id": "decimal-negative-trailing", "carrier": "decimal", "input": "-0.250", "expected": "-0.25" },
|
|
23
|
+
{ "id": "decimal-subpenny-exact", "carrier": "decimal", "input": "1.234500", "expected": "1.2345" },
|
|
24
|
+
{ "id": "decimal-tenth-exact", "carrier": "decimal", "input": "0.1", "expected": "0.1" },
|
|
25
|
+
{ "id": "decimal-rejects-exponent", "carrier": "decimal", "input": "1e3", "expectError": true },
|
|
26
|
+
|
|
27
|
+
{ "id": "double-integer-valued", "carrier": "double", "input": "1000", "expected": "1000" },
|
|
28
|
+
{ "id": "double-exponent-form", "carrier": "double", "input": "1e3", "expected": "1000" },
|
|
29
|
+
{ "id": "double-fraction", "carrier": "double", "input": "1.5", "expected": "1.5" },
|
|
30
|
+
{ "id": "double-negative-zero", "carrier": "double", "input": "-0", "expected": "0" },
|
|
31
|
+
{ "id": "double-nan", "carrier": "double", "input": "NaN", "expected": "NaN" },
|
|
32
|
+
{ "id": "double-inf", "carrier": "double", "input": "INF", "expected": "INF" },
|
|
33
|
+
{ "id": "double-neg-inf", "carrier": "double", "input": "-INF", "expected": "-INF" },
|
|
34
|
+
{ "id": "double-rejects-Infinity-spelling", "carrier": "double", "input": "Infinity", "expectError": true },
|
|
35
|
+
|
|
36
|
+
{ "id": "float-fraction", "carrier": "float", "input": "1.5", "expected": "1.5" },
|
|
37
|
+
{ "id": "float-nan", "carrier": "float", "input": "NaN", "expected": "NaN" },
|
|
38
|
+
|
|
39
|
+
{ "id": "boolean-true", "carrier": "boolean", "input": "true", "expected": "true" },
|
|
40
|
+
{ "id": "boolean-one", "carrier": "boolean", "input": "1", "expected": "true" },
|
|
41
|
+
{ "id": "boolean-false", "carrier": "boolean", "input": "false", "expected": "false" },
|
|
42
|
+
{ "id": "boolean-zero", "carrier": "boolean", "input": "0", "expected": "false" },
|
|
43
|
+
{ "id": "boolean-rejects-uppercase", "carrier": "boolean", "input": "TRUE", "expectError": true },
|
|
44
|
+
|
|
45
|
+
{ "id": "string-ascii-unchanged", "carrier": "string", "input": "hello", "expected": "hello" },
|
|
46
|
+
{ "id": "string-nfd-to-nfc", "carrier": "string", "input": "é", "expected": "é" },
|
|
47
|
+
{ "id": "string-nfc-stable", "carrier": "string", "input": "é", "expected": "é" },
|
|
48
|
+
{ "id": "string-no-whitespace-collapse", "carrier": "string", "input": "a b\t", "expected": "a b\t" },
|
|
49
|
+
|
|
50
|
+
{ "id": "anyURI-nfc", "carrier": "anyURI", "input": "https://example.org/é", "expected": "https://example.org/é" },
|
|
51
|
+
|
|
52
|
+
{ "id": "hexBinary-lowercase-to-upper", "carrier": "hexBinary", "input": "0fb7", "expected": "0FB7" },
|
|
53
|
+
{ "id": "hexBinary-already-upper", "carrier": "hexBinary", "input": "0FB7", "expected": "0FB7" },
|
|
54
|
+
{ "id": "hexBinary-empty", "carrier": "hexBinary", "input": "", "expected": "" },
|
|
55
|
+
{ "id": "hexBinary-rejects-odd-length", "carrier": "hexBinary", "input": "abc", "expectError": true },
|
|
56
|
+
|
|
57
|
+
{ "id": "base64-canonical", "carrier": "base64Binary", "input": "aGVsbG8=", "expected": "aGVsbG8=" },
|
|
58
|
+
{ "id": "base64-line-wrap-collapses", "carrier": "base64Binary", "input": "aGVs\nbG8=", "expected": "aGVsbG8=" },
|
|
59
|
+
|
|
60
|
+
{ "id": "dateTime-offset-to-utc-z", "carrier": "dateTime", "input": "2026-05-31T13:00:00+01:00", "expected": "2026-05-31T12:00:00Z" },
|
|
61
|
+
{ "id": "dateTime-z-stable", "carrier": "dateTime", "input": "2026-05-31T12:00:00Z", "expected": "2026-05-31T12:00:00Z" },
|
|
62
|
+
{ "id": "dateTime-plus-zero-to-z", "carrier": "dateTime", "input": "2026-05-31T12:00:00+00:00", "expected": "2026-05-31T12:00:00Z" },
|
|
63
|
+
{ "id": "dateTime-rolls-back-a-day", "carrier": "dateTime", "input": "2026-05-31T01:00:00+02:00", "expected": "2026-05-30T23:00:00Z" },
|
|
64
|
+
{ "id": "dateTime-rolls-year", "carrier": "dateTime", "input": "2026-12-31T23:00:00-02:00", "expected": "2027-01-01T01:00:00Z" },
|
|
65
|
+
{ "id": "dateTime-floating-no-z", "carrier": "dateTime", "input": "2026-05-31T12:00:00", "expected": "2026-05-31T12:00:00" },
|
|
66
|
+
{ "id": "dateTime-nanos-preserved", "carrier": "dateTime", "input": "2026-01-01T00:00:00.123456789Z", "expected": "2026-01-01T00:00:00.123456789Z" },
|
|
67
|
+
{ "id": "dateTime-frac-trailing-zeros-trimmed", "carrier": "dateTime", "input": "2026-01-01T00:00:00.1200Z", "expected": "2026-01-01T00:00:00.12Z" },
|
|
68
|
+
{ "id": "dateTime-frac-all-zeros-dropped", "carrier": "dateTime", "input": "2026-01-01T00:00:00.000Z", "expected": "2026-01-01T00:00:00Z" },
|
|
69
|
+
{ "id": "dateTime-frac-survives-shift", "carrier": "dateTime", "input": "2026-01-01T00:30:00.500+01:00", "expected": "2025-12-31T23:30:00.5Z" },
|
|
70
|
+
|
|
71
|
+
{ "id": "date-no-shift", "carrier": "date", "input": "2026-05-31", "expected": "2026-05-31" },
|
|
72
|
+
{ "id": "date-plus-zero-to-z", "carrier": "date", "input": "2026-05-31+00:00", "expected": "2026-05-31Z" },
|
|
73
|
+
{ "id": "date-offset-preserved-not-shifted", "carrier": "date", "input": "2026-05-31-05:00", "expected": "2026-05-31-05:00" },
|
|
74
|
+
|
|
75
|
+
{ "id": "time-no-shift", "carrier": "time", "input": "13:00:00-05:00", "expected": "13:00:00-05:00" },
|
|
76
|
+
{ "id": "time-frac-trimmed", "carrier": "time", "input": "23:30:00.500Z", "expected": "23:30:00.5Z" },
|
|
77
|
+
{ "id": "time-frac-all-zeros-dropped", "carrier": "time", "input": "00:00:00.000", "expected": "00:00:00" },
|
|
78
|
+
{ "id": "time-24-to-00", "carrier": "time", "input": "24:00:00", "expected": "00:00:00" },
|
|
79
|
+
{ "id": "time-plus-zero-to-z", "carrier": "time", "input": "12:00:00+00:00", "expected": "12:00:00Z" }
|
|
80
|
+
]
|
|
81
|
+
}
|