@kanonak-protocol/sdk 4.7.0 → 4.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +1 -1
- package/dist/chunk-MFQUKORC.js +2 -0
- package/dist/chunk-OOR5SVNQ.js +152 -0
- package/dist/{chunk-MPBNEKCQ.js → chunk-T63Q2PMS.js} +1 -1
- package/dist/index.js +1 -1
- package/dist/look/LookRenderer.d.ts +81 -0
- package/dist/look/index.d.ts +1 -1
- package/dist/repositories/PublisherConfig.d.ts +3 -0
- package/dist/repositories/browser.js +1 -1
- package/dist/repositories/index.js +1 -1
- package/dist/search/index.js +1 -1
- package/dist/server/assembleModel.d.ts +2 -0
- package/dist/server/index.d.ts +4 -2
- package/dist/server/index.js +65 -2
- package/dist/server/loadResourceModel.d.ts +5 -0
- package/dist/server/renderDiagnostics.d.ts +74 -0
- package/dist/server/renderStack.d.ts +40 -0
- package/dist/server/requestRouter.d.ts +6 -0
- package/dist/server/types.d.ts +26 -0
- package/dist/transformations/index.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-F26XWM5K.js +0 -2
- package/dist/chunk-XRXCYM3U.js +0 -148
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as Pn,b as wn,c as Sn,d as Cn,e as be}from"./chunk-RWEGPZ23.js";import{a as yr,c as Ce,e as He,h as ze,i as We,j as gr}from"./chunk-
|
|
1
|
+
import{a as Pn,b as wn,c as Sn,d as Cn,e as be}from"./chunk-RWEGPZ23.js";import{a as yr,c as Ce,e as He,h as ze,i as We,j as gr}from"./chunk-OOR5SVNQ.js";import{a as hn,b as kn,c as bn,d as W,e as G,f as l,g as hr}from"./chunk-KGWDV7FW.js";import{a as fr}from"./chunk-NV63IOB7.js";import"./chunk-QHABFCRC.js";import{a as zt,b as Wt,c as Gt,d as Jt,e as qt,f as en,g as tn,h as nn,i as rn}from"./chunk-T63Q2PMS.js";import{b as Yt,c as Zt,d as Qt}from"./chunk-MFQUKORC.js";import{a as Ht}from"./chunk-4NO7MHS7.js";import{a as En,b as xn,c as In,d as vn}from"./chunk-RYOZTXI7.js";import{a as Kn,b as Dn}from"./chunk-PEUTCG3B.js";import{a as jn}from"./chunk-PEJALHXK.js";import{a as Xt}from"./chunk-SC5M74NM.js";import{A as lr,B as ur,C as pr,D as dr,M as mr,a as Nn,b as Tn,c as Ln,d as _n,e as Un,f as Fn,g as Mn,h as Hn,i as zn,j as Wn,k as Gn,l as Jn,m as qn,n as Yn,o as Zn,p as Xn,q as Qn,r as er,s as tr,t as nr,u as rr,v as or,w as ar,x as ir,y as sr,z as cr}from"./chunk-IZRPJCQW.js";import"./chunk-SHDHMKMJ.js";import{a as y,b as C,c as sn,d as Fe,e as v,f as ke,g as fn,h as yn,i as $}from"./chunk-DSHPAWJQ.js";import{a as S}from"./chunk-NJ3AZYQD.js";import{a as gn,b as Pe,c as $n,d as h,e as An,f as Vn,g as Bn,h as On}from"./chunk-UK2OIPAB.js";import{f as z,k as j,l as we,m as Se,n as Me}from"./chunk-PBNVHBS3.js";import{b as cn,c as ln,d as K,e as un,f as pn,h as dn,j as mn}from"./chunk-VKTFLHCW.js";import{a as on,b as fe,c as f,d as p,e as an,f as ye,g as R,h as ge,i as he,j as E,k as x,l as I}from"./chunk-T3JR2SV6.js";import{a as H}from"./chunk-FUUTGGJS.js";import{a as Nt,b as me,c as M,d as Tt,e as k,f as Lt,g as _t,h as Ut,i as Ft,j as Mt}from"./chunk-2ACBWC7K.js";import{a as Rn}from"./chunk-ODIECDN7.js";import{VersionOperator as Ni}from"@kanonak-protocol/types/document/models/enums";import{existsSync as Or,readFileSync as Dr}from"fs";import{homedir as Nr}from"os";import{join as Tr}from"path";import{execFile as kr}from"child_process";import{promisify as br}from"util";var J=br(kr),q="kanonak",Y="/usr/bin/security",A=class{async get(e){let t=l(e);try{let{stdout:r}=await J(Y,["find-generic-password","-s",q,"-a",t,"-w"],{timeout:1e4});try{return JSON.parse(r.trim())}catch{throw new Error(`Stored credential for '${t}' is corrupted (not valid JSON).
|
|
2
2
|
Run 'kanonak logout ${t}' then 'kanonak login ${t}' to fix.`)}}catch(r){if(Ge(r,44))return null;throw new Error(`macOS Keychain read failed for '${t}': ${Z(r)}
|
|
3
3
|
The Keychain may be locked or inaccessible.
|
|
4
4
|
Try unlocking it via Keychain Access.app or running 'security unlock-keychain'.`)}}async store(e,t){let r=l(e),o=JSON.stringify(t);try{await J(Y,["add-generic-password","-s",q,"-a",r,"-U","-w",o],{timeout:1e4})}catch(a){throw new Error(`macOS Keychain write failed for '${r}': ${Z(a)}
|
|
@@ -37,6 +37,61 @@ export interface ResolvedLook {
|
|
|
37
37
|
/** The class in the hierarchy where the declaration was found. */
|
|
38
38
|
sourceClass: Uri;
|
|
39
39
|
}
|
|
40
|
+
/** Where one resolved `--kan-*` token value came from. */
|
|
41
|
+
export interface TokenProvenance {
|
|
42
|
+
/** The resolved token value. */
|
|
43
|
+
readonly value: string;
|
|
44
|
+
/** Namespace (`publisher/pkg@ver`) of the subject that declared it. */
|
|
45
|
+
readonly sourceNamespace: string;
|
|
46
|
+
/** Name of the declaring subject (the instance itself, a class, or `Resource`). */
|
|
47
|
+
readonly sourceName: string;
|
|
48
|
+
/** Which cascade level supplied it. */
|
|
49
|
+
readonly level: 'instance' | 'class' | 'resource-floor';
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The base stylesheet (everything after the `:root` token block) and where it
|
|
53
|
+
* came from — or, when absent, exactly why. The two failure modes are distinct
|
|
54
|
+
* because they have different fixes:
|
|
55
|
+
*
|
|
56
|
+
* - `no-look-styles-in-catalog`: no `look-styles` package reached the render
|
|
57
|
+
* catalog at all (not in workspace/cache, and the ambient fetch failed).
|
|
58
|
+
* Fix: install `kanonak.org/look-styles` into the cache of the machine/user
|
|
59
|
+
* running the render.
|
|
60
|
+
* - `content-property-unresolved`: a `base-stylesheet` asset IS in the catalog
|
|
61
|
+
* but its `site.content` property did not resolve (typically the package was
|
|
62
|
+
* cached without its imports block, so the property reference can't bind).
|
|
63
|
+
* Fix: re-install the package from its raw published source.
|
|
64
|
+
*/
|
|
65
|
+
export interface BaseStylesheetStatus {
|
|
66
|
+
/** The CSS text, when fully resolved. */
|
|
67
|
+
readonly css?: string;
|
|
68
|
+
/** Namespace (`publisher/look-styles@ver`) of the chosen asset. */
|
|
69
|
+
readonly sourceNamespace?: string;
|
|
70
|
+
/** Publisher's own look-styles, or the kanonak.org universal default. */
|
|
71
|
+
readonly scope?: 'publisher-override' | 'universal-default';
|
|
72
|
+
/** Why `css` is undefined. */
|
|
73
|
+
readonly problem?: 'no-look-styles-in-catalog' | 'content-property-unresolved';
|
|
74
|
+
/** Every `base-stylesheet` asset namespace considered (all versions found). */
|
|
75
|
+
readonly candidates: readonly string[];
|
|
76
|
+
}
|
|
77
|
+
/** The full structured explanation behind one resource's rendered stylesheet. */
|
|
78
|
+
export interface StylesheetExplanation {
|
|
79
|
+
/** The resource being explained. */
|
|
80
|
+
readonly resource: {
|
|
81
|
+
readonly namespace: string;
|
|
82
|
+
readonly name: string;
|
|
83
|
+
};
|
|
84
|
+
/** Each `:root` `--kan-*` token and where it cascaded from. */
|
|
85
|
+
readonly tokens: ReadonlyMap<string, TokenProvenance>;
|
|
86
|
+
/** The base stylesheet status (everything after `:root`). */
|
|
87
|
+
readonly baseStylesheet: BaseStylesheetStatus;
|
|
88
|
+
/** The look (band declaration) styling the HTML body, when one resolves. */
|
|
89
|
+
readonly look?: {
|
|
90
|
+
readonly sourceClass: Uri;
|
|
91
|
+
};
|
|
92
|
+
/** Human-readable warnings: condition, consequence, and fix. */
|
|
93
|
+
readonly warnings: readonly string[];
|
|
94
|
+
}
|
|
40
95
|
export declare class LookRenderer {
|
|
41
96
|
private readonly catalog;
|
|
42
97
|
constructor(catalog: Kanonak[]);
|
|
@@ -110,6 +165,15 @@ export declare class LookRenderer {
|
|
|
110
165
|
* full URI), assumed globally unique by convention.
|
|
111
166
|
*/
|
|
112
167
|
findCascadedTokens(instance: SubjectKanonak): Map<string, string>;
|
|
168
|
+
/**
|
|
169
|
+
* The token cascade with provenance: same walk as
|
|
170
|
+
* {@link findCascadedTokens} (which delegates here — ONE cascade
|
|
171
|
+
* implementation), but each resolved token records WHICH subject declared
|
|
172
|
+
* it and at which cascade level. This is what makes the `:root` block
|
|
173
|
+
* explainable instead of magic: the CSS provenance header, the serve
|
|
174
|
+
* diagnostics endpoint, and startup logging all read from this.
|
|
175
|
+
*/
|
|
176
|
+
explainCascadedTokens(instance: SubjectKanonak): Map<string, TokenProvenance>;
|
|
113
177
|
/**
|
|
114
178
|
* Render the stylesheet for an instance — a CSS string with the
|
|
115
179
|
* cascaded tokens as `--kan-*` custom properties on `:root`, plus
|
|
@@ -197,6 +261,15 @@ export declare class LookRenderer {
|
|
|
197
261
|
*/
|
|
198
262
|
private collectCascadedSvgTiers;
|
|
199
263
|
renderStylesheet(instance: SubjectKanonak): string;
|
|
264
|
+
/**
|
|
265
|
+
* The full structured explanation behind {@link renderStylesheet}'s output
|
|
266
|
+
* for one resource: every token with its cascade source, the base
|
|
267
|
+
* stylesheet's provenance (or the precise reason it's missing), the look
|
|
268
|
+
* that styles the body, and derived warnings. `renderStylesheet` is a pure
|
|
269
|
+
* formatting of this — so what the page gets and what the diagnostics say
|
|
270
|
+
* can never disagree.
|
|
271
|
+
*/
|
|
272
|
+
explainStylesheet(instance: SubjectKanonak): StylesheetExplanation;
|
|
200
273
|
/**
|
|
201
274
|
* Find the publisher-appropriate `base-stylesheet` Asset in the catalog
|
|
202
275
|
* and return its CSS content. Prefers an Asset published by
|
|
@@ -206,6 +279,14 @@ export declare class LookRenderer {
|
|
|
206
279
|
* to an empty string and emit only the token cascade.
|
|
207
280
|
*/
|
|
208
281
|
private findBaseStylesheet;
|
|
282
|
+
/**
|
|
283
|
+
* The base-stylesheet lookup with provenance: same selection as
|
|
284
|
+
* {@link findBaseStylesheet} (which delegates here — ONE lookup
|
|
285
|
+
* implementation), but reporting WHICH asset was chosen, which were
|
|
286
|
+
* considered, and — when nothing usable was found — exactly why, so the
|
|
287
|
+
* "CSS stops at :root" failure mode is diagnosable instead of silent.
|
|
288
|
+
*/
|
|
289
|
+
explainBaseStylesheet(contextPublisher: string): BaseStylesheetStatus;
|
|
209
290
|
/**
|
|
210
291
|
* Render the instance as body-only HTML using its cascaded look.
|
|
211
292
|
*/
|
package/dist/look/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { LookRenderer, type ResolvedLook } from './LookRenderer.js';
|
|
1
|
+
export { LookRenderer, type ResolvedLook, type TokenProvenance, type BaseStylesheetStatus, type StylesheetExplanation, } from './LookRenderer.js';
|
|
2
2
|
export { resolveDisplayValue, type DisplayValue } from './displayValue.js';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AuthenticatedFetchFn } from '../auth/index.js';
|
|
1
2
|
export interface PublisherConfig {
|
|
2
3
|
version: number;
|
|
3
4
|
index?: string;
|
|
@@ -43,7 +44,9 @@ export interface PublisherConfig {
|
|
|
43
44
|
*/
|
|
44
45
|
export declare function defaultPublisherConfig(publisher: string): PublisherConfig;
|
|
45
46
|
export declare class PublisherConfigResolver {
|
|
47
|
+
private readonly fetchFn?;
|
|
46
48
|
private readonly cache;
|
|
49
|
+
constructor(fetchFn?: AuthenticatedFetchFn | undefined);
|
|
47
50
|
getConfig(publisher: string): Promise<PublisherConfig>;
|
|
48
51
|
private fetchConfig;
|
|
49
52
|
resolveIndexUrl(publisher: string, config: PublisherConfig): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as e,c as r,d as n}from"../chunk-
|
|
1
|
+
import{b as e,c as r,d as n}from"../chunk-MFQUKORC.js";import{a as o}from"../chunk-4NO7MHS7.js";import"../chunk-SC5M74NM.js";import"../chunk-NJ3AZYQD.js";import"../chunk-2ACBWC7K.js";export{n as HttpKanonakDocumentRepository,o as InMemoryKanonakDocumentRepository,e as PublisherConfigResolver,r as PublisherIndex};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as b,b as c,c as d,d as e,e as f,f as k,g as l,h as m,i as n}from"../chunk-
|
|
1
|
+
import{a as b,b as c,c as d,d as e,e as f,f as k,g as l,h as m,i as n}from"../chunk-T63Q2PMS.js";import{a as g,b as h,c as i,d as j}from"../chunk-MFQUKORC.js";import{a}from"../chunk-4NO7MHS7.js";import"../chunk-SC5M74NM.js";import"../chunk-NJ3AZYQD.js";import"../chunk-2ACBWC7K.js";export{d as CompositeKanonakDocumentRepository,c as DocumentLocation,b as FileSystemKanonakDocumentRepository,j as HttpKanonakDocumentRepository,a as InMemoryKanonakDocumentRepository,k as LocalFirstRepository,l as LockAwareRepository,h as PublisherConfigResolver,i as PublisherIndex,f as RepositoryFactory,n as buildLocalFirstRepository,m as collectKanonakFiles,g as defaultPublisherConfig,e as getGlobalCachePath};
|
package/dist/search/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as g}from"../chunk-
|
|
1
|
+
import{a as g}from"../chunk-OOR5SVNQ.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-DSHPAWJQ.js";import"../chunk-NJ3AZYQD.js";import{d as m,h as S}from"../chunk-UK2OIPAB.js";import{a as p,f as E}from"../chunk-PBNVHBS3.js";import"../chunk-VKTFLHCW.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+`
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Kanonak } from '../kanonaks/index.js';
|
|
2
2
|
import type { LookRenderer } from '../look/index.js';
|
|
3
3
|
import type { IPackageProducer } from '../producer/index.js';
|
|
4
|
+
import type { RenderStackReport } from './renderStack.js';
|
|
4
5
|
import type { ServerModel } from './types.js';
|
|
5
6
|
/**
|
|
6
7
|
* Build the route-facing indexes for a {@link ServerModel} from an already-built
|
|
@@ -19,5 +20,6 @@ export declare function assembleServerModel(params: {
|
|
|
19
20
|
lookRenderer: LookRenderer;
|
|
20
21
|
localNamespaces: Set<string>;
|
|
21
22
|
rawByNsKey: Map<string, string>;
|
|
23
|
+
renderStack: RenderStackReport;
|
|
22
24
|
producers?: readonly IPackageProducer[];
|
|
23
25
|
}): ServerModel;
|
package/dist/server/index.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export { route } from './route.js';
|
|
|
5
5
|
export { RequestRouter, landingPage } from './requestRouter.js';
|
|
6
6
|
export type { RequestRouterOptions } from './requestRouter.js';
|
|
7
7
|
export { deriveImportClosure, ClosureScopedRepository } from './closure.js';
|
|
8
|
-
export { UNIVERSAL_RENDER_BASE, resolveRenderContract, renderRefKey, } from './renderStack.js';
|
|
9
|
-
export type { RenderPackageRef } from './renderStack.js';
|
|
8
|
+
export { UNIVERSAL_RENDER_BASE, resolveRenderContract, renderRefKey, buildRenderStackWarnings, } from './renderStack.js';
|
|
9
|
+
export type { RenderPackageRef, RenderPackageStatus, RenderStackReport, } from './renderStack.js';
|
|
10
|
+
export { buildRenderDiagnostics, renderDiagnosticsHtml } from './renderDiagnostics.js';
|
|
11
|
+
export type { RenderDiagnostics } from './renderDiagnostics.js';
|
|
10
12
|
export type { ServerModel, RouteResponse, LoadServerModelOptions, PackageVersion, } from './types.js';
|
package/dist/server/index.js
CHANGED
|
@@ -1,3 +1,66 @@
|
|
|
1
|
-
import{j as E}from"../chunk-XRXCYM3U.js";import"../chunk-QHABFCRC.js";import{a as Z,d as A,f as te,h as N}from"../chunk-MPBNEKCQ.js";import{a as ee,b as re,c as V,d as I}from"../chunk-F26XWM5K.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-DSHPAWJQ.js";import{a as D}from"../chunk-NJ3AZYQD.js";import{b as O}from"../chunk-UK2OIPAB.js";import"../chunk-PBNVHBS3.js";import"../chunk-VKTFLHCW.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(`
|
|
1
|
+
import{j as ee}from"../chunk-OOR5SVNQ.js";import"../chunk-QHABFCRC.js";import{a as he,d as z,f as ke,h as J}from"../chunk-T63Q2PMS.js";import{a as me,b as fe,c as O,d as Y}from"../chunk-MFQUKORC.js";import{a as ge}from"../chunk-4NO7MHS7.js";import"../chunk-PEUTCG3B.js";import{a as be}from"../chunk-PEJALHXK.js";import"../chunk-SC5M74NM.js";import"../chunk-SHDHMKMJ.js";import{i as Q}from"../chunk-DSHPAWJQ.js";import{a as E}from"../chunk-NJ3AZYQD.js";import{b as X}from"../chunk-UK2OIPAB.js";import{g as Z}from"../chunk-PBNVHBS3.js";import"../chunk-VKTFLHCW.js";import{c as ye}from"../chunk-T3JR2SV6.js";import"../chunk-FUUTGGJS.js";import{c as M,e as F,f as L,g as ue}from"../chunk-2ACBWC7K.js";import{readFileSync as Pe,writeFileSync as De,mkdirSync as _e}from"fs";import{join as we}from"path";function ve(t){let e=t.metadata?.namespace_;return e?`${e.publisher}/${e.package_}`:void 0}async function H(t,e){let n=new Set,r=[...t];for(;r.length>0;){let s=r.shift(),a=ve(s);if(!a||n.has(a))continue;n.add(a);let m=s.metadata?.imports;if(m)for(let[p,k]of Object.entries(m))for(let d of k)try{let u=await e.getHighestCompatibleVersionAsync(p,d);u&&r.push(u)}catch{}}return n}var V=class{constructor(e,n){this.inner=e;this.scope=n}inner;scope;async getAllDocumentsAsync(){return(await this.inner.getAllDocumentsAsync()).filter(n=>{let r=ve(n);return r!==void 0&&this.scope.has(r)})}getDocumentAsync(e){return this.inner.getDocumentAsync(e)}getDocumentsByNamespaceAsync(e,n){return this.inner.getDocumentsByNamespaceAsync(e,n)}getHighestCompatibleVersionAsync(e,n){return this.inner.getHighestCompatibleVersionAsync(e,n)}saveDocumentAsync(e,n){return this.inner.saveDocumentAsync(e,n)}deleteDocumentAsync(e){return this.inner.deleteDocumentAsync(e)}clearNamespaceAsync(e,n){return this.inner.clearNamespaceAsync(e,n)}getAllDocumentReferencesAsync(){return this.inner.getAllDocumentReferencesAsync()}getDocumentContentAsync(e){return this.inner.getDocumentContentAsync(e)}getDocumentUriAsync(e){return this.inner.getDocumentUriAsync(e)}};var Se=[{publisher:"kanonak.org",package_:"core-kanonak"},{publisher:"kanonak.org",package_:"site"},{publisher:"kanonak.org",package_:"link"},{publisher:"kanonak.org",package_:"look-tokens"},{publisher:"kanonak.org",package_:"look-styles"},{publisher:"kanonak.org",package_:"look"},{publisher:"kanonak.org",package_:"universal-look"}];function T(t){let e=t?.render;if(e&&e.length>0){let n=[];for(let r of e)try{let s=X(r);s.kind==="package"?n.push({publisher:s.publisher,package_:s.package_}):s.kind==="resource"&&n.push({publisher:s.uri.publisher,package_:s.uri.package_})}catch{}if(n.length>0)return n}return Se}function C(t){return`${t.publisher}/${t.package_}`}function W(t){let e={"kanonak.org/look-styles":"pages render UNSTYLED \u2014 generated CSS stops at the :root token block","kanonak.org/look-tokens":"the :root block loses the universal design-token floor (colors, fonts, spacing)","kanonak.org/universal-look":"resources without their own look render as an empty HTML comment","kanonak.org/look":"band vocabulary (Hero, PropertyList, \u2026) is unresolvable \u2014 declared looks cannot render","kanonak.org/site":"the site vocabulary (content, navigation) is unresolvable \u2014 the base stylesheet cannot bind","kanonak.org/core-kanonak":"the Package/Publisher classes are unresolvable \u2014 package and publisher pages degrade","kanonak.org/link":"link vocabulary is unresolvable \u2014 cross-reference styling degrades"},n=[];for(let r of t)if(r.origin==="missing"){let s=C(r),a=e[s]??"whatever this package contributes to rendering is lost";n.push(`Render-stack package ${s} is MISSING (${r.reason??"unknown reason"}) \u2014 ${a}. Fix: kanonak install ${s} (as the user running the render), or restore network access to ${r.publisher}.`)}else r.resolvedButNotInCatalog&&n.push(`Render-stack package ${C(r)} resolved (${r.origin}) but is NOT in the parsed catalog \u2014 this is a closure-scoping bug; please report it.`);return n}function re(t){let{publisher:e,availablePublishers:n,catalog:r,lookRenderer:s,localNamespaces:a,rawByNsKey:m,renderStack:p,producers:k}=t,d=new Map,u=new Map,o=new Map,h=new Set;for(let y of r){if(!(y instanceof ye))continue;let b=y.namespace||"";if(!a.has(b))continue;d.set(`${b}/${y.name}`,y);let $=b.split("/")[1]??"",[w,_]=$.split("@");if(!w||!_)continue;let I=ue(_);I&&(h.has($)||(h.add($),u.has(w)||u.set(w,[]),u.get(w).push({verStr:_,version:I})),y.name===w&&o.set($,y))}for(let y of u.values())y.sort((b,$)=>M($.version,b.version));return{publisher:e,availablePublishers:n,catalog:r,lookRenderer:s,localNamespaces:a,rawByNsKey:m,bySubject:d,pkgVersions:u,pkgSelfByVer:o,renderStack:p,...k?{producers:k}:{}}}async function se(t,e={}){let n=new E,r=new ge(n),s=[],a=[];for(let c of J(t)){let l;try{l=Pe(c,"utf-8")}catch{continue}let v;try{v=n.parse(l).metadata?.namespace_}catch{continue}if(!v?.version)continue;let N=v.version;a.push({publisher:v.publisher,package_:v.package_,verStr:F(N),version:N,source:l})}a.sort((c,l)=>M(l.version,c.version));for(let c of a)await r.saveDocumentAsync(n.parse(c.source),`${c.publisher}/${c.package_}@${c.verStr}`),s.push({publisher:c.publisher,package_:c.package_,verStr:c.verStr,source:c.source});let m=[...new Set(s.map(c=>c.publisher))].sort(),p=e.publisher;if(p){if(!m.includes(p))throw new Error(`Publisher "${p}" not found in workspace. Available: ${m.join(", ")||"(none)"}`)}else if(m.length===1)p=m[0];else throw m.length===0?new Error(`No Kanonak packages found under ${t}`):new Error(`Workspace has multiple publishers (${m.join(", ")}). Pass --publisher <domain> to choose which one to serve.`);let k=new Set,d=new Map;for(let c of s)c.publisher===p&&(k.add(`${c.publisher}/${c.package_}@${c.verStr}`),d.set(`${c.package_}@${c.verStr}`,c.source));let u=z(),o=new he(u,!0,n),h={};e.httpCache&&(h.getFromCache=e.httpCache.getFromCache,h.onFetch=e.httpCache.onFetch),e.fetchFn&&(h.fetchFn=e.fetchFn);let y=e.repository??new ke(r,o,new Y(h)),b=e.log??(()=>{}),$=T(void 0),w=[],_=c=>c.map(l=>l.metadata.namespace_?.version).filter(l=>l!==void 0).sort((l,v)=>M(v,l)).map(F);if(!e.repository){b(`[render-stack] resolving ${$.length} ambient look-stack package(s); cache: ${u}`);let c=e.fetchFn?new O({fetchFn:e.fetchFn}):new O;for(let l of $){let v=C(l),N=await r.getDocumentsByNamespaceAsync(l.publisher,l.package_);if(N.length>0){let S=_(N);w.push({...l,origin:"workspace",versions:S}),b(`[render-stack] ${v} \u2014 workspace (${S.join(", ")})`);continue}let U=await o.getDocumentsByNamespaceAsync(l.publisher,l.package_);if(U.length>0){let S=_(U);w.push({...l,origin:"cache",versions:S}),b(`[render-stack] ${v} \u2014 cache (${S.join(", ")})`);continue}try{let S=await c.getHighestVersion(l.publisher,l.package_);if(!S){let f=`publisher ${l.publisher} reachable but its index does not list ${l.package_}`;w.push({...l,origin:"missing",reason:f}),b(`[render-stack] ${v} \u2014 MISSING: ${f}`);continue}let j=await c.getPackageUrl(l.publisher,l.package_,S),i=await(e.fetchFn?e.fetchFn(j,l.publisher):fetch(j));if(!i.ok){let f=`fetch ${j} failed: HTTP ${i.status} ${i.statusText}`;w.push({...l,origin:"missing",reason:f}),b(`[render-stack] ${v} \u2014 MISSING: ${f}`);continue}let g=await i.text();await r.saveDocumentAsync(n.parse(g),`${l.publisher}/${l.package_}@${S}`);try{let f=we(u,l.publisher);_e(f,{recursive:!0}),De(we(f,`${l.package_}@${S}.kan.yml`),g,"utf-8"),w.push({...l,origin:"fetched",versions:[S]}),b(`[render-stack] ${v}@${S} \u2014 fetched from ${j}, installed to cache`)}catch(f){w.push({...l,origin:"fetched",versions:[S]}),b(`[render-stack] ${v}@${S} \u2014 fetched from ${j}, but cache ${u} is NOT WRITABLE (${f.message}); usable for this load only \u2014 every load will re-fetch it`)}}catch(S){let j=`fetch failed: ${S.message}`;w.push({...l,origin:"missing",reason:j}),b(`[render-stack] ${v} \u2014 MISSING: ${j}`)}}}let I=y;if(!e.repository){let c=(await r.getAllDocumentsAsync()).filter(v=>v.metadata.namespace_?.publisher===p),l=await H(c,y);for(let v of $)l.add(C(v));I=new V(y,l)}let B=await new Q(n).parseKanonaks(I),oe=new ee(B),G=(c,l)=>Z(B,{publisher:c,package_:l,name:l}).length>0,A;if(e.repository){A=[];for(let c of $){let l=await y.getDocumentsByNamespaceAsync(c.publisher,c.package_);A.push(l.length>0?{...c,origin:"repository",versions:_(l)}:{...c,origin:"missing",reason:"not present in the caller-supplied repository"})}}else A=w.map(c=>c.origin==="missing"||G(c.publisher,c.package_)?c:{...c,resolvedButNotInCatalog:!0});let q=W(A);for(let c of q)b(`[render-stack] WARNING: ${c}`);return re({publisher:p,availablePublishers:m,catalog:B,lookRenderer:oe,localNamespaces:k,rawByNsKey:d,renderStack:{contractSource:"universal-default",cachePath:u,packages:A,warnings:q}})}import{existsSync as je,readFileSync as Ce,writeFileSync as Ae,mkdirSync as Ie}from"fs";import{join as $e}from"path";async function ae(t,e={}){let n=new E,r=X(t),s=r.kind==="resource"?r.uri.publisher:r.publisher,a=e.log??(()=>{}),m=e.cacheRoot??z(),p=(i,g,f)=>$e(m,i,`${g}@${f}.kan.yml`),k=new Set,d=new Set,u=new Map,o=new Y({getFromCache:(i,g,f)=>{let D=p(i,g,f),R=je(D)?Ce(D,"utf-8"):null;return R!==null&&k.add(`${i}/${g}`),R},onFetch:(i,g,f,D)=>{d.add(`${i}/${g}`);try{let R=$e(m,i);Ie(R,{recursive:!0}),Ae(p(i,g,f),D,"utf-8")}catch(R){u.set(`${i}/${g}`,R.message),a(`[render] fetched ${i}/${g}@${f} but cache ${m} is NOT WRITABLE (${R.message}); usable for this load only \u2014 every load will re-fetch it`)}},...e.fetchFn?{fetchFn:e.fetchFn}:{}}),h=new O(e.fetchFn?{fetchFn:e.fetchFn}:void 0),y;if(r.kind==="resource"){let i=r.uri.version;y=[i?{package_:r.uri.package_,version:`${i.major}.${i.minor}.${i.patch}`}:{package_:r.uri.package_}]}else if(r.kind==="package"){let i=r.version;y=[i?{package_:r.package_,version:`${i.major}.${i.minor}.${i.patch}`}:{package_:r.package_}]}else y=(await h.listLatestPackages(s)).map(g=>({package_:g.packageName}));let b=async(i,g,f)=>{try{let D=f?n.buildImport(g,"=",f,i):n.buildImport(g,"*","0.0.0",i),R=await o.getHighestCompatibleVersionAsync(i,D);return R?{doc:R}:{doc:null,error:`${i} did not resolve ${g}${f?`@${f}`:""} (not in its index, or unreachable)`}}catch(D){return{doc:null,error:D.message}}},$=[],w=[];for(let i of y){let{doc:g,error:f}=await b(s,i.package_,i.version);g?$.push(g):f&&w.push(f)}if($.length===0)throw new Error(`Could not fetch any package for address "${t}" from publisher "${s}".`+(w.length>0?` Reasons: ${w.join("; ")}`:""));let _=await new fe(e.fetchFn).getConfig(s).catch(()=>{}),I=T(_),B=_?.render&&_.render.length>0?"publisher-well-known":"universal-default",oe=i=>i.map(g=>g.metadata.namespace_?.version).filter(g=>g!==void 0).sort((g,f)=>M(f,g)).map(F);a(`[render-stack] resolving ${I.length} ambient look-stack package(s) (contract: ${B}); cache: ${m}`);let G=[],A=[];for(let i of I){let g=C(i),{doc:f,error:D}=await b(i.publisher,i.package_,void 0);if(f){G.push(f);let R=oe([f]),pe=d.has(g)?"fetched":k.has(g)?"cache":"fetched";A.push({...i,origin:pe,versions:R}),a(`[render-stack] ${g} \u2014 ${pe} (${R.join(", ")})`+(u.has(g)?" [cache write FAILED \u2014 will re-fetch next load]":""))}else A.push({...i,origin:"missing",reason:D??"unresolved"}),a(`[render-stack] ${g} \u2014 MISSING: ${D??"unresolved"}`)}let q=await H([...$,...G],o),de=new V(o,q),c=await new Q(n).parseKanonaks(de),l=new ee(c),v=A.map(i=>i.origin==="missing"||Z(c,{publisher:i.publisher,package_:i.package_,name:i.package_}).length>0?i:{...i,resolvedButNotInCatalog:!0}),N=W(v);for(let i of N)a(`[render-stack] WARNING: ${i}`);let U={contractSource:B,cachePath:m,packages:v,warnings:N},S=new Set,j=new Map;for(let i of await o.getAllDocumentsAsync()){let g=i.metadata.namespace_;if(!g?.version||g.publisher!==s)continue;let f=F(g.version),D=`${g.publisher}/${g.package_}@${f}`;S.add(D);let R=await o.getDocumentContentAsync(D);R!==null&&j.set(`${g.package_}@${f}`,R)}return re({publisher:s,availablePublishers:[s],catalog:c,lookRenderer:l,localNamespaces:S,rawByNsKey:j,renderStack:U})}import{VersionOperator as ne}from"@kanonak-protocol/types/document/models/enums";function te(t){let{lookRenderer:e,publisher:n,renderStack:r,catalog:s}=t,a=e.explainStylesheet(e.publisherSubject(n)),m=[...a.tokens.entries()].map(([o,h])=>({name:o,value:h.value,source:`${h.sourceNamespace}/${h.sourceName}`,level:h.level})),p=a.baseStylesheet,k={present:p.css!==void 0,...p.sourceNamespace!==void 0?{source:p.sourceNamespace}:{},...p.scope!==void 0?{scope:p.scope}:{},...p.css!==void 0?{bytes:p.css.length}:{},...p.problem!==void 0?{problem:p.problem}:{},candidates:p.candidates},d=new Map;for(let o of s){let h=o.namespace;h&&d.set(h,(d.get(h)??0)+1)}let u=[...d.entries()].map(([o,h])=>({namespace:o,resources:h})).sort((o,h)=>o.namespace.localeCompare(h.namespace));return{publisher:n,renderStack:{contractSource:r.contractSource,cachePath:r.cachePath,packages:r.packages.map(o=>({package_:C(o),origin:o.origin,...o.versions!==void 0?{versions:o.versions}:{},...o.reason!==void 0?{reason:o.reason}:{},...o.resolvedButNotInCatalog!==void 0?{resolvedButNotInCatalog:o.resolvedButNotInCatalog}:{}}))},stylesheet:{tokens:m,baseStylesheet:k,...a.look?{look:{sourceClass:`${a.look.sourceClass.publisher}/${a.look.sourceClass.package_}/${a.look.sourceClass.name}`}}:{}},catalog:u,warnings:[...r.warnings,...a.warnings.filter(o=>!r.warnings.includes(o))]}}function Ne(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function ie(t){let e=Ne,n=t.warnings.length===0,r=t.warnings.length===0?'<p class="ok">\u2713 No problems detected \u2014 the render stack is fully resolved and pages should be styled.</p>':t.warnings.map(d=>`<div class="warn">\u26A0 ${e(d)}</div>`).join(`
|
|
2
|
+
`),s=t.renderStack.packages.map(d=>{let u=d.origin!=="missing"&&!d.resolvedButNotInCatalog,o=d.origin==="missing"?'<span class="bad">MISSING</span>':d.resolvedButNotInCatalog?`<span class="bad">${e(d.origin)} (not in catalog)</span>`:`<span class="good">${e(d.origin)}</span>`,h=d.reason?e(d.reason):e((d.versions??[]).join(", "));return`<tr class="${u?"":"row-bad"}"><td><code>${e(d.package_)}</code></td><td>${o}</td><td>${h}</td></tr>`}).join(`
|
|
3
|
+
`),a=t.stylesheet.baseStylesheet,m=a.present?`<p><span class="good">\u2713 present</span> \u2014 <code>${e(a.source??"")}</code> (${a.bytes} bytes, ${e(a.scope??"")})</p>`:`<p><span class="bad">\u2717 MISSING</span>${a.problem?` \u2014 ${e(a.problem)}`:""}${a.candidates.length>0?`<br>candidates considered: ${a.candidates.map(d=>`<code>${e(d)}</code>`).join(", ")}`:""}</p><p>Without the base stylesheet, generated CSS stops at the <code>:root</code> token block and pages appear unstyled.</p>`,p=t.stylesheet.tokens.map(d=>`<tr><td><code>--kan-${e(d.name)}</code></td><td><code>${e(d.value)}</code></td><td><code>${e(d.source)}</code></td><td>${e(d.level)}</td></tr>`).join(`
|
|
4
|
+
`),k=t.catalog.map(d=>`<tr><td><code>${e(d.namespace)}</code></td><td>${d.resources}</td></tr>`).join(`
|
|
5
|
+
`);return`<!doctype html>
|
|
6
|
+
<html lang="en">
|
|
7
|
+
<head>
|
|
8
|
+
<meta charset="utf-8">
|
|
9
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
10
|
+
<title>Render diagnostics \u2014 ${e(t.publisher)}</title>
|
|
11
|
+
<style>
|
|
12
|
+
body { font-family: system-ui, sans-serif; max-width: 64rem; margin: 2rem auto; padding: 0 1rem; line-height: 1.5; color: #1a1a1a; background: #fff; }
|
|
13
|
+
h1 { font-size: 1.5rem; } h2 { font-size: 1.15rem; margin-top: 2rem; border-bottom: 1px solid #ddd; padding-bottom: .25rem; }
|
|
14
|
+
table { border-collapse: collapse; width: 100%; font-size: .9rem; }
|
|
15
|
+
th, td { text-align: left; padding: .35rem .6rem; border-bottom: 1px solid #eee; vertical-align: top; }
|
|
16
|
+
th { background: #f6f6f6; }
|
|
17
|
+
code { background: #f3f3f3; padding: 0 .25rem; border-radius: 3px; font-size: .85em; }
|
|
18
|
+
.good { color: #0a7d33; font-weight: 600; } .bad { color: #b91c1c; font-weight: 600; }
|
|
19
|
+
.ok { background: #ecfdf3; border: 1px solid #0a7d33; padding: .75rem 1rem; border-radius: 6px; }
|
|
20
|
+
.warn { background: #fef2f2; border: 1px solid #b91c1c; padding: .75rem 1rem; border-radius: 6px; margin-bottom: .5rem; white-space: pre-wrap; }
|
|
21
|
+
.row-bad td { background: #fff5f5; }
|
|
22
|
+
.meta { color: #666; font-size: .85rem; }
|
|
23
|
+
.status-banner { font-size: 1.1rem; padding: .5rem 1rem; border-radius: 6px; display: inline-block; margin-bottom: 1rem;
|
|
24
|
+
background: ${n?"#ecfdf3":"#fef2f2"}; border: 1px solid ${n?"#0a7d33":"#b91c1c"}; }
|
|
25
|
+
</style>
|
|
26
|
+
</head>
|
|
27
|
+
<body>
|
|
28
|
+
<h1>Render diagnostics \u2014 ${e(t.publisher)}</h1>
|
|
29
|
+
<p class="status-banner">${n?"\u2713 Healthy":`\u2717 ${t.warnings.length} problem(s) found`}</p>
|
|
30
|
+
<p class="meta">Machine-readable version: <a href="/.well-known/kanonak-render.json"><code>/.well-known/kanonak-render.json</code></a></p>
|
|
31
|
+
|
|
32
|
+
<h2>Problems</h2>
|
|
33
|
+
${r}
|
|
34
|
+
|
|
35
|
+
<h2>Ambient render stack</h2>
|
|
36
|
+
<p class="meta">The look stack is discovered, not imported \u2014 these packages must be resolvable for any publisher's pages to render styled.
|
|
37
|
+
Contract: <code>${e(t.renderStack.contractSource)}</code> \xB7 Package cache: <code>${e(t.renderStack.cachePath)}</code></p>
|
|
38
|
+
<table>
|
|
39
|
+
<tr><th>Package</th><th>Origin</th><th>Versions / reason</th></tr>
|
|
40
|
+
${s}
|
|
41
|
+
</table>
|
|
42
|
+
|
|
43
|
+
<h2>Base stylesheet</h2>
|
|
44
|
+
<p class="meta">Everything after the <code>:root</code> block in generated CSS comes from a <code>look-styles/base-stylesheet</code> asset in the render catalog.</p>
|
|
45
|
+
${m}
|
|
46
|
+
|
|
47
|
+
<h2>Design tokens (:root)</h2>
|
|
48
|
+
<p class="meta">Resolved for the publisher landing page. Each token shows which resource in the cascade supplied it.</p>
|
|
49
|
+
${t.stylesheet.tokens.length===0?'<p><span class="bad">\u2717 No tokens resolved</span></p>':`<table>
|
|
50
|
+
<tr><th>Token</th><th>Value</th><th>Declared by</th><th>Cascade level</th></tr>
|
|
51
|
+
${p}
|
|
52
|
+
</table>`}
|
|
53
|
+
|
|
54
|
+
<h2>Look (page body)</h2>
|
|
55
|
+
${t.stylesheet.look?`<p><span class="good">\u2713</span> Bands resolve from <code>${e(t.stylesheet.look.sourceClass)}</code></p>`:'<p><span class="bad">\u2717 No look resolved</span> \u2014 the page body renders as an empty comment.</p>'}
|
|
56
|
+
|
|
57
|
+
<h2>Render catalog (${t.catalog.length} package version(s))</h2>
|
|
58
|
+
<p class="meta">Everything the renderer can see for this publisher \u2014 the served packages, their import closure, and the ambient render stack.</p>
|
|
59
|
+
<table>
|
|
60
|
+
<tr><th>Package version</th><th>Resources</th></tr>
|
|
61
|
+
${k}
|
|
62
|
+
</table>
|
|
63
|
+
</body>
|
|
64
|
+
</html>`}var x={".html":"text/html; charset=utf-8",".css":"text/css; charset=utf-8",".svg":"image/svg+xml",".md":"text/markdown; charset=utf-8",".kan.yml":"application/yaml; charset=utf-8",".txt":"text/plain; charset=utf-8",".json":"application/json; charset=utf-8"},P=(t,e,n,r)=>({status:t,headers:{"Content-Type":e,...r||{}},body:n}),K=t=>P(404,x[".html"],`<!doctype html><meta charset=utf-8><title>404</title><h1>404</h1><p>Not found: ${t}</p>`),Fe=t=>({status:301,headers:{Location:t},body:""}),Ke=t=>({status:302,headers:{Location:t},body:""});function Me(t){switch(t.kind){case"exact":return{operator:ne.Exact,version:L(t.major,t.minor,t.patch)};case"minor-pin":return{operator:ne.Compatible,version:L(t.major,t.minor,0)};case"major-pin":return{operator:ne.Major,version:L(t.major,0,0)};default:return{operator:ne.Any,version:L(0,0,0)}}}async function Ve(t,e,n,r){if(!r)return null;let s=t.producers?.find(k=>k.canProduce(t.publisher,e));if(!s)return null;let a=await s.resolveVersion(t.publisher,e,Me(n));if(!a)return null;let m=F(a);if(n.kind!=="exact")return Ke(`/${e}/${m}.kan.yml`);let{source:p}=await s.produce(t.publisher,e,a);return P(200,x[".kan.yml"],p)}function Re(t,e,n){let r=t.pkgVersions.get(e);if(!r||r.length===0)return null;switch(n.kind){case"any":return r[0].verStr;case"major-pin":return r.find(s=>s.version.major===n.major)?.verStr??null;case"minor-pin":return r.find(s=>s.version.major===n.major&&s.version.minor===n.minor)?.verStr??null;case"exact":return r.find(s=>s.version.major===n.major&&s.version.minor===n.minor&&s.version.patch===n.patch)?.verStr??null;default:return null}}async function ce(t,e,n=""){let{lookRenderer:r,publisher:s}=t;if(e==="/.well-known/kanonak.json"){let o=me(s);return t.producers&&t.producers.length>0&&(o.resolveByRedirect=!0),P(200,x[".json"],JSON.stringify(o,null,2))}if(e==="/index.txt"){let o=[...t.localNamespaces].map(h=>h.split("/")[1].replace("@","/")).sort();return P(200,x[".txt"],o.join(`
|
|
2
65
|
`)+`
|
|
3
|
-
`)}if(e==="/"||e==="/index.html"||e==="/index.css"){let
|
|
66
|
+
`)}if(e==="/.well-known/kanonak-render.json")return P(200,x[".json"],JSON.stringify(te(t),null,2));if(e==="/.well-known/kanonak-render")return P(200,x[".html"],ie(te(t)));if(e==="/"||e==="/index.html"||e==="/index.css"){let o=r.publisherSubject(s);return e==="/index.css"?P(200,x[".css"],r.renderStylesheet(o)):P(200,x[".html"],await r.renderDocument(o,{rootIndex:!0}))}let a=".html",m=!1,p=e;for(let o of[".kan.yml",".css",".svg",".md",".html"])if(e.endsWith(o)){a=o,m=!0,p=e.slice(0,-o.length);break}let k=!m&&/application\/yaml|text\/yaml/i.test(n),d=p.endsWith("/");d&&p!=="/"&&(p=p.slice(0,-1));let u=be.parse(p,s);if(!u)return K(e);if(u.kind==="package"){let o=Re(t,u.package_,u.versionSpec);if(!o)return await Ve(t,u.package_,u.versionSpec,a===".kan.yml"||k)??K(e);if(a===".kan.yml"||k){let b=t.rawByNsKey.get(`${u.package_}@${o}`);return b!==void 0?P(200,x[".kan.yml"],b):K(e)}let h=t.pkgSelfByVer.get(`${u.package_}@${o}`);if(!h)return K(e);if(a===".css")return P(200,x[".css"],r.renderStylesheet(h));if(!d)return Fe(p+"/");let y=u.versionSpec.kind==="any";if(y&&!r.hasDeclaredView(h)){let b=(t.pkgVersions.get(u.package_)||[]).map($=>$.verStr);return P(200,x[".html"],r.renderPackageVersionList(u.package_,b,h))}return P(200,x[".html"],await r.renderDocument(h,y?{bareOverview:!0}:void 0))}if(u.kind==="resource"){let o=Re(t,u.package_,u.versionSpec);if(!o)return K(e);let h=t.bySubject.get(`${s}/${u.package_}@${o}/${u.name}`);if(!h)return K(e);switch(a){case".css":return P(200,x[".css"],r.renderStylesheet(h));case".svg":return P(200,x[".svg"],await r.renderSvg(h));case".md":{let y=r.renderRawMarkdown(h);return y===void 0?K(e):P(200,x[".md"],y)}default:return P(200,x[".html"],await r.renderDocument(h))}}return K(e)}import{readFileSync as Be}from"fs";var le=class{constructor(e={}){this.options=e}options;models=new Map;workspaceIndex;clearCache(){this.models.clear(),this.workspaceIndex=void 0}getWorkspaceIndex(){if(this.workspaceIndex)return this.workspaceIndex;let e=new Set,n=new Set;if(this.options.root!==void 0){let r=new E;for(let s of J(this.options.root))try{let a=r.parse(Be(s,"utf-8")).metadata?.namespace_;if(!a?.version)continue;let m=a.version;e.add(`${a.publisher}/${a.package_}@${m.major}.${m.minor}.${m.patch}`),n.add(`${a.publisher}/${a.package_}`)}catch{}}return this.workspaceIndex={exact:e,pkgs:n},this.workspaceIndex}async modelFor(e,n,r){let s=this.getWorkspaceIndex(),a={...this.options.fetchFn?{fetchFn:this.options.fetchFn}:{},...this.options.log?{log:this.options.log}:{}},m=n?r?s.exact.has(`${e}/${n}@${r}`):s.pkgs.has(`${e}/${n}`):[...s.pkgs].some(o=>o.startsWith(`${e}/`)),p,k;if(m&&this.options.root!==void 0){let o=this.options.root;p=`ws:${e}`,k=()=>se(o,{publisher:e,...this.options.log?{log:this.options.log}:{}})}else{let o=n?r?`${e}/${n}@${r}`:`${e}/${n}`:e;p=`rm:${o}`,k=()=>ae(o,a)}let d=this.models.get(p);if(d)return d;let u=await k();return u.lookRenderer.setLinkMode("open-world"),this.models.set(p,u),u}async handle(e,n=""){let r=e.split("/").filter(Boolean);if(r.length===0)return{status:200,headers:{"Content-Type":"text/html; charset=utf-8"},body:xe()};let s=r[0];if(!s.includes("."))return{status:404,headers:{"Content-Type":"text/html; charset=utf-8"},body:"<!doctype html><meta charset=utf-8><title>404</title><h1>404</h1><p>Expected a publisher domain as the first path segment: <code>/{publisher}/{package}/{version}/{resource}</code></p>"};let a=r.length>=2&&(r[1]==="index.html"||r[1]==="index.css"||r[1]==="index.txt"||r[1]===".well-known"),m=!a&&r.length>=2?r[1]:void 0,p=!a&&r.length>=3&&/^\d+\.\d+\.\d+$/.test(r[2])?r[2]:void 0,k=await this.modelFor(s,m,p),d=e.endsWith("/")&&r.length>1?"/":"",u="/"+r.slice(1).join("/")+d,o=await ce(k,u,n);return o.headers.Location?{...o,headers:{...o.headers,Location:`/${s}${o.headers.Location}`}}:o}};function xe(){return'<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Kanonak origin</title></head><body style="font-family:system-ui;max-width:40rem;margin:4rem auto;padding:0 1rem"><h1>Kanonak request-driven origin</h1><p>Open a resource by its address:</p><p><code>/{publisher}/{package}/{version}/{resource}</code></p><p>e.g. <code>/kanonak.org/capabilities/2.0.0/Capability</code></p></body></html>'}export{V as ClosureScopedRepository,le as RequestRouter,Se as UNIVERSAL_RENDER_BASE,te as buildRenderDiagnostics,W as buildRenderStackWarnings,H as deriveImportClosure,xe as landingPage,ae as loadResourceModel,se as loadServerModel,ie as renderDiagnosticsHtml,C as renderRefKey,T as resolveRenderContract,ce as route};
|
|
@@ -5,6 +5,11 @@ export interface LoadResourceModelOptions {
|
|
|
5
5
|
fetchFn?: AuthenticatedFetchFn;
|
|
6
6
|
/** Override the global cache directory (the untrusted download accelerator). */
|
|
7
7
|
cacheRoot?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Progress/observability sink — narrates render-stack resolution (where each
|
|
10
|
+
* ambient look package came from, every fetch failure) as it happens.
|
|
11
|
+
*/
|
|
12
|
+
log?: (line: string) => void;
|
|
8
13
|
}
|
|
9
14
|
/**
|
|
10
15
|
* Build a {@link ServerModel} seeded from a single Kanonak ADDRESS, fetching
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { ServerModel } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Render diagnostics — the self-service answer to "why does my site have no
|
|
4
|
+
* styles?" / "what is actually contributing to this page?".
|
|
5
|
+
*
|
|
6
|
+
* The look stack is AMBIENT (discovered, not imported), so when part of it is
|
|
7
|
+
* missing the only symptom is a bare page — no error anywhere. This module
|
|
8
|
+
* turns the server model's render-stack report (load-time: where each ambient
|
|
9
|
+
* package came from) plus the LookRenderer's stylesheet explanation
|
|
10
|
+
* (request-time: what the landing page's CSS actually resolves to) into one
|
|
11
|
+
* structured, human- and machine-readable report, served at:
|
|
12
|
+
*
|
|
13
|
+
* - `/.well-known/kanonak-render.json` — machine (curl / tooling)
|
|
14
|
+
* - `/.well-known/kanonak-render` — human (self-contained HTML)
|
|
15
|
+
*
|
|
16
|
+
* The HTML page deliberately depends on NOTHING it diagnoses: all styling is
|
|
17
|
+
* inline, so it renders correctly precisely when the look stack is broken.
|
|
18
|
+
*/
|
|
19
|
+
/** JSON-friendly render diagnostics (no Maps, no class instances). */
|
|
20
|
+
export interface RenderDiagnostics {
|
|
21
|
+
/** The served publisher. */
|
|
22
|
+
readonly publisher: string;
|
|
23
|
+
/** Load-time: how the ambient render stack resolved when the model was built. */
|
|
24
|
+
readonly renderStack: {
|
|
25
|
+
readonly contractSource: string;
|
|
26
|
+
readonly cachePath: string;
|
|
27
|
+
readonly packages: readonly {
|
|
28
|
+
readonly package_: string;
|
|
29
|
+
readonly origin: string;
|
|
30
|
+
readonly versions?: readonly string[];
|
|
31
|
+
readonly reason?: string;
|
|
32
|
+
readonly resolvedButNotInCatalog?: boolean;
|
|
33
|
+
}[];
|
|
34
|
+
};
|
|
35
|
+
/** Request-time: what the publisher landing page's stylesheet resolves to. */
|
|
36
|
+
readonly stylesheet: {
|
|
37
|
+
readonly tokens: readonly {
|
|
38
|
+
readonly name: string;
|
|
39
|
+
readonly value: string;
|
|
40
|
+
readonly source: string;
|
|
41
|
+
readonly level: string;
|
|
42
|
+
}[];
|
|
43
|
+
readonly baseStylesheet: {
|
|
44
|
+
readonly present: boolean;
|
|
45
|
+
readonly source?: string;
|
|
46
|
+
readonly scope?: string;
|
|
47
|
+
readonly bytes?: number;
|
|
48
|
+
readonly problem?: string;
|
|
49
|
+
readonly candidates: readonly string[];
|
|
50
|
+
};
|
|
51
|
+
readonly look?: {
|
|
52
|
+
readonly sourceClass: string;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
/** Every package namespace in the parsed render catalog + its resource count. */
|
|
56
|
+
readonly catalog: readonly {
|
|
57
|
+
readonly namespace: string;
|
|
58
|
+
readonly resources: number;
|
|
59
|
+
}[];
|
|
60
|
+
/** All warnings: load-time (render stack) + request-time (stylesheet). */
|
|
61
|
+
readonly warnings: readonly string[];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Build the diagnostics for a served model. Pure — reads the model's
|
|
65
|
+
* load-time render-stack report and asks the LookRenderer to explain the
|
|
66
|
+
* publisher landing page's stylesheet; performs no I/O.
|
|
67
|
+
*/
|
|
68
|
+
export declare function buildRenderDiagnostics(model: ServerModel): RenderDiagnostics;
|
|
69
|
+
/**
|
|
70
|
+
* The human-readable diagnostics page. Entirely self-contained (inline CSS,
|
|
71
|
+
* no external stylesheet, no look-stack dependency) — it must render correctly
|
|
72
|
+
* exactly when the thing it diagnoses is broken.
|
|
73
|
+
*/
|
|
74
|
+
export declare function renderDiagnosticsHtml(diag: RenderDiagnostics): string;
|
|
@@ -40,3 +40,43 @@ export declare const UNIVERSAL_RENDER_BASE: readonly RenderPackageRef[];
|
|
|
40
40
|
export declare function resolveRenderContract(config: PublisherConfig | undefined): readonly RenderPackageRef[];
|
|
41
41
|
/** The closure-set key (`publisher/package`) for a render-stack ref. */
|
|
42
42
|
export declare function renderRefKey(ref: RenderPackageRef): string;
|
|
43
|
+
/** How one render-stack package became available to the render catalog (or didn't). */
|
|
44
|
+
export interface RenderPackageStatus {
|
|
45
|
+
readonly publisher: string;
|
|
46
|
+
readonly package_: string;
|
|
47
|
+
/**
|
|
48
|
+
* Where the package came from:
|
|
49
|
+
* - `workspace` — authored in the served workspace
|
|
50
|
+
* - `cache` — already in the global package cache
|
|
51
|
+
* - `fetched` — fetched from its publisher during this load and installed to the cache
|
|
52
|
+
* - `repository` — present in a caller-supplied resolution repository
|
|
53
|
+
* - `missing` — NOT available anywhere; pages lose whatever this package contributes
|
|
54
|
+
*/
|
|
55
|
+
readonly origin: 'workspace' | 'cache' | 'fetched' | 'repository' | 'missing';
|
|
56
|
+
/** Resolved version(s) found, highest first, when known. */
|
|
57
|
+
readonly versions?: readonly string[];
|
|
58
|
+
/** Why it's missing (`origin === 'missing'`) — the captured failure, never swallowed. */
|
|
59
|
+
readonly reason?: string;
|
|
60
|
+
/** True when the package resolved but did NOT make it into the parsed catalog (a scoping bug). */
|
|
61
|
+
readonly resolvedButNotInCatalog?: boolean;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The load-time render-stack resolution report, attached to the `ServerModel`.
|
|
65
|
+
* `warnings` are human-readable: condition + consequence + fix.
|
|
66
|
+
*/
|
|
67
|
+
export interface RenderStackReport {
|
|
68
|
+
/** Universal kanonak.org base, or the publisher's `.well-known` `render` override. */
|
|
69
|
+
readonly contractSource: 'universal-default' | 'publisher-well-known';
|
|
70
|
+
/** The global cache directory consulted (and populated by ambient fetches). */
|
|
71
|
+
readonly cachePath: string;
|
|
72
|
+
/** Per-package resolution status, in contract order. */
|
|
73
|
+
readonly packages: readonly RenderPackageStatus[];
|
|
74
|
+
/** Derived warnings — every `missing` package and every degraded capability. */
|
|
75
|
+
readonly warnings: readonly string[];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Derive the report's warnings from per-package statuses. What each missing
|
|
79
|
+
* package COSTS the page is part of the message — that's the insight a person
|
|
80
|
+
* debugging "my site has no styles" needs, and it differs per package.
|
|
81
|
+
*/
|
|
82
|
+
export declare function buildRenderStackWarnings(packages: readonly RenderPackageStatus[]): string[];
|
|
@@ -9,6 +9,12 @@ export interface RequestRouterOptions {
|
|
|
9
9
|
root?: string;
|
|
10
10
|
/** Authenticated fetch for remote publisher fetches (auth / testing). */
|
|
11
11
|
fetchFn?: AuthenticatedFetchFn;
|
|
12
|
+
/**
|
|
13
|
+
* Progress/observability sink, forwarded to every model build — narrates
|
|
14
|
+
* render-stack resolution (where each ambient look package came from, every
|
|
15
|
+
* fetch failure) as it happens. The CLI passes `console.log`.
|
|
16
|
+
*/
|
|
17
|
+
log?: (line: string) => void;
|
|
12
18
|
}
|
|
13
19
|
/**
|
|
14
20
|
* The request-driven routing engine: maps a publisher-FIRST path
|
package/dist/server/types.d.ts
CHANGED
|
@@ -4,7 +4,9 @@ import type { Kanonak } from '../kanonaks/index.js';
|
|
|
4
4
|
import { SubjectKanonak } from '../kanonaks/index.js';
|
|
5
5
|
import type { LookRenderer } from '../look/index.js';
|
|
6
6
|
import type { HttpCacheHooks } from '../repositories/index.js';
|
|
7
|
+
import type { AuthenticatedFetchFn } from '../auth/index.js';
|
|
7
8
|
import type { IPackageProducer } from '../producer/index.js';
|
|
9
|
+
import type { RenderStackReport } from './renderStack.js';
|
|
8
10
|
/** A package version present in the served workspace. */
|
|
9
11
|
export interface PackageVersion {
|
|
10
12
|
/** "major.minor.patch" string form. */
|
|
@@ -45,6 +47,14 @@ export interface ServerModel {
|
|
|
45
47
|
* `EntitlementProducer` here for a gated origin.
|
|
46
48
|
*/
|
|
47
49
|
readonly producers?: readonly IPackageProducer[];
|
|
50
|
+
/**
|
|
51
|
+
* How the ambient render stack (look-styles, look-tokens, …) resolved when
|
|
52
|
+
* this model was loaded — per-package origin, captured failure reasons, and
|
|
53
|
+
* derived warnings. This is what serve logs at startup and what the
|
|
54
|
+
* `/.well-known/kanonak-render` diagnostics endpoint reports, so a styling
|
|
55
|
+
* failure is explainable instead of a silently bare page.
|
|
56
|
+
*/
|
|
57
|
+
readonly renderStack: RenderStackReport;
|
|
48
58
|
}
|
|
49
59
|
/** A routed response. `body` is always a string (HTML/CSS/SVG/MD/YAML/JSON). */
|
|
50
60
|
export interface RouteResponse {
|
|
@@ -67,5 +77,21 @@ export interface LoadServerModelOptions {
|
|
|
67
77
|
repository?: IKanonakDocumentRepository;
|
|
68
78
|
/** HTTP write-through cache hook for the default stack (e.g. a disk cache). */
|
|
69
79
|
httpCache?: HttpCacheHooks;
|
|
80
|
+
/**
|
|
81
|
+
* Transport for ALL remote fetches the default stack performs — the HTTP
|
|
82
|
+
* repository's index/package fetches, the publisher config fetch, AND the
|
|
83
|
+
* ambient render-stack package fetch below. A consumer that must control
|
|
84
|
+
* fetching (a sandboxed/no-disk environment, or one synthesizing sources
|
|
85
|
+
* from a non-HTTP store) provides this so no request escapes to a raw
|
|
86
|
+
* `fetch`. Ignored when `repository` is supplied (the caller owns transport).
|
|
87
|
+
*/
|
|
88
|
+
fetchFn?: AuthenticatedFetchFn;
|
|
89
|
+
/**
|
|
90
|
+
* Progress/observability sink. When provided, model loading narrates what it
|
|
91
|
+
* is doing — workspace scan results, where each render-stack package
|
|
92
|
+
* resolved from, every fetch and every failure — as it happens. The CLI
|
|
93
|
+
* passes `console.log`; embedders can capture or discard.
|
|
94
|
+
*/
|
|
95
|
+
log?: (line: string) => void;
|
|
70
96
|
}
|
|
71
97
|
export { SubjectKanonak };
|
|
@@ -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-OOR5SVNQ.js";import{a as se}from"../chunk-NV63IOB7.js";import"../chunk-QHABFCRC.js";import"../chunk-4NO7MHS7.js";import"../chunk-RYOZTXI7.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-DSHPAWJQ.js";import{a as ae}from"../chunk-NJ3AZYQD.js";import{b as L,c as A,f as S}from"../chunk-PBNVHBS3.js";import"../chunk-VKTFLHCW.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kanonak-protocol/sdk",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.9.0",
|
|
4
4
|
"description": "TypeScript SDK for the Kanonak Protocol — parse, resolve, validate, reason over, and render .kan.yml packages.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
"yaml-parser"
|
|
126
126
|
],
|
|
127
127
|
"dependencies": {
|
|
128
|
-
"@kanonak-protocol/types": "^4.
|
|
128
|
+
"@kanonak-protocol/types": "^4.9.0",
|
|
129
129
|
"ignore": "^7.0.5",
|
|
130
130
|
"js-yaml": "^4.1.0",
|
|
131
131
|
"yaml": "^2.7.0"
|