7373 . cat-card . cc-title { display : flex; align-items : center; gap : 9px ; font-size : 18px ; font-weight : 650 ; letter-spacing : -0.01em ; }
7474 . cat-card . cc-title . ic { width : 19px ; height : 19px ; color : var ( --accent ) ; }
7575 . cat-card . cc-doc { color : var ( --muted ) ; font-size : 13.5px ; margin-top : 5px ; }
76+ . cat-card . cc-doc . md-h { font-size : 14px ; font-weight : 650 ; color : var ( --ink ) ; margin : 8px 0 4px ; }
77+ . cat-card . cc-doc . md-p { margin : 4px 0 ; }
78+ . cat-card . cc-doc . md-p : first-child { margin-top : 0 ; }
79+ . cat-card . cc-doc . md-ul { margin : 4px 0 ; padding-left : 18px ; }
80+ . cat-card . cc-doc code { font-family : var ( --mono ) ; background : var ( --chip ) ; padding : 1px 5px ; border-radius : 4px ; font-size : .92em ; }
81+ . cat-card . cc-doc a { color : var ( --accent ) ; }
7682 . badges { display : flex; gap : 8px ; flex-wrap : wrap; margin-top : 13px ; }
7783 . badge { display : inline-flex; align-items : center; gap : 6px ; font-size : 12.5px ; padding : 5px 11px ; border : 1px solid var ( --line-strong ) ; border-radius : 8px ; text-decoration : none; color : var ( --ink ) ; background : var ( --panel ) ; }
7884 . badge : hover { border-color : var ( --accent ) ; color : var ( --accent ) ; }
190196 . t-name , . fn-name { font-family : var ( --mono ) ; font-size : 12.5px ; font-weight : 550 ; }
191197 . t-meta { color : var ( --muted ) ; font-size : 11.5px ; font-family : var ( --mono ) ; font-variant-numeric : tabular-nums; flex : none; }
192198 . fn-sig { color : var ( --muted ) ; font-size : 12px ; font-family : var ( --mono ) ; flex : none; }
193- . t-comment , . fn-doc { color : var ( --muted ) ; font-size : 12.5px ; overflow : hidden; text-overflow : ellipsis; white-space : nowrap; min-width : 0 ; margin-left : auto; text-align : right; }
199+ . fn-doc { color : var ( --muted ) ; font-size : 12.5px ; overflow : hidden; text-overflow : ellipsis; white-space : nowrap; min-width : 0 ; margin-left : auto; text-align : right; }
194200
195201 /* level 4: body inset */
196202 . t-body , . fn-body { padding : 9px 13px 12px ; background : color-mix ( in srgb, var ( --kc ) 4% , var ( --bg ) ) ; border-radius : 0 0 var ( --row-radius ) var ( --row-radius ) ; }
203+ . t-desc { color : var ( --ink ) ; font-size : 12.5px ; line-height : 1.5 ; margin : 0 0 11px ; }
204+ . t-desc . md-h { font-size : 13px ; font-weight : 650 ; margin : 8px 0 4px ; }
205+ . t-desc . md-p { margin : 4px 0 ; }
206+ . t-desc . md-p : first-child { margin-top : 0 ; }
207+ . t-desc . md-ul { margin : 4px 0 ; padding-left : 18px ; }
208+ . t-desc code { font-family : var ( --mono ) ; background : var ( --chip ) ; padding : 1px 5px ; border-radius : 4px ; font-size : .92em ; }
209+ . t-desc a { color : var ( --accent ) ; }
197210 . args-label { font-size : 10.5px ; letter-spacing : .06em ; text-transform : uppercase; color : var ( --muted ) ; font-weight : 700 ; margin : 0 0 6px ; }
198211 . cols { display : flex; flex-direction : column; gap : 6px ; }
199212 . col-item { border : 1px solid color-mix ( in srgb, var ( --kc ) 22% , var ( --line ) ) ; border-radius : 7px ; padding : 7px 10px ; background : color-mix ( in srgb, var ( --kc ) 4% , var ( --panel ) ) ; }
225238</ style >
226239</ head >
227240< body >
228- <!-- vgi-landing-asset v1 -->
241+ <!-- vgi-landing-asset v2 -->
229242
230243< a class ="skip " href ="#contents "> Skip to contents</ a >
231244
@@ -312,6 +325,55 @@ <h1 id="worker-name">—</h1>
312325const esc = s => String ( s ) . replace ( / [ & < > " ] / g, c => ( { '&' :'&' , '<' :'<' , '>' :'>' , '"' :'"' } [ c ] ) ) ;
313326const sqlHi = s => esc ( s ) . replace ( / \b ( S E L E C T | F R O M | W H E R E | G R O U P B Y | O R D E R B Y | I N T E R V A L | A N D | O R | A S | J O I N | O N | Y E A R ) \b / g, m => '<span class="kw">' + m + '</span>' ) ;
314327
328+ function mdToHtml ( src ) {
329+ if ( ! src ) return '' ;
330+ var lines = String ( src ) . replace ( / \r \n ? / g, '\n' ) . split ( '\n' ) , out = [ ] , i = 0 ;
331+ function inl ( t ) {
332+ t = esc ( t ) ;
333+ t = t . replace ( / ` ( [ ^ ` ] + ) ` / g, '<code>$1</code>' ) ;
334+ t = t . replace ( / \* \* ( [ ^ * ] + ) \* \* / g, '<strong>$1</strong>' ) ;
335+ t = t . replace ( / ( ^ | [ ^ * ] ) \* ( [ ^ * ] + ) \* / g, '$1<em>$2</em>' ) ;
336+ t = t . replace ( / \[ ( [ ^ \] ] + ) \] \( ( h t t p s ? : \/ \/ [ ^ ) \s ] + ) \) / g, '<a href="$2" target="_blank" rel="noopener">$1</a>' ) ;
337+ return t ;
338+ }
339+ while ( i < lines . length ) {
340+ var ln = lines [ i ] ;
341+ if ( / ^ \s * $ / . test ( ln ) ) { i ++ ; continue ; }
342+ var h = ln . match ( / ^ ( # { 1 , 6 } ) \s + ( .* ) $ / ) ;
343+ if ( h ) { var lv = Math . min ( h [ 1 ] . length , 6 ) ; out . push ( '<h' + lv + ' class="md-h">' + inl ( h [ 2 ] ) + '</h' + lv + '>' ) ; i ++ ; continue ; }
344+ if ( / ^ \s * [ - * + ] \s + / . test ( ln ) ) {
345+ var items = [ ] ;
346+ while ( i < lines . length && / ^ \s * [ - * + ] \s + / . test ( lines [ i ] ) ) { items . push ( '<li>' + inl ( lines [ i ] . replace ( / ^ \s * [ - * + ] \s + / , '' ) ) + '</li>' ) ; i ++ ; }
347+ out . push ( '<ul class="md-ul">' + items . join ( '' ) + '</ul>' ) ; continue ;
348+ }
349+ var para = [ ln ] ; i ++ ;
350+ while ( i < lines . length && ! / ^ \s * $ / . test ( lines [ i ] ) && ! / ^ ( # { 1 , 6 } \s | \s * [ - * + ] \s ) / . test ( lines [ i ] ) ) { para . push ( lines [ i ] ) ; i ++ ; }
351+ out . push ( '<p class="md-p">' + inl ( para . join ( ' ' ) ) + '</p>' ) ;
352+ }
353+ return out . join ( '' ) ;
354+ }
355+ var _DDB_TYPES = { int8 :'TINYINT' , int16 :'SMALLINT' , int32 :'INTEGER' , int64 :'BIGINT' ,
356+ uint8 :'UTINYINT' , uint16 :'USMALLINT' , uint32 :'UINTEGER' , uint64 :'UBIGINT' ,
357+ halffloat :'FLOAT' , float :'FLOAT' , float32 :'FLOAT' , double :'DOUBLE' , float64 :'DOUBLE' ,
358+ bool :'BOOLEAN' , boolean :'BOOLEAN' , string :'VARCHAR' , large_string :'VARCHAR' , utf8 :'VARCHAR' , large_utf8 :'VARCHAR' ,
359+ binary :'BLOB' , large_binary :'BLOB' , date32 :'DATE' , 'date32[day]' :'DATE' , date64 :'DATE' , null :'NULL' ,
360+ month_day_nano_interval :'INTERVAL' } ;
361+ function duckdbType ( t ) {
362+ if ( ! t ) return t ; t = String ( t ) ; var lt = t . toLowerCase ( ) ;
363+ if ( _DDB_TYPES [ lt ] ) return _DDB_TYPES [ lt ] ;
364+ var d = t . match ( / ^ d i c t i o n a r y < v a l u e s = ( [ ^ , > ] + ) / i) ; if ( d ) return duckdbType ( d [ 1 ] . trim ( ) ) ;
365+ var l = t . match ( / ^ (?: l a r g e _ ) ? l i s t < (?: i t e m : \s * ) ? ( .+ ) > $ / i) ; if ( l ) return duckdbType ( l [ 1 ] . trim ( ) ) + '[]' ;
366+ if ( / ^ f i x e d _ s i z e _ b i n a r y / i. test ( t ) ) return 'BLOB' ;
367+ var ts = t . match ( / ^ t i m e s t a m p \[ ( [ ^ , \] ] + ) (?: , \s * t z = ( [ ^ \] ] + ) ) ? \] $ / i) ; if ( ts ) return ts [ 2 ] ?'TIMESTAMPTZ' :'TIMESTAMP' ;
368+ if ( / ^ t i m e ( 3 2 | 6 4 ) \[ / i. test ( t ) ) return 'TIME' ;
369+ if ( / ^ d u r a t i o n \[ / i. test ( t ) ) return 'INTERVAL' ;
370+ var dec = t . match ( / ^ d e c i m a l (?: 1 2 8 | 2 5 6 ) \( ( \d + ) , \s * ( \d + ) \) $ / i) ; if ( dec ) return 'DECIMAL(' + dec [ 1 ] + ',' + dec [ 2 ] + ')' ;
371+ if ( / ^ s t r u c t < / i. test ( t ) ) return 'STRUCT' ;
372+ if ( / ^ m a p < / i. test ( t ) ) return 'MAP' ;
373+ return t ;
374+ }
375+
376+
315377// ── identity pill ────────────────────────────────────────────────────────────────
316378function renderIdentity ( ) {
317379 if ( ! describe . oauth ) return ;
@@ -377,7 +439,7 @@ <h1 id="worker-name">—</h1>
377439 ? '<div class="cc-by">' + [ t . author ?'by ' + esc ( t . author ) :'' , t . copyright ?esc ( t . copyright ) :'' ] . filter ( Boolean ) . join ( ' · ' ) + '</div>' : '' ;
378440 document . getElementById ( 'cat-card' ) . innerHTML =
379441 '<div class="cc-title">' + icon ( 'catalog' ) + esc ( t . title || c . name ) + '</div>' +
380- ( t . doc_md ? '<div class="cc-doc">' + esc ( t . doc_md ) + '</div>' : '' ) +
442+ ( t . doc_md ? '<div class="cc-doc">' + mdToHtml ( t . doc_md ) + '</div>' : '' ) +
381443 ( badges ? '<div class="badges">' + badges + '</div>' : '' ) + kw + by ;
382444}
383445
@@ -482,9 +544,9 @@ <h1 id="worker-name">—</h1>
482544 const kcls = kind === 'view' ? ' view k-view' : '' ;
483545 return '<details class="tbl' + kcls + '" data-name="' + esc ( t . name . toLowerCase ( ) ) + '" data-kind="' + kind + '" data-catalog="' + esc ( catName ) + '" data-schema="' + esc ( s . name ) + '" data-table="' + esc ( t . name ) + '">' +
484546 '<summary>' + icon ( 'caret' , 'tri' ) + icon ( iconName , 'row-icon' ) +
485- '<span class="t-name">' + esc ( t . name ) + '</span><span class="t-meta">' + t . cols + ' cols</span>' +
486- ( t . comment ? '<span class="t-comment">' + esc ( t . comment ) + '</span>' :'' ) + '</summary>' +
547+ '<span class="t-name">' + esc ( t . name ) + '</span><span class="t-meta">' + t . cols + ' cols</span></summary>' +
487548 '<div class="t-body">' +
549+ ( t . comment ? '<div class="t-desc">' + mdToHtml ( t . comment ) + '</div>' : '' ) +
488550 ( kind === 'view' && t . def ? '<div class="args-label">Definition</div><pre class="view-sql">' + sqlHi ( t . def ) + '</pre>' : '' ) +
489551 '<div class="args-label">Columns</div><div class="cols"><div class="skeleton">Loading columns…</div></div></div></details>' ;
490552}
@@ -497,7 +559,7 @@ <h1 id="worker-name">—</h1>
497559 const def = ( a . default !== undefined && a . default !== null ) ? '<span class="arg-def">default ' + esc ( a . default ) + '</span>' : '' ;
498560 const desc = a . desc ? esc ( a . desc ) : '' ;
499561 const meta = ( desc || def ) ? '<div class="col-comment">' + desc + ( desc && def ?' · ' :'' ) + def + '</div>' : '' ;
500- return '<div class="col-item"><div class="col"><span class="col-name">' + esc ( a . name ) + ( a . named ?'<span class="arg-kind"> :=</span>' :'' ) + '</span><span class="col-type">' + esc ( a . type ) + '</span></div>' + meta + '</div>' ;
562+ return '<div class="col-item"><div class="col"><span class="col-name">' + esc ( a . name ) + ( a . named ?'<span class="arg-kind"> :=</span>' :'' ) + '</span><span class="col-type">' + esc ( duckdbType ( a . type ) ) + '</span></div>' + meta + '</div>' ;
501563}
502564function fnRow ( f , iconName ) {
503565 const pos = f . args . filter ( a => ! a . named ) , named = f . args . filter ( a => a . named ) ;
@@ -563,7 +625,7 @@ <h1 id="worker-name">—</h1>
563625 const body = d . querySelector ( '.cols' ) ;
564626 fetchColumns ( d . dataset . catalog , d . dataset . schema , d . dataset . table ) . then ( info => {
565627 body . innerHTML = info . columns . map ( col =>
566- '<div class="col-item"><div class="col"><span class="col-name">' + esc ( col . name ) + '</span><span class="col-type">' + esc ( col . type ) + '</span></div>' +
628+ '<div class="col-item"><div class="col"><span class="col-name">' + esc ( col . name ) + '</span><span class="col-type">' + esc ( duckdbType ( col . type ) ) + '</span></div>' +
567629 ( col . comment ? '<div class="col-comment">' + esc ( col . comment ) + '</div>' :'' ) + '</div>' ) . join ( '' ) ;
568630 } ) ;
569631} , true ) ;
@@ -604,9 +666,7 @@ <h1 id="worker-name">—</h1>
604666 '<a href="' + prefix + '/describe">RPC API</a><span class="dot">·</span>' +
605667 '<a href="https://github.com/query-farm">Source</a><span class="dot">·</span>' +
606668 '<a href="https://query.farm">Query.Farm</a>' +
607- '<div class="foot-meta">vgi-rpc (<code>' + esc ( describe . worker . lang ) + '</code>) · v' + esc ( describe . worker . version ) + ' · <code>' + esc ( describe . server_id ) + '</code></div>' +
608- '<div class="foot-meta">landing_schema_version ' + describe . landing_schema_version +
609- ' · shared page, identical across Python / Go / Rust / TypeScript / Java</div>' ;
669+ '<div class="foot-meta">vgi-rpc (<code>' + esc ( describe . worker . lang ) + '</code>) · v' + esc ( describe . worker . version ) + ' · <code>' + esc ( describe . server_id ) + '</code></div>' ;
610670}
611671
612672function renderAll ( ) { renderCatBar ( ) ; renderCatCard ( ) ; renderConnect ( ) ; updateCupola ( ) ; renderContents ( ) ; }
0 commit comments