@kanonak-protocol/sdk 4.13.0 → 4.15.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.d.ts +1 -1
- package/dist/browser.js +2 -2
- package/dist/chunk-6U26UASC.js +1 -0
- package/dist/chunk-7BHDZHJY.js +1 -0
- package/dist/{chunk-VWS25JH4.js → chunk-EZSHR3CB.js} +1 -1
- package/dist/chunk-GZPLWII7.js +1 -0
- package/dist/{chunk-V72IVYR4.js → chunk-IHB7UVEH.js} +4 -4
- package/dist/chunk-MX3DEXMV.js +1 -0
- package/dist/{chunk-RGOBWOBB.js → chunk-S6VSAKXB.js} +1 -1
- package/dist/{chunk-CR55WXIN.js → chunk-TVSHIXLA.js} +1 -1
- package/dist/chunk-VZNNI2VR.js +2 -0
- package/dist/chunk-WFQANMBQ.js +1 -0
- package/dist/chunk-ZO5IUMX6.js +63 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +12 -12
- package/dist/kanonaks/DefinedKanonak.d.ts +12 -0
- package/dist/parsing/KanonakObjectParser.d.ts +14 -1
- package/dist/parsing/index.js +1 -1
- package/dist/reasoning/KanonakVocabulary.d.ts +11 -0
- package/dist/reasoning/index.js +1 -1
- package/dist/resolution/ResourceResolver.d.ts +0 -4
- package/dist/resolution/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/uri-helpers/index.js +1 -1
- package/dist/validation/OntologyValidationResult.d.ts +12 -0
- package/dist/validation/ValidationCache.d.ts +34 -76
- package/dist/validation/ValidationSeverity.d.ts +7 -0
- package/dist/validation/documentModel.d.ts +47 -1
- package/dist/validation/index.d.ts +1 -1
- package/dist/validation/index.js +1 -1
- package/dist/validation/rules/repository/ClassDefinitionRule.d.ts +21 -6
- package/dist/validation/rules/repository/ClassHierarchyCycleRule.d.ts +9 -4
- package/dist/validation/rules/repository/EmbeddedKanonakTypeRule.d.ts +29 -90
- package/dist/validation/rules/repository/ObjectPropertyValueValidationRule.d.ts +20 -6
- package/dist/validation/rules/repository/PropertyDomainRule.d.ts +21 -17
- package/dist/validation/rules/repository/PropertyHierarchyCycleRule.d.ts +8 -4
- package/dist/validation/rules/repository/PropertyKindRangeConsistencyRule.d.ts +29 -0
- package/dist/validation/rules/repository/PropertyRangeReferenceRule.d.ts +14 -7
- package/dist/validation/rules/repository/PropertyRangeRequiredRule.d.ts +13 -2
- package/dist/validation/rules/repository/ReservedNameShadowRule.d.ts +24 -0
- package/dist/validation/rules/repository/SubClassOfReferenceRule.d.ts +16 -13
- package/dist/validation/rules/repository/SubPropertyOfReferenceRule.d.ts +12 -5
- package/dist/validation/rules/repository/UnresolvedReferenceRule.d.ts +16 -4
- package/dist/validation/rules/repository/hierarchyCycle.d.ts +25 -0
- package/dist/validation/rules/repository/index.d.ts +2 -4
- package/package.json +2 -2
- package/dist/chunk-4UT2CLAT.js +0 -1
- package/dist/chunk-7HRKWTBB.js +0 -1
- package/dist/chunk-7TKJHKC2.js +0 -1
- package/dist/chunk-BKVPSPG4.js +0 -1
- package/dist/chunk-IEOSSSB5.js +0 -1
- package/dist/chunk-NUXUITUC.js +0 -2
- package/dist/chunk-SHDHMKMJ.js +0 -1
- package/dist/chunk-UBBZWWRB.js +0 -86
- package/dist/validation/rules/repository/DefinitionPropertyReferenceRule.d.ts +0 -13
- package/dist/validation/rules/repository/ObjectPropertyImportRule.d.ts +0 -9
- package/dist/validation/rules/repository/PropertyValueTypeRule.d.ts +0 -11
- package/dist/validation/rules/repository/XsdImportRule.d.ts +0 -11
package/dist/server/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{j as ee}from"../chunk-V72IVYR4.js";import"../chunk-QHABFCRC.js";import{a as he,d as z,f as ye,h as J}from"../chunk-GMEPM2QQ.js";import{d as me,e as fe,f as ke,g as O,h as Y}from"../chunk-JYBKSBB5.js";import{a as ge}from"../chunk-4NO7MHS7.js";import"../chunk-PEUTCG3B.js";import{a as ve}from"../chunk-PEJALHXK.js";import"../chunk-SC5M74NM.js";import"../chunk-SHDHMKMJ.js";import{h as Q}from"../chunk-BKVPSPG4.js";import{a as E}from"../chunk-NJ3AZYQD.js";import{b as X}from"../chunk-IEOSSSB5.js";import{g as Z}from"../chunk-7TKJHKC2.js";import"../chunk-7HRKWTBB.js";import{c as be}from"../chunk-4UT2CLAT.js";import"../chunk-FUUTGGJS.js";import{c as M,e as F,f as L,g as ue}from"../chunk-2ACBWC7K.js";import{readFileSync as De,writeFileSync as _e,mkdirSync as je}from"fs";import{join as $e}from"path";function Se(t){let e=t.metadata?.namespace_;return e?`${e.publisher}/${e.package_}`:void 0}async function H(t,e){let n=new Set,r=[...t];for(;r.length>0;){let s=r.shift(),a=Se(s);if(!a||n.has(a))continue;n.add(a);let m=s.metadata?.imports;if(m)for(let[p,k]of Object.entries(m))for(let d of k)try{let u=await e.getHighestCompatibleVersionAsync(p,d);u&&r.push(u)}catch{}}return n}var V=class{constructor(e,n){this.inner=e;this.scope=n}inner;scope;async getAllDocumentsAsync(){return(await this.inner.getAllDocumentsAsync()).filter(n=>{let r=Se(n);return r!==void 0&&this.scope.has(r)})}getDocumentAsync(e){return this.inner.getDocumentAsync(e)}getDocumentsByNamespaceAsync(e,n){return this.inner.getDocumentsByNamespaceAsync(e,n)}getHighestCompatibleVersionAsync(e,n){return this.inner.getHighestCompatibleVersionAsync(e,n)}saveDocumentAsync(e,n){return this.inner.saveDocumentAsync(e,n)}deleteDocumentAsync(e){return this.inner.deleteDocumentAsync(e)}clearNamespaceAsync(e,n){return this.inner.clearNamespaceAsync(e,n)}getAllDocumentReferencesAsync(){return this.inner.getAllDocumentReferencesAsync()}getDocumentContentAsync(e){return this.inner.getDocumentContentAsync(e)}getDocumentUriAsync(e){return this.inner.getDocumentUriAsync(e)}};var we=[{publisher:"kanonak.org",package_:"core-kanonak"},{publisher:"kanonak.org",package_:"site"},{publisher:"kanonak.org",package_:"link"},{publisher:"kanonak.org",package_:"look-tokens"},{publisher:"kanonak.org",package_:"look-styles"},{publisher:"kanonak.org",package_:"look"},{publisher:"kanonak.org",package_:"universal-look"}];function T(t){let e=t?.render;if(e&&e.length>0){let n=[];for(let r of e)try{let s=X(r);s.kind==="package"?n.push({publisher:s.publisher,package_:s.package_}):s.kind==="resource"&&n.push({publisher:s.uri.publisher,package_:s.uri.package_})}catch{}if(n.length>0)return n}return we}function C(t){return`${t.publisher}/${t.package_}`}function W(t){let e={"kanonak.org/look-styles":"pages render UNSTYLED \u2014 generated CSS stops at the :root token block","kanonak.org/look-tokens":"the :root block loses the universal design-token floor (colors, fonts, spacing)","kanonak.org/universal-look":"resources without their own look render as an empty HTML comment","kanonak.org/look":"band vocabulary (Hero, PropertyList, \u2026) is unresolvable \u2014 declared looks cannot render","kanonak.org/site":"the site vocabulary (content, navigation) is unresolvable \u2014 the base stylesheet cannot bind","kanonak.org/core-kanonak":"the Package/Publisher classes are unresolvable \u2014 package and publisher pages degrade","kanonak.org/link":"link vocabulary is unresolvable \u2014 cross-reference styling degrades"},n=[];for(let r of t)if(r.origin==="missing"){let s=C(r),a=e[s]??"whatever this package contributes to rendering is lost";n.push(`Render-stack package ${s} is MISSING (${r.reason??"unknown reason"}) \u2014 ${a}. Fix: kanonak install ${s} (as the user running the render), or restore network access to ${r.publisher}.`)}else r.resolvedButNotInCatalog&&n.push(`Render-stack package ${C(r)} resolved (${r.origin}) but is NOT in the parsed catalog \u2014 this is a closure-scoping bug; please report it.`);return n}function re(t){let{publisher:e,availablePublishers:n,catalog:r,lookRenderer:s,localNamespaces:a,rawByNsKey:m,renderStack:p,producers:k}=t,d=new Map,u=new Map,o=new Map,h=new Set;for(let y of r){if(!(y instanceof be))continue;let b=y.namespace||"";if(!a.has(b))continue;d.set(`${b}/${y.name}`,y);let $=b.split("/")[1]??"",[w,_]=$.split("@");if(!w||!_)continue;let I=ue(_);I&&(h.has($)||(h.add($),u.has(w)||u.set(w,[]),u.get(w).push({verStr:_,version:I})),y.name===w&&o.set($,y))}for(let y of u.values())y.sort((b,$)=>M($.version,b.version));return{publisher:e,availablePublishers:n,catalog:r,lookRenderer:s,localNamespaces:a,rawByNsKey:m,bySubject:d,pkgVersions:u,pkgSelfByVer:o,renderStack:p,...k?{producers:k}:{}}}async function se(t,e={}){let n=new E,r=new ge(n),s=[],a=[];for(let c of J(t)){let l;try{l=De(c,"utf-8")}catch{continue}let v;try{v=n.parse(l).metadata?.namespace_}catch{continue}if(!v?.version)continue;let N=v.version;a.push({publisher:v.publisher,package_:v.package_,verStr:F(N),version:N,source:l})}a.sort((c,l)=>M(l.version,c.version));for(let c of a)await r.saveDocumentAsync(n.parse(c.source),`${c.publisher}/${c.package_}@${c.verStr}`),s.push({publisher:c.publisher,package_:c.package_,verStr:c.verStr,source:c.source});let m=[...new Set(s.map(c=>c.publisher))].sort(),p=e.publisher;if(p){if(!m.includes(p))throw new Error(`Publisher "${p}" not found in workspace. Available: ${m.join(", ")||"(none)"}`)}else if(m.length===1)p=m[0];else throw m.length===0?new Error(`No Kanonak packages found under ${t}`):new Error(`Workspace has multiple publishers (${m.join(", ")}). Pass --publisher <domain> to choose which one to serve.`);let k=new Set,d=new Map;for(let c of s)c.publisher===p&&(k.add(`${c.publisher}/${c.package_}@${c.verStr}`),d.set(`${c.package_}@${c.verStr}`,c.source));let u=z(),o=new he(u,!0,n),h={};e.httpCache&&(h.getFromCache=e.httpCache.getFromCache,h.onFetch=e.httpCache.onFetch),e.fetchFn&&(h.fetchFn=e.fetchFn);let y=e.repository??new ye(r,o,new Y(h)),b=e.log??(()=>{}),$=T(void 0),w=[],_=c=>c.map(l=>l.metadata.namespace_?.version).filter(l=>l!==void 0).sort((l,v)=>M(v,l)).map(F);if(!e.repository){b(`[render-stack] resolving ${$.length} ambient look-stack package(s); cache: ${u}`);let c=e.fetchFn?new O({fetchFn:e.fetchFn}):new O;for(let l of $){let v=C(l),N=await r.getDocumentsByNamespaceAsync(l.publisher,l.package_);if(N.length>0){let S=_(N);w.push({...l,origin:"workspace",versions:S}),b(`[render-stack] ${v} \u2014 workspace (${S.join(", ")})`);continue}let U=await o.getDocumentsByNamespaceAsync(l.publisher,l.package_);if(U.length>0){let S=_(U);w.push({...l,origin:"cache",versions:S}),b(`[render-stack] ${v} \u2014 cache (${S.join(", ")})`);continue}try{let S=await c.getHighestVersion(l.publisher,l.package_);if(!S){let f=`publisher ${l.publisher} reachable but its index does not list ${l.package_}`;w.push({...l,origin:"missing",reason:f}),b(`[render-stack] ${v} \u2014 MISSING: ${f}`);continue}let j=await c.getPackageUrl(l.publisher,l.package_,S),i=await(e.fetchFn?e.fetchFn(j,l.publisher):me(j));if(!i.ok){let f=`fetch ${j} failed: HTTP ${i.status} ${i.statusText}`;w.push({...l,origin:"missing",reason:f}),b(`[render-stack] ${v} \u2014 MISSING: ${f}`);continue}let g=await i.text();await r.saveDocumentAsync(n.parse(g),`${l.publisher}/${l.package_}@${S}`);try{let f=$e(u,l.publisher);je(f,{recursive:!0}),_e($e(f,`${l.package_}@${S}.kan.yml`),g,"utf-8"),w.push({...l,origin:"fetched",versions:[S]}),b(`[render-stack] ${v}@${S} \u2014 fetched from ${j}, installed to cache`)}catch(f){w.push({...l,origin:"fetched",versions:[S]}),b(`[render-stack] ${v}@${S} \u2014 fetched from ${j}, but cache ${u} is NOT WRITABLE (${f.message}); usable for this load only \u2014 every load will re-fetch it`)}}catch(S){let j=`fetch failed: ${S.message}`;w.push({...l,origin:"missing",reason:j}),b(`[render-stack] ${v} \u2014 MISSING: ${j}`)}}}let I=y;if(!e.repository){let c=(await r.getAllDocumentsAsync()).filter(v=>v.metadata.namespace_?.publisher===p),l=await H(c,y);for(let v of $)l.add(C(v));I=new V(y,l)}let B=await new Q(n).parseKanonaks(I),oe=new ee(B),G=(c,l)=>Z(B,{publisher:c,package_:l,name:l}).length>0,A;if(e.repository){A=[];for(let c of $){let l=await y.getDocumentsByNamespaceAsync(c.publisher,c.package_);A.push(l.length>0?{...c,origin:"repository",versions:_(l)}:{...c,origin:"missing",reason:"not present in the caller-supplied repository"})}}else A=w.map(c=>c.origin==="missing"||G(c.publisher,c.package_)?c:{...c,resolvedButNotInCatalog:!0});let q=W(A);for(let c of q)b(`[render-stack] WARNING: ${c}`);return re({publisher:p,availablePublishers:m,catalog:B,lookRenderer:oe,localNamespaces:k,rawByNsKey:d,renderStack:{contractSource:"universal-default",cachePath:u,packages:A,warnings:q}})}import{existsSync as Ce,readFileSync as Ae,writeFileSync as Ie,mkdirSync as Ne}from"fs";import{join as Re}from"path";async function ae(t,e={}){let n=new E,r=X(t),s=r.kind==="resource"?r.uri.publisher:r.publisher,a=e.log??(()=>{}),m=e.cacheRoot??z(),p=(i,g,f)=>Re(m,i,`${g}@${f}.kan.yml`),k=new Set,d=new Set,u=new Map,o=new Y({getFromCache:(i,g,f)=>{let D=p(i,g,f),R=Ce(D)?Ae(D,"utf-8"):null;return R!==null&&k.add(`${i}/${g}`),R},onFetch:(i,g,f,D)=>{d.add(`${i}/${g}`);try{let R=Re(m,i);Ne(R,{recursive:!0}),Ie(p(i,g,f),D,"utf-8")}catch(R){u.set(`${i}/${g}`,R.message),a(`[render] fetched ${i}/${g}@${f} but cache ${m} is NOT WRITABLE (${R.message}); usable for this load only \u2014 every load will re-fetch it`)}},...e.fetchFn?{fetchFn:e.fetchFn}:{}}),h=new O(e.fetchFn?{fetchFn:e.fetchFn}:void 0),y;if(r.kind==="resource"){let i=r.uri.version;y=[i?{package_:r.uri.package_,version:`${i.major}.${i.minor}.${i.patch}`}:{package_:r.uri.package_}]}else if(r.kind==="package"){let i=r.version;y=[i?{package_:r.package_,version:`${i.major}.${i.minor}.${i.patch}`}:{package_:r.package_}]}else y=(await h.listLatestPackages(s)).map(g=>({package_:g.packageName}));let b=async(i,g,f)=>{try{let D=f?n.buildImport(g,"=",f,i):n.buildImport(g,"*","0.0.0",i),R=await o.getHighestCompatibleVersionAsync(i,D);return R?{doc:R}:{doc:null,error:`${i} did not resolve ${g}${f?`@${f}`:""} (not in its index, or unreachable)`}}catch(D){return{doc:null,error:D.message}}},$=[],w=[];for(let i of y){let{doc:g,error:f}=await b(s,i.package_,i.version);g?$.push(g):f&&w.push(f)}if($.length===0)throw new Error(`Could not fetch any package for address "${t}" from publisher "${s}".`+(w.length>0?` Reasons: ${w.join("; ")}`:""));let _=await new ke(e.fetchFn).getConfig(s).catch(()=>{}),I=T(_),B=_?.render&&_.render.length>0?"publisher-well-known":"universal-default",oe=i=>i.map(g=>g.metadata.namespace_?.version).filter(g=>g!==void 0).sort((g,f)=>M(f,g)).map(F);a(`[render-stack] resolving ${I.length} ambient look-stack package(s) (contract: ${B}); cache: ${m}`);let G=[],A=[];for(let i of I){let g=C(i),{doc:f,error:D}=await b(i.publisher,i.package_,void 0);if(f){G.push(f);let R=oe([f]),pe=d.has(g)?"fetched":k.has(g)?"cache":"fetched";A.push({...i,origin:pe,versions:R}),a(`[render-stack] ${g} \u2014 ${pe} (${R.join(", ")})`+(u.has(g)?" [cache write FAILED \u2014 will re-fetch next load]":""))}else A.push({...i,origin:"missing",reason:D??"unresolved"}),a(`[render-stack] ${g} \u2014 MISSING: ${D??"unresolved"}`)}let q=await H([...$,...G],o),de=new V(o,q),c=await new Q(n).parseKanonaks(de),l=new ee(c),v=A.map(i=>i.origin==="missing"||Z(c,{publisher:i.publisher,package_:i.package_,name:i.package_}).length>0?i:{...i,resolvedButNotInCatalog:!0}),N=W(v);for(let i of N)a(`[render-stack] WARNING: ${i}`);let U={contractSource:B,cachePath:m,packages:v,warnings:N},S=new Set,j=new Map;for(let i of await o.getAllDocumentsAsync()){let g=i.metadata.namespace_;if(!g?.version||g.publisher!==s)continue;let f=F(g.version),D=`${g.publisher}/${g.package_}@${f}`;S.add(D);let R=await o.getDocumentContentAsync(D);R!==null&&j.set(`${g.package_}@${f}`,R)}return re({publisher:s,availablePublishers:[s],catalog:c,lookRenderer:l,localNamespaces:S,rawByNsKey:j,renderStack:U})}import{VersionOperator as ne}from"@kanonak-protocol/types/document/models/enums";function te(t){let{lookRenderer:e,publisher:n,renderStack:r,catalog:s}=t,a=e.explainStylesheet(e.publisherSubject(n)),m=[...a.tokens.entries()].map(([o,h])=>({name:o,value:h.value,source:`${h.sourceNamespace}/${h.sourceName}`,level:h.level})),p=a.baseStylesheet,k={present:p.css!==void 0,...p.sourceNamespace!==void 0?{source:p.sourceNamespace}:{},...p.scope!==void 0?{scope:p.scope}:{},...p.css!==void 0?{bytes:p.css.length}:{},...p.problem!==void 0?{problem:p.problem}:{},candidates:p.candidates},d=new Map;for(let o of s){let h=o.namespace;h&&d.set(h,(d.get(h)??0)+1)}let u=[...d.entries()].map(([o,h])=>({namespace:o,resources:h})).sort((o,h)=>o.namespace.localeCompare(h.namespace));return{publisher:n,renderStack:{contractSource:r.contractSource,cachePath:r.cachePath,packages:r.packages.map(o=>({package_:C(o),origin:o.origin,...o.versions!==void 0?{versions:o.versions}:{},...o.reason!==void 0?{reason:o.reason}:{},...o.resolvedButNotInCatalog!==void 0?{resolvedButNotInCatalog:o.resolvedButNotInCatalog}:{}}))},stylesheet:{tokens:m,baseStylesheet:k,...a.look?{look:{sourceClass:`${a.look.sourceClass.publisher}/${a.look.sourceClass.package_}/${a.look.sourceClass.name}`}}:{}},catalog:u,warnings:[...r.warnings,...a.warnings.filter(o=>!r.warnings.includes(o))]}}function Fe(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function ie(t){let e=Fe,n=t.warnings.length===0,r=t.warnings.length===0?'<p class="ok">\u2713 No problems detected \u2014 the render stack is fully resolved and pages should be styled.</p>':t.warnings.map(d=>`<div class="warn">\u26A0 ${e(d)}</div>`).join(`
|
|
1
|
+
import{j as ee}from"../chunk-IHB7UVEH.js";import"../chunk-QHABFCRC.js";import{a as he,d as z,f as ye,h as J}from"../chunk-GMEPM2QQ.js";import{d as me,e as fe,f as ke,g as O,h as Y}from"../chunk-JYBKSBB5.js";import{a as ge}from"../chunk-4NO7MHS7.js";import"../chunk-PEUTCG3B.js";import{a as ve}from"../chunk-PEJALHXK.js";import"../chunk-SC5M74NM.js";import{l as X}from"../chunk-MX3DEXMV.js";import{a as E}from"../chunk-NJ3AZYQD.js";import{b as Z}from"../chunk-WFQANMBQ.js";import"../chunk-6U26UASC.js";import"../chunk-GZPLWII7.js";import{c as be,s as Q}from"../chunk-7BHDZHJY.js";import"../chunk-FUUTGGJS.js";import{c as M,e as F,f as L,g as ue}from"../chunk-2ACBWC7K.js";import{readFileSync as De,writeFileSync as _e,mkdirSync as je}from"fs";import{join as $e}from"path";function Se(t){let e=t.metadata?.namespace_;return e?`${e.publisher}/${e.package_}`:void 0}async function H(t,e){let n=new Set,r=[...t];for(;r.length>0;){let s=r.shift(),a=Se(s);if(!a||n.has(a))continue;n.add(a);let m=s.metadata?.imports;if(m)for(let[p,k]of Object.entries(m))for(let d of k)try{let u=await e.getHighestCompatibleVersionAsync(p,d);u&&r.push(u)}catch{}}return n}var V=class{constructor(e,n){this.inner=e;this.scope=n}inner;scope;async getAllDocumentsAsync(){return(await this.inner.getAllDocumentsAsync()).filter(n=>{let r=Se(n);return r!==void 0&&this.scope.has(r)})}getDocumentAsync(e){return this.inner.getDocumentAsync(e)}getDocumentsByNamespaceAsync(e,n){return this.inner.getDocumentsByNamespaceAsync(e,n)}getHighestCompatibleVersionAsync(e,n){return this.inner.getHighestCompatibleVersionAsync(e,n)}saveDocumentAsync(e,n){return this.inner.saveDocumentAsync(e,n)}deleteDocumentAsync(e){return this.inner.deleteDocumentAsync(e)}clearNamespaceAsync(e,n){return this.inner.clearNamespaceAsync(e,n)}getAllDocumentReferencesAsync(){return this.inner.getAllDocumentReferencesAsync()}getDocumentContentAsync(e){return this.inner.getDocumentContentAsync(e)}getDocumentUriAsync(e){return this.inner.getDocumentUriAsync(e)}};var we=[{publisher:"kanonak.org",package_:"core-kanonak"},{publisher:"kanonak.org",package_:"site"},{publisher:"kanonak.org",package_:"link"},{publisher:"kanonak.org",package_:"look-tokens"},{publisher:"kanonak.org",package_:"look-styles"},{publisher:"kanonak.org",package_:"look"},{publisher:"kanonak.org",package_:"universal-look"}];function T(t){let e=t?.render;if(e&&e.length>0){let n=[];for(let r of e)try{let s=Z(r);s.kind==="package"?n.push({publisher:s.publisher,package_:s.package_}):s.kind==="resource"&&n.push({publisher:s.uri.publisher,package_:s.uri.package_})}catch{}if(n.length>0)return n}return we}function C(t){return`${t.publisher}/${t.package_}`}function W(t){let e={"kanonak.org/look-styles":"pages render UNSTYLED \u2014 generated CSS stops at the :root token block","kanonak.org/look-tokens":"the :root block loses the universal design-token floor (colors, fonts, spacing)","kanonak.org/universal-look":"resources without their own look render as an empty HTML comment","kanonak.org/look":"band vocabulary (Hero, PropertyList, \u2026) is unresolvable \u2014 declared looks cannot render","kanonak.org/site":"the site vocabulary (content, navigation) is unresolvable \u2014 the base stylesheet cannot bind","kanonak.org/core-kanonak":"the Package/Publisher classes are unresolvable \u2014 package and publisher pages degrade","kanonak.org/link":"link vocabulary is unresolvable \u2014 cross-reference styling degrades"},n=[];for(let r of t)if(r.origin==="missing"){let s=C(r),a=e[s]??"whatever this package contributes to rendering is lost";n.push(`Render-stack package ${s} is MISSING (${r.reason??"unknown reason"}) \u2014 ${a}. Fix: kanonak install ${s} (as the user running the render), or restore network access to ${r.publisher}.`)}else r.resolvedButNotInCatalog&&n.push(`Render-stack package ${C(r)} resolved (${r.origin}) but is NOT in the parsed catalog \u2014 this is a closure-scoping bug; please report it.`);return n}function re(t){let{publisher:e,availablePublishers:n,catalog:r,lookRenderer:s,localNamespaces:a,rawByNsKey:m,renderStack:p,producers:k}=t,d=new Map,u=new Map,o=new Map,h=new Set;for(let y of r){if(!(y instanceof be))continue;let b=y.namespace||"";if(!a.has(b))continue;d.set(`${b}/${y.name}`,y);let $=b.split("/")[1]??"",[w,_]=$.split("@");if(!w||!_)continue;let I=ue(_);I&&(h.has($)||(h.add($),u.has(w)||u.set(w,[]),u.get(w).push({verStr:_,version:I})),y.name===w&&o.set($,y))}for(let y of u.values())y.sort((b,$)=>M($.version,b.version));return{publisher:e,availablePublishers:n,catalog:r,lookRenderer:s,localNamespaces:a,rawByNsKey:m,bySubject:d,pkgVersions:u,pkgSelfByVer:o,renderStack:p,...k?{producers:k}:{}}}async function se(t,e={}){let n=new E,r=new ge(n),s=[],a=[];for(let c of J(t)){let l;try{l=De(c,"utf-8")}catch{continue}let v;try{v=n.parse(l).metadata?.namespace_}catch{continue}if(!v?.version)continue;let N=v.version;a.push({publisher:v.publisher,package_:v.package_,verStr:F(N),version:N,source:l})}a.sort((c,l)=>M(l.version,c.version));for(let c of a)await r.saveDocumentAsync(n.parse(c.source),`${c.publisher}/${c.package_}@${c.verStr}`),s.push({publisher:c.publisher,package_:c.package_,verStr:c.verStr,source:c.source});let m=[...new Set(s.map(c=>c.publisher))].sort(),p=e.publisher;if(p){if(!m.includes(p))throw new Error(`Publisher "${p}" not found in workspace. Available: ${m.join(", ")||"(none)"}`)}else if(m.length===1)p=m[0];else throw m.length===0?new Error(`No Kanonak packages found under ${t}`):new Error(`Workspace has multiple publishers (${m.join(", ")}). Pass --publisher <domain> to choose which one to serve.`);let k=new Set,d=new Map;for(let c of s)c.publisher===p&&(k.add(`${c.publisher}/${c.package_}@${c.verStr}`),d.set(`${c.package_}@${c.verStr}`,c.source));let u=z(),o=new he(u,!0,n),h={};e.httpCache&&(h.getFromCache=e.httpCache.getFromCache,h.onFetch=e.httpCache.onFetch),e.fetchFn&&(h.fetchFn=e.fetchFn);let y=e.repository??new ye(r,o,new Y(h)),b=e.log??(()=>{}),$=T(void 0),w=[],_=c=>c.map(l=>l.metadata.namespace_?.version).filter(l=>l!==void 0).sort((l,v)=>M(v,l)).map(F);if(!e.repository){b(`[render-stack] resolving ${$.length} ambient look-stack package(s); cache: ${u}`);let c=e.fetchFn?new O({fetchFn:e.fetchFn}):new O;for(let l of $){let v=C(l),N=await r.getDocumentsByNamespaceAsync(l.publisher,l.package_);if(N.length>0){let S=_(N);w.push({...l,origin:"workspace",versions:S}),b(`[render-stack] ${v} \u2014 workspace (${S.join(", ")})`);continue}let U=await o.getDocumentsByNamespaceAsync(l.publisher,l.package_);if(U.length>0){let S=_(U);w.push({...l,origin:"cache",versions:S}),b(`[render-stack] ${v} \u2014 cache (${S.join(", ")})`);continue}try{let S=await c.getHighestVersion(l.publisher,l.package_);if(!S){let f=`publisher ${l.publisher} reachable but its index does not list ${l.package_}`;w.push({...l,origin:"missing",reason:f}),b(`[render-stack] ${v} \u2014 MISSING: ${f}`);continue}let j=await c.getPackageUrl(l.publisher,l.package_,S),i=await(e.fetchFn?e.fetchFn(j,l.publisher):me(j));if(!i.ok){let f=`fetch ${j} failed: HTTP ${i.status} ${i.statusText}`;w.push({...l,origin:"missing",reason:f}),b(`[render-stack] ${v} \u2014 MISSING: ${f}`);continue}let g=await i.text();await r.saveDocumentAsync(n.parse(g),`${l.publisher}/${l.package_}@${S}`);try{let f=$e(u,l.publisher);je(f,{recursive:!0}),_e($e(f,`${l.package_}@${S}.kan.yml`),g,"utf-8"),w.push({...l,origin:"fetched",versions:[S]}),b(`[render-stack] ${v}@${S} \u2014 fetched from ${j}, installed to cache`)}catch(f){w.push({...l,origin:"fetched",versions:[S]}),b(`[render-stack] ${v}@${S} \u2014 fetched from ${j}, but cache ${u} is NOT WRITABLE (${f.message}); usable for this load only \u2014 every load will re-fetch it`)}}catch(S){let j=`fetch failed: ${S.message}`;w.push({...l,origin:"missing",reason:j}),b(`[render-stack] ${v} \u2014 MISSING: ${j}`)}}}let I=y;if(!e.repository){let c=(await r.getAllDocumentsAsync()).filter(v=>v.metadata.namespace_?.publisher===p),l=await H(c,y);for(let v of $)l.add(C(v));I=new V(y,l)}let B=await new X(n).parseKanonaks(I),oe=new ee(B),G=(c,l)=>Q(B,{publisher:c,package_:l,name:l}).length>0,A;if(e.repository){A=[];for(let c of $){let l=await y.getDocumentsByNamespaceAsync(c.publisher,c.package_);A.push(l.length>0?{...c,origin:"repository",versions:_(l)}:{...c,origin:"missing",reason:"not present in the caller-supplied repository"})}}else A=w.map(c=>c.origin==="missing"||G(c.publisher,c.package_)?c:{...c,resolvedButNotInCatalog:!0});let q=W(A);for(let c of q)b(`[render-stack] WARNING: ${c}`);return re({publisher:p,availablePublishers:m,catalog:B,lookRenderer:oe,localNamespaces:k,rawByNsKey:d,renderStack:{contractSource:"universal-default",cachePath:u,packages:A,warnings:q}})}import{existsSync as Ce,readFileSync as Ae,writeFileSync as Ie,mkdirSync as Ne}from"fs";import{join as Re}from"path";async function ae(t,e={}){let n=new E,r=Z(t),s=r.kind==="resource"?r.uri.publisher:r.publisher,a=e.log??(()=>{}),m=e.cacheRoot??z(),p=(i,g,f)=>Re(m,i,`${g}@${f}.kan.yml`),k=new Set,d=new Set,u=new Map,o=new Y({getFromCache:(i,g,f)=>{let D=p(i,g,f),R=Ce(D)?Ae(D,"utf-8"):null;return R!==null&&k.add(`${i}/${g}`),R},onFetch:(i,g,f,D)=>{d.add(`${i}/${g}`);try{let R=Re(m,i);Ne(R,{recursive:!0}),Ie(p(i,g,f),D,"utf-8")}catch(R){u.set(`${i}/${g}`,R.message),a(`[render] fetched ${i}/${g}@${f} but cache ${m} is NOT WRITABLE (${R.message}); usable for this load only \u2014 every load will re-fetch it`)}},...e.fetchFn?{fetchFn:e.fetchFn}:{}}),h=new O(e.fetchFn?{fetchFn:e.fetchFn}:void 0),y;if(r.kind==="resource"){let i=r.uri.version;y=[i?{package_:r.uri.package_,version:`${i.major}.${i.minor}.${i.patch}`}:{package_:r.uri.package_}]}else if(r.kind==="package"){let i=r.version;y=[i?{package_:r.package_,version:`${i.major}.${i.minor}.${i.patch}`}:{package_:r.package_}]}else y=(await h.listLatestPackages(s)).map(g=>({package_:g.packageName}));let b=async(i,g,f)=>{try{let D=f?n.buildImport(g,"=",f,i):n.buildImport(g,"*","0.0.0",i),R=await o.getHighestCompatibleVersionAsync(i,D);return R?{doc:R}:{doc:null,error:`${i} did not resolve ${g}${f?`@${f}`:""} (not in its index, or unreachable)`}}catch(D){return{doc:null,error:D.message}}},$=[],w=[];for(let i of y){let{doc:g,error:f}=await b(s,i.package_,i.version);g?$.push(g):f&&w.push(f)}if($.length===0)throw new Error(`Could not fetch any package for address "${t}" from publisher "${s}".`+(w.length>0?` Reasons: ${w.join("; ")}`:""));let _=await new ke(e.fetchFn).getConfig(s).catch(()=>{}),I=T(_),B=_?.render&&_.render.length>0?"publisher-well-known":"universal-default",oe=i=>i.map(g=>g.metadata.namespace_?.version).filter(g=>g!==void 0).sort((g,f)=>M(f,g)).map(F);a(`[render-stack] resolving ${I.length} ambient look-stack package(s) (contract: ${B}); cache: ${m}`);let G=[],A=[];for(let i of I){let g=C(i),{doc:f,error:D}=await b(i.publisher,i.package_,void 0);if(f){G.push(f);let R=oe([f]),pe=d.has(g)?"fetched":k.has(g)?"cache":"fetched";A.push({...i,origin:pe,versions:R}),a(`[render-stack] ${g} \u2014 ${pe} (${R.join(", ")})`+(u.has(g)?" [cache write FAILED \u2014 will re-fetch next load]":""))}else A.push({...i,origin:"missing",reason:D??"unresolved"}),a(`[render-stack] ${g} \u2014 MISSING: ${D??"unresolved"}`)}let q=await H([...$,...G],o),de=new V(o,q),c=await new X(n).parseKanonaks(de),l=new ee(c),v=A.map(i=>i.origin==="missing"||Q(c,{publisher:i.publisher,package_:i.package_,name:i.package_}).length>0?i:{...i,resolvedButNotInCatalog:!0}),N=W(v);for(let i of N)a(`[render-stack] WARNING: ${i}`);let U={contractSource:B,cachePath:m,packages:v,warnings:N},S=new Set,j=new Map;for(let i of await o.getAllDocumentsAsync()){let g=i.metadata.namespace_;if(!g?.version||g.publisher!==s)continue;let f=F(g.version),D=`${g.publisher}/${g.package_}@${f}`;S.add(D);let R=await o.getDocumentContentAsync(D);R!==null&&j.set(`${g.package_}@${f}`,R)}return re({publisher:s,availablePublishers:[s],catalog:c,lookRenderer:l,localNamespaces:S,rawByNsKey:j,renderStack:U})}import{VersionOperator as ne}from"@kanonak-protocol/types/document/models/enums";function te(t){let{lookRenderer:e,publisher:n,renderStack:r,catalog:s}=t,a=e.explainStylesheet(e.publisherSubject(n)),m=[...a.tokens.entries()].map(([o,h])=>({name:o,value:h.value,source:`${h.sourceNamespace}/${h.sourceName}`,level:h.level})),p=a.baseStylesheet,k={present:p.css!==void 0,...p.sourceNamespace!==void 0?{source:p.sourceNamespace}:{},...p.scope!==void 0?{scope:p.scope}:{},...p.css!==void 0?{bytes:p.css.length}:{},...p.problem!==void 0?{problem:p.problem}:{},candidates:p.candidates},d=new Map;for(let o of s){let h=o.namespace;h&&d.set(h,(d.get(h)??0)+1)}let u=[...d.entries()].map(([o,h])=>({namespace:o,resources:h})).sort((o,h)=>o.namespace.localeCompare(h.namespace));return{publisher:n,renderStack:{contractSource:r.contractSource,cachePath:r.cachePath,packages:r.packages.map(o=>({package_:C(o),origin:o.origin,...o.versions!==void 0?{versions:o.versions}:{},...o.reason!==void 0?{reason:o.reason}:{},...o.resolvedButNotInCatalog!==void 0?{resolvedButNotInCatalog:o.resolvedButNotInCatalog}:{}}))},stylesheet:{tokens:m,baseStylesheet:k,...a.look?{look:{sourceClass:`${a.look.sourceClass.publisher}/${a.look.sourceClass.package_}/${a.look.sourceClass.name}`}}:{}},catalog:u,warnings:[...r.warnings,...a.warnings.filter(o=>!r.warnings.includes(o))]}}function Fe(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function ie(t){let e=Fe,n=t.warnings.length===0,r=t.warnings.length===0?'<p class="ok">\u2713 No problems detected \u2014 the render stack is fully resolved and pages should be styled.</p>':t.warnings.map(d=>`<div class="warn">\u26A0 ${e(d)}</div>`).join(`
|
|
2
2
|
`),s=t.renderStack.packages.map(d=>{let u=d.origin!=="missing"&&!d.resolvedButNotInCatalog,o=d.origin==="missing"?'<span class="bad">MISSING</span>':d.resolvedButNotInCatalog?`<span class="bad">${e(d.origin)} (not in catalog)</span>`:`<span class="good">${e(d.origin)}</span>`,h=d.reason?e(d.reason):e((d.versions??[]).join(", "));return`<tr class="${u?"":"row-bad"}"><td><code>${e(d.package_)}</code></td><td>${o}</td><td>${h}</td></tr>`}).join(`
|
|
3
3
|
`),a=t.stylesheet.baseStylesheet,m=a.present?`<p><span class="good">\u2713 present</span> \u2014 <code>${e(a.source??"")}</code> (${a.bytes} bytes, ${e(a.scope??"")})</p>`:`<p><span class="bad">\u2717 MISSING</span>${a.problem?` \u2014 ${e(a.problem)}`:""}${a.candidates.length>0?`<br>candidates considered: ${a.candidates.map(d=>`<code>${e(d)}</code>`).join(", ")}`:""}</p><p>Without the base stylesheet, generated CSS stops at the <code>:root</code> token block and pages appear unstyled.</p>`,p=t.stylesheet.tokens.map(d=>`<tr><td><code>--kan-${e(d.name)}</code></td><td><code>${e(d.value)}</code></td><td><code>${e(d.source)}</code></td><td>${e(d.level)}</td></tr>`).join(`
|
|
4
4
|
`),k=t.catalog.map(d=>`<tr><td><code>${e(d.namespace)}</code></td><td>${d.resources}</td></tr>`).join(`
|
|
@@ -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-IHB7UVEH.js";import{a as se}from"../chunk-EZSHR3CB.js";import"../chunk-QHABFCRC.js";import"../chunk-4NO7MHS7.js";import"../chunk-S6VSAKXB.js";import"../chunk-PEJALHXK.js";import{d as kn,e as bn,f as hn,g as Dn,l as ie}from"../chunk-MX3DEXMV.js";import{a as ae}from"../chunk-NJ3AZYQD.js";import"../chunk-6U26UASC.js";import"../chunk-GZPLWII7.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,n as L,o as A,r as S}from"../chunk-7BHDZHJY.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(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a,b,c,d,e,f,g,h,i,j,k,l,m
|
|
1
|
+
import{a as n}from"../chunk-6U26UASC.js";import{m as a,n as b,o as c,p as d,q as e,r as f,s as g,t as h,u as i,v as j,w as k,x as l,y as m}from"../chunk-7BHDZHJY.js";import"../chunk-FUUTGGJS.js";import"../chunk-2ACBWC7K.js";export{n as SingleDocumentRepository,g as findAllResourcesByCanonicalUri,f as findSubjectByUri,e as findSubjectsByType,i as getDatatypeValue,l as getEmbeddedValue,m as getListValues,k as getReferenceUri,j as getStringValue,h as hasProperty,d as hasType,c as toCanonicalUrl,a as uriKey,b as uriMatches};
|
|
@@ -3,5 +3,17 @@ export declare class OntologyValidationResult {
|
|
|
3
3
|
isValid: boolean;
|
|
4
4
|
errors: OntologyValidationError[];
|
|
5
5
|
warnings: OntologyValidationError[];
|
|
6
|
+
/**
|
|
7
|
+
* Informational notices (`ValidationSeverity.Info`) — never affect `isValid`.
|
|
8
|
+
* Kept in their own channel so consumers can surface them distinctly (an
|
|
9
|
+
* Information diagnostic in an editor, a separate CLI line) or ignore them.
|
|
10
|
+
*/
|
|
11
|
+
infos: OntologyValidationError[];
|
|
6
12
|
get totalIssues(): number;
|
|
13
|
+
/**
|
|
14
|
+
* All diagnostics across every severity, errors first. Consumers that render
|
|
15
|
+
* every severity (the VS Code PROBLEMS view, the CLI listing) iterate this so
|
|
16
|
+
* a new severity channel is picked up without each call site changing.
|
|
17
|
+
*/
|
|
18
|
+
get allDiagnostics(): OntologyValidationError[];
|
|
7
19
|
}
|
|
@@ -1,94 +1,52 @@
|
|
|
1
1
|
import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
|
|
2
2
|
import type { Kanonak } from '../kanonaks/Kanonak.js';
|
|
3
3
|
/**
|
|
4
|
-
* Per-validation-pass memoization shared across every repository rule
|
|
5
|
-
*
|
|
4
|
+
* Per-validation-pass memoization shared across every repository rule applied to
|
|
5
|
+
* documents in the same repository.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* the entire repo through `KanonakObjectParser`.
|
|
7
|
+
* The expensive shared work is the full-repository `parseKanonaks`. Every
|
|
8
|
+
* repository rule reads the resolved object model (the merged catalog via
|
|
9
|
+
* {@link getKanonaks}, or the pre-merge per-document authored view via
|
|
10
|
+
* {@link getAuthoredKanonaks}); the cache parses the repo at most ONCE per pass
|
|
11
|
+
* and serves both views from that single parse. A batch caller
|
|
12
|
+
* (`KanonakObjectValidator.validateDocumentsAsync`) constructs one cache and
|
|
13
|
+
* threads it through every per-document `validateAsync`, so validating a whole
|
|
14
|
+
* directory is one parse, not O(documents x catalog).
|
|
16
15
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* reading from the cache when present; without it they fall back
|
|
23
|
-
* to their original logic (used by single-document callers like
|
|
24
|
-
* the CLI's `kanonak validate <path>`).
|
|
25
|
-
*
|
|
26
|
-
* The cache also exposes a wrapped `repository` that memoizes
|
|
27
|
-
* `getHighestCompatibleVersionAsync` and
|
|
28
|
-
* `getDocumentsByNamespaceAsync` — both linear scans over the
|
|
29
|
-
* in-memory repo. Rules that don't know about the cache still
|
|
30
|
-
* benefit, because the validator passes `cache.repository` as the
|
|
31
|
-
* repo argument so their existing lookup calls hit the cache
|
|
32
|
-
* transparently.
|
|
16
|
+
* The cache also exposes a wrapped {@link repository} that memoizes the two
|
|
17
|
+
* linear-scan repository lookups (`getHighestCompatibleVersionAsync`,
|
|
18
|
+
* `getDocumentsByNamespaceAsync`); rules that call the repository directly hit
|
|
19
|
+
* the cache transparently because the validator passes `cache.repository` as the
|
|
20
|
+
* repo argument.
|
|
33
21
|
*/
|
|
34
22
|
export declare class ValidationCache {
|
|
35
23
|
private readonly underlying;
|
|
36
24
|
/**
|
|
37
|
-
* Repository wrapper that memoizes read-only lookups for the
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* automatically without needing to know about the cache.
|
|
25
|
+
* Repository wrapper that memoizes read-only lookups for the lifetime of this
|
|
26
|
+
* cache. Pass this to every rule (instead of the bare repository) so existing
|
|
27
|
+
* rule code that calls `repository.getHighestCompatibleVersionAsync(...)`
|
|
28
|
+
* benefits automatically without needing to know about the cache.
|
|
42
29
|
*/
|
|
43
30
|
readonly repository: IKanonakDocumentRepository;
|
|
44
|
-
private
|
|
45
|
-
private importClosureCache;
|
|
46
|
-
private classDeclarationsCache;
|
|
47
|
-
private propertyNamesCache;
|
|
48
|
-
private allDocumentsPromise;
|
|
31
|
+
private parsePromise;
|
|
49
32
|
constructor(underlying: IKanonakDocumentRepository);
|
|
50
33
|
/**
|
|
51
|
-
* Full-repository `parseKanonaks` result
|
|
52
|
-
* lifetime.
|
|
53
|
-
*
|
|
54
|
-
* Filter by `subject.namespace` to scope to a specific document.
|
|
34
|
+
* Full-repository `parseKanonaks` result (the open-world-merged catalog),
|
|
35
|
+
* memoized for the cache's lifetime. Filter by `subject.namespace` to scope to
|
|
36
|
+
* a specific document.
|
|
55
37
|
*/
|
|
56
38
|
getKanonaks(): Promise<Kanonak[]>;
|
|
57
39
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*/
|
|
68
|
-
getImportClosure(docId: string): Promise<Set<string>>;
|
|
69
|
-
/**
|
|
70
|
-
* subClassOf relationships declared inside the given document's
|
|
71
|
-
* body (NOT in its imports). Map<className, parentClassName[]>.
|
|
72
|
-
* Composed across an import closure to build the effective class
|
|
73
|
-
* hierarchy a rule needs.
|
|
74
|
-
*
|
|
75
|
-
* Cached per-doc so two rules consulting the same document's
|
|
76
|
-
* declarations (or the same document validated multiple times)
|
|
77
|
-
* walk its body once.
|
|
78
|
-
*/
|
|
79
|
-
getClassDeclarations(docId: string): Promise<Map<string, string[]>>;
|
|
80
|
-
/**
|
|
81
|
-
* Names of property-typed entities (`ObjectProperty`,
|
|
82
|
-
* `DatatypeProperty`, `AnnotationProperty`, plain `Property`)
|
|
83
|
-
* declared inside the given document's body. Used by reference-
|
|
84
|
-
* resolution rules to answer "is property P defined here?" in O(1)
|
|
85
|
-
* after a one-time scan.
|
|
40
|
+
* The PRE-MERGE, per-document parse from the SAME single full-repo parse as
|
|
41
|
+
* {@link getKanonaks}: each document's authored subjects (and embeddeds),
|
|
42
|
+
* stamped with their `sourceDoc`, before the open-world merge folds them onto
|
|
43
|
+
* shared URIs and dedups cross-document duplicates. A per-document rule that
|
|
44
|
+
* must validate exactly what a document authored — including augmentations it
|
|
45
|
+
* asserts about imported entities, which the merge files under the imported
|
|
46
|
+
* namespace — filters this by `sourceDoc`, instead of re-parsing the document
|
|
47
|
+
* (which would break the ≤1-parse contract). Resolution targets still come
|
|
48
|
+
* from the merged {@link getKanonaks}.
|
|
86
49
|
*/
|
|
87
|
-
|
|
88
|
-
private
|
|
89
|
-
private computeImportClosure;
|
|
90
|
-
private buildDocsByIdIndex;
|
|
91
|
-
private computeClassDeclarations;
|
|
92
|
-
private computePropertyNames;
|
|
93
|
-
private findDocById;
|
|
50
|
+
getAuthoredKanonaks(): Promise<Kanonak[]>;
|
|
51
|
+
private parseOnce;
|
|
94
52
|
}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
export declare enum ValidationSeverity {
|
|
2
|
+
/**
|
|
3
|
+
* Informational notice — nothing is wrong and resolution succeeds, but
|
|
4
|
+
* something is worth confirming because a silent mistake could hide here
|
|
5
|
+
* (e.g. a local entity that shadows a reserved built-in name). Surfaces in
|
|
6
|
+
* tooling as an Information diagnostic, never blocks.
|
|
7
|
+
*/
|
|
8
|
+
Info = "Info",
|
|
2
9
|
Warning = "Warning",
|
|
3
10
|
Error = "Error"
|
|
4
11
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
|
|
2
|
-
import type { KanonakDocument } from '@kanonak-protocol/types/document/models/types';
|
|
2
|
+
import type { KanonakDocument, Import, DocumentReference } from '@kanonak-protocol/types/document/models/types';
|
|
3
3
|
import type { ValidationCache } from './ValidationCache.js';
|
|
4
4
|
import type { Kanonak } from '../kanonaks/Kanonak.js';
|
|
5
5
|
import { DefinedKanonak } from '../kanonaks/DefinedKanonak.js';
|
|
@@ -29,6 +29,24 @@ export declare function getCatalogKanonaks(document: KanonakDocument, repository
|
|
|
29
29
|
* captured data.)
|
|
30
30
|
*/
|
|
31
31
|
export declare function getDocumentKanonaks(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<Kanonak[]>;
|
|
32
|
+
/**
|
|
33
|
+
* The subjects THIS document authored — INCLUDING the open-world augmentations
|
|
34
|
+
* it asserts about imported entities. An augmentation (e.g. a look package
|
|
35
|
+
* adding `semanticSvg` to `rdfs.Resource`) is filed under the IMPORTED package's
|
|
36
|
+
* namespace by the open-world merge, so {@link getDocumentKanonaks} — which
|
|
37
|
+
* scopes by the document's own namespace — does not return it. This reads the
|
|
38
|
+
* parser's PRE-MERGE view (each subject + embedded stamped with its authoring
|
|
39
|
+
* `sourceDoc`) from the SAME single parse as {@link getCatalogKanonaks}, then
|
|
40
|
+
* keeps the subjects this document authored. Unlike a re-parse it preserves the
|
|
41
|
+
* ≤1-parse batch contract; unlike the merged catalog it does not lose a
|
|
42
|
+
* document's authored statements to cross-document de-duplication.
|
|
43
|
+
*
|
|
44
|
+
* Use this when a rule must validate what a document authored regardless of
|
|
45
|
+
* which namespace the merge files it under (e.g. an embedded `type:` on an
|
|
46
|
+
* augmentation). Resolution targets are still looked up against
|
|
47
|
+
* {@link getCatalogKanonaks}.
|
|
48
|
+
*/
|
|
49
|
+
export declare function getAuthoredKanonaks(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<Kanonak[]>;
|
|
32
50
|
/** A DefinedKanonak visited during a walk, with a human-facing locator path. */
|
|
33
51
|
export interface WalkNode {
|
|
34
52
|
readonly kanonak: DefinedKanonak;
|
|
@@ -46,3 +64,31 @@ export declare function walkDefinedKanonaks(roots: Kanonak[], visit: (node: Walk
|
|
|
46
64
|
/** `publisher/package@major.minor.patch` — matches `SubjectKanonak.namespace`
|
|
47
65
|
* and the parser's `sourceDoc`. Undefined for a document without a namespace. */
|
|
48
66
|
export declare function namespaceOf(document: KanonakDocument): string | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Cacheless catalog source: exposes the target document PLUS every other
|
|
69
|
+
* document in the backing repository through `getAllDocumentsAsync` (and
|
|
70
|
+
* delegates all resolution lookups to the backing repository). This lets the
|
|
71
|
+
* single-document parse see the whole import closure — so cross-package
|
|
72
|
+
* references resolve to real imported subjects, matching the cached (batch)
|
|
73
|
+
* path. The target document is listed first and any same-namespace copy in the
|
|
74
|
+
* repository is excluded, so the in-hand document stays authoritative for its
|
|
75
|
+
* own namespace even when an older copy was saved. Unlike
|
|
76
|
+
* `SingleDocumentRepository` (which exposes ONLY the target document, by
|
|
77
|
+
* design, for parsing one entity in isolation), this includes the closure
|
|
78
|
+
* precisely because validation existence checks need it.
|
|
79
|
+
*/
|
|
80
|
+
export declare class DocumentWithRepositoryCatalog implements IKanonakDocumentRepository {
|
|
81
|
+
private readonly document;
|
|
82
|
+
private readonly broader;
|
|
83
|
+
constructor(document: KanonakDocument, broader: IKanonakDocumentRepository);
|
|
84
|
+
getAllDocumentsAsync(): Promise<KanonakDocument[]>;
|
|
85
|
+
getDocumentAsync(identifier: string): Promise<KanonakDocument | null>;
|
|
86
|
+
getDocumentsByNamespaceAsync(publisher: string, package_: string): Promise<KanonakDocument[]>;
|
|
87
|
+
getHighestCompatibleVersionAsync(publisher: string, import_: Import): Promise<KanonakDocument | null>;
|
|
88
|
+
getAllDocumentReferencesAsync(): Promise<DocumentReference[]>;
|
|
89
|
+
getDocumentContentAsync(identifier: string): Promise<string | null>;
|
|
90
|
+
getDocumentUriAsync(identifier: string): Promise<string | null>;
|
|
91
|
+
saveDocumentAsync(): Promise<void>;
|
|
92
|
+
deleteDocumentAsync(): Promise<void>;
|
|
93
|
+
clearNamespaceAsync(): Promise<void>;
|
|
94
|
+
}
|
|
@@ -8,4 +8,4 @@ export { KanonakObjectValidator } from './KanonakObjectValidator.js';
|
|
|
8
8
|
export type { IDocumentValidationRule } from './rules/document/IDocumentValidationRule.js';
|
|
9
9
|
export type { IRepositoryValidationRule } from './rules/repository/IRepositoryValidationRule.js';
|
|
10
10
|
export { NamespacePrefixRule, ResourceNamingRule, PropertyTypeSpecificityRule, SubjectKanonakTypeRequiredRule, PackageHeaderRule } from './rules/document/index.js';
|
|
11
|
-
export { ImportExistenceRule, UnresolvedReferenceRule, ClassHierarchyCycleRule, PropertyHierarchyCycleRule, PropertyRangeRequiredRule, SubClassOfReferenceRule, SubPropertyOfReferenceRule, NamespaceImportCycleRule, UnresolvedPredicateRule,
|
|
11
|
+
export { ImportExistenceRule, UnresolvedReferenceRule, ClassHierarchyCycleRule, PropertyHierarchyCycleRule, PropertyRangeRequiredRule, SubClassOfReferenceRule, SubPropertyOfReferenceRule, NamespaceImportCycleRule, UnresolvedPredicateRule, AmbiguousReferenceRule, PropertyRangeReferenceRule, ObjectPropertyValueValidationRule, PropertyDomainRule, PropertyKindRangeConsistencyRule, ReservedNameShadowRule, ClassDefinitionRule, EmbeddedKanonakTypeRule, MarkdownLinkRule, DisplayLensScopeRule, LookSemanticSvgPathRule, TxExpressionPathRule, ShaclShapeRule, OwlOneOfRule, DiamondNameClashRule } from './rules/repository/index.js';
|
package/dist/validation/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A,B,C,D,E,F,G,
|
|
1
|
+
import{A,B,C,D,E,F,G,J as H,K as I,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-ZO5IUMX6.js";import"../chunk-MX3DEXMV.js";import"../chunk-NJ3AZYQD.js";import"../chunk-WFQANMBQ.js";import"../chunk-6U26UASC.js";import"../chunk-GZPLWII7.js";import"../chunk-7BHDZHJY.js";import"../chunk-FUUTGGJS.js";import"../chunk-2ACBWC7K.js";export{u as AmbiguousReferenceRule,A as ClassDefinitionRule,n as ClassHierarchyCycleRule,H as DiamondNameClashRule,C as DisplayLensScopeRule,k as EmbeddedKanonakTypeRule,l as ImportExistenceRule,I as KanonakObjectValidator,D as LookSemanticSvgPathRule,B as MarkdownLinkRule,s as NamespaceImportCycleRule,f as NamespacePrefixRule,w as ObjectPropertyValueValidationRule,c as OntologyValidationError,a as OntologyValidationResult,G as OwlOneOfRule,j as PackageHeaderRule,x as PropertyDomainRule,o as PropertyHierarchyCycleRule,y as PropertyKindRangeConsistencyRule,v as PropertyRangeReferenceRule,p as PropertyRangeRequiredRule,h as PropertyTypeSpecificityRule,z as ReservedNameShadowRule,g as ResourceNamingRule,F as ShaclShapeRule,q as SubClassOfReferenceRule,r as SubPropertyOfReferenceRule,i as SubjectKanonakTypeRequiredRule,E as TxExpressionPathRule,t as UnresolvedPredicateRule,m as UnresolvedReferenceRule,e as ValidationCache,d as ValidationContext,b as ValidationSeverity};
|
|
@@ -2,11 +2,26 @@ import type { KanonakDocument } from '@kanonak-protocol/types/document/models/ty
|
|
|
2
2
|
import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
|
|
3
3
|
import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
|
|
4
4
|
import { OntologyValidationError } from '../../OntologyValidationError.js';
|
|
5
|
+
import type { ValidationCache } from '../../ValidationCache.js';
|
|
6
|
+
/**
|
|
7
|
+
* Every `type` target — the class an entity is declared an instance of — must
|
|
8
|
+
* resolve to a class-like resource. A built-in meta-class (`Class`,
|
|
9
|
+
* `ObjectProperty`, `Datatype`, `Package`, …) is itself a `type: Class` subject
|
|
10
|
+
* in the core packages, so it resolves the same way as a user-defined class —
|
|
11
|
+
* no hardcoded built-in allow-list is needed, and a real typo (`type: Conatiner`)
|
|
12
|
+
* is correctly flagged regardless of how it was aliased.
|
|
13
|
+
*
|
|
14
|
+
* Reads the resolved object model recursively ({@link walkDefinedKanonaks}), so
|
|
15
|
+
* a bad `type` on an embedded kanonak at any depth is caught, not just on
|
|
16
|
+
* top-level subjects (the #65 gap). The `type` target parses to a
|
|
17
|
+
* `ReferenceKanonak` whose `subject` URI the parser canonicalizes; existence +
|
|
18
|
+
* class-ness are checked by `findSubjectByUri` + `ResourceTypeClassifier`, never
|
|
19
|
+
* by a built-in-name set or `split('.')` alias extraction. (`type` is the
|
|
20
|
+
* structural predicate this rule owns — `UnresolvedReferenceRule` skips it.)
|
|
21
|
+
*/
|
|
5
22
|
export declare class ClassDefinitionRule implements IRepositoryValidationRule {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
private
|
|
10
|
-
private isClassEntity;
|
|
11
|
-
private isDefinitionType;
|
|
23
|
+
readonly ruleName = "ClassDefinition";
|
|
24
|
+
validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
|
|
25
|
+
private resolvesToClassLike;
|
|
26
|
+
private error;
|
|
12
27
|
}
|
|
@@ -2,10 +2,15 @@ import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/documen
|
|
|
2
2
|
import type { KanonakDocument } from '@kanonak-protocol/types/document/models/types';
|
|
3
3
|
import { OntologyValidationError } from '../../OntologyValidationError.js';
|
|
4
4
|
import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
|
|
5
|
+
import type { ValidationCache } from '../../ValidationCache.js';
|
|
6
|
+
/**
|
|
7
|
+
* Detects a circular `subClassOf` hierarchy. Reads the resolved object model: the
|
|
8
|
+
* subClassOf graph is walked by canonical `KanonakUri` (resolved through the
|
|
9
|
+
* import closure) and compared by `uriKey` identity, so a cycle that closes
|
|
10
|
+
* across packages — where the same class is spelled with different aliases in
|
|
11
|
+
* each hop — is caught, where the old local-name hierarchy map would miss it.
|
|
12
|
+
*/
|
|
5
13
|
export declare class ClassHierarchyCycleRule implements IRepositoryValidationRule {
|
|
6
14
|
readonly ruleName = "ClassHierarchyCycle";
|
|
7
|
-
validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository): Promise<OntologyValidationError[]>;
|
|
8
|
-
private buildClassHierarchy;
|
|
9
|
-
private detectCycle;
|
|
10
|
-
private detectCycleRecursive;
|
|
15
|
+
validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
|
|
11
16
|
}
|
|
@@ -2,101 +2,40 @@ import type { KanonakDocument } from '@kanonak-protocol/types/document/models/ty
|
|
|
2
2
|
import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
|
|
3
3
|
import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
|
|
4
4
|
import { OntologyValidationError } from '../../OntologyValidationError.js';
|
|
5
|
+
import type { ValidationCache } from '../../ValidationCache.js';
|
|
5
6
|
/**
|
|
6
|
-
* Validates `type:`
|
|
7
|
+
* Validates an explicit `type:` on an embedded kanonak against the range of the
|
|
8
|
+
* parent property it is embedded under: the declared type must be the range
|
|
9
|
+
* itself (redundant — a Warning) or a `subClassOf` descendant of it (accepted),
|
|
10
|
+
* supporting discriminated-union modelling with real OWL semantics.
|
|
7
11
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* parent property
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* Reads the resolved object model, NOT raw `document.body`. The parser has
|
|
13
|
+
* already resolved every embedding predicate to its canonical property URI, so
|
|
14
|
+
* the parent property is known directly from the `EmbeddedStatement`/`ListStatement`
|
|
15
|
+
* predicate — collapsing the old local-name property-range map and its
|
|
16
|
+
* alias/parent-class disambiguation entirely. The subclass test is the single
|
|
17
|
+
* canonical `superClassChain` walk compared by `uriKey` identity, so a
|
|
18
|
+
* cross-package subclass resolves regardless of the alias spelling each document
|
|
19
|
+
* used (`fml.Expression` vs `Expression` both being `…/formula/Expression`) —
|
|
20
|
+
* fixing the string-comparison false-negative the old `isSubclassOfAsync` +
|
|
21
|
+
* local-name fallback produced (#65, comment 4). Coverage is recursive on
|
|
22
|
+
* embeddeds at any depth.
|
|
15
23
|
*
|
|
16
|
-
* -
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* - Non-subclass declarations error with a suggestion to either
|
|
21
|
-
* drop the type or add a matching `subClassOf:` to the declared
|
|
22
|
-
* class.
|
|
23
|
-
* - When the parent property has no `range:`, or the range is a
|
|
24
|
-
* "universal" class (`Resource`, `Class`), no constraint is
|
|
25
|
-
* enforced — every declared embedded type is accepted.
|
|
26
|
-
*
|
|
27
|
-
* Why this is a repository rule rather than a document rule: deciding
|
|
28
|
-
* whether `cp.OrCondition` is a subclass of `Condition` requires
|
|
29
|
-
* walking `subClassOf` across the importing document's transitive
|
|
30
|
-
* imports, which the document-only validator interface can't reach.
|
|
31
|
-
* The class hierarchy walk is delegated to
|
|
32
|
-
* `ResourceResolver.isSubclassOfAsync`, the same helper other
|
|
33
|
-
* range-aware rules already share.
|
|
24
|
+
* - A "universal" range (`rdfs.Resource`, `rdfs.Class`) imposes no constraint.
|
|
25
|
+
* - An embedded with no explicit `type:` is fine (the type is inferred).
|
|
26
|
+
* - An unresolved parent property or range is reported by the dedicated
|
|
27
|
+
* reference rules, not here.
|
|
34
28
|
*/
|
|
35
29
|
export declare class EmbeddedKanonakTypeRule implements IRepositoryValidationRule {
|
|
36
|
-
|
|
37
|
-
validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository): Promise<OntologyValidationError[]>;
|
|
38
|
-
/**
|
|
39
|
-
* Pick the right property-range candidate when multiple packages
|
|
40
|
-
* declare a property with the same local name (e.g. `tx.Not.operand`
|
|
41
|
-
* range `Expression` vs. `wv.NotCondition.operand` range `Condition`).
|
|
42
|
-
*
|
|
43
|
-
* Disambiguation strategy, in priority order:
|
|
44
|
-
*
|
|
45
|
-
* 1. If the property name as authored is alias-prefixed
|
|
46
|
-
* (`tx.operand`), match candidates whose declaring entity
|
|
47
|
-
* shares the same alias prefix. This is the unambiguous case
|
|
48
|
-
* most authors hit — the YAML key carries the disambiguator.
|
|
49
|
-
* 2. Otherwise, if the parent dict has a `type:` declaration,
|
|
50
|
-
* match candidates whose `domain` local-name equals the parent
|
|
51
|
-
* class's local-name. The embedded under `type: tx.Not` only
|
|
52
|
-
* reasonably refers to the `operand` property whose domain is
|
|
53
|
-
* `tx.Not` (kanonak-protocol/typescript#17).
|
|
54
|
-
* 3. Last resort: return the first candidate. Authors who hit this
|
|
55
|
-
* branch have a genuinely ambiguous shape — bare property name,
|
|
56
|
-
* no parent type, multiple matching properties — and the rule
|
|
57
|
-
* can't tell which they meant.
|
|
58
|
-
*/
|
|
59
|
-
private pickRange;
|
|
60
|
-
/**
|
|
61
|
-
* Recursively descend through a YAML dict, validating any `type:`
|
|
62
|
-
* declarations encountered at depth > 0 against the closest known
|
|
63
|
-
* parent-property range.
|
|
64
|
-
*
|
|
65
|
-
* `parentPropertyRange` flows down from the property under which
|
|
66
|
-
* this dict sits. Two cases preserve it correctly:
|
|
67
|
-
*
|
|
68
|
-
* 1. **Single embedded under a property** — keys here are the
|
|
69
|
-
* embedded's properties; we look up each key's own range and
|
|
70
|
-
* pass it down for the next level.
|
|
71
|
-
* 2. **Dict-keyed list of embeddeds** (e.g.
|
|
72
|
-
* `hasArgument: { foo: {...}, bar: {...} }`) — keys are labels
|
|
73
|
-
* rather than properties, so they resolve to no range. In that
|
|
74
|
-
* case we propagate the OUTER property's range through the
|
|
75
|
-
* label level so the embedded values still get checked.
|
|
76
|
-
*
|
|
77
|
-
* List items are handled identically: a list under property P
|
|
78
|
-
* means each item is an embedded under P, regardless of whether
|
|
79
|
-
* the list is positional (`- item`) or dict-keyed.
|
|
80
|
-
*/
|
|
81
|
-
private checkEmbeddedTypes;
|
|
82
|
-
private validateEmbeddedType;
|
|
83
|
-
private localName;
|
|
30
|
+
readonly ruleName = "EmbeddedKanonakType";
|
|
31
|
+
validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
|
|
84
32
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* property with the same local name (e.g. `tx.Not.operand` range
|
|
89
|
-
* `Expression` AND `wv.NotCondition.operand` range `Condition`).
|
|
90
|
-
*
|
|
91
|
-
* Pre-#17, this map collapsed candidates by overwriting each prior
|
|
92
|
-
* entry, so the last-loaded property won and silently shadowed the
|
|
93
|
-
* others. Now all candidates are kept; `pickRange` picks the right
|
|
94
|
-
* one at lookup time using alias-prefix and parent-class context.
|
|
95
|
-
*
|
|
96
|
-
* The local-name keying mirrors the lookup pattern in
|
|
97
|
-
* `checkEmbeddedTypes` (which uses `localName(propertyName)` for
|
|
98
|
-
* the lookup). Same convention as `PropertyValueTypeRule` and
|
|
99
|
-
* `ObjectPropertyValueValidationRule`.
|
|
33
|
+
* Descend a node's statements: every embedded object (single or list item) is
|
|
34
|
+
* checked against its embedding property's range, then recursed into so a
|
|
35
|
+
* deeper embedded is checked against ITS own embedding property.
|
|
100
36
|
*/
|
|
101
|
-
private
|
|
37
|
+
private walk;
|
|
38
|
+
private check;
|
|
39
|
+
private redundant;
|
|
40
|
+
private notSubclass;
|
|
102
41
|
}
|
|
@@ -2,11 +2,25 @@ import type { KanonakDocument } from '@kanonak-protocol/types/document/models/ty
|
|
|
2
2
|
import type { IKanonakDocumentRepository } from '@kanonak-protocol/types/document/models';
|
|
3
3
|
import type { IRepositoryValidationRule } from './IRepositoryValidationRule.js';
|
|
4
4
|
import { OntologyValidationError } from '../../OntologyValidationError.js';
|
|
5
|
+
import type { ValidationCache } from '../../ValidationCache.js';
|
|
6
|
+
/**
|
|
7
|
+
* When an ObjectProperty's range is a schema-level meta-class, a value that
|
|
8
|
+
* REFERENCES an entity must reference one of that nature — e.g. a property whose
|
|
9
|
+
* range is `rdfs.Class` must point at a class, not an instance. This is the
|
|
10
|
+
* named-reference analogue of {@link EmbeddedKanonakTypeRule} (which constrains
|
|
11
|
+
* the declared type of an EMBEDDED value against its property's range).
|
|
12
|
+
*
|
|
13
|
+
* Reads the resolved object model (recursive on embeddeds at any depth): the
|
|
14
|
+
* property and its range are canonical URIs, the referent's nature is decided by
|
|
15
|
+
* `ResourceTypeClassifier`, identity by `uriMatches` — never by local-name range
|
|
16
|
+
* matching. Ordinary (non-meta) ranges and unresolved references are out of
|
|
17
|
+
* scope here (the latter is owned by `UnresolvedReferenceRule`); value-shape
|
|
18
|
+
* (scalar-vs-reference) is enforced structurally by the parser.
|
|
19
|
+
*/
|
|
5
20
|
export declare class ObjectPropertyValueValidationRule implements IRepositoryValidationRule {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
private
|
|
10
|
-
private
|
|
11
|
-
private buildPropertyMetadataAsync;
|
|
21
|
+
readonly ruleName = "ObjectPropertyValue";
|
|
22
|
+
validateAsync(document: KanonakDocument, repository: IKanonakDocumentRepository, cache?: ValidationCache): Promise<OntologyValidationError[]>;
|
|
23
|
+
private walk;
|
|
24
|
+
private check;
|
|
25
|
+
private warn;
|
|
12
26
|
}
|