@@ -32,33 +32,53 @@ import yaml from 'js-yaml'
3232import fs from 'fs'
3333import { chunk , last } from 'lodash-es'
3434import { visit } from 'unist-util-visit'
35+ import type { Test } from 'unist-util-visit'
36+ import type { Node , Parent } from 'unist'
37+ import type { Element , Nodes } from 'hast'
3538import { h } from 'hastscript'
3639import { fromMarkdown } from 'mdast-util-from-markdown'
3740import { toHast } from 'mdast-util-to-hast'
3841import type { Root } from 'mdast'
3942import { header } from './code-header'
4043import findPage from '@/frame/lib/find-page'
4144import { createLogger } from '@/observability/logger'
45+ import type { Context } from '@/types'
4246
4347const logger = createLogger ( import . meta. url )
4448
4549interface LanguageConfig {
4650 comment : 'number' | 'slash' | 'xml' | 'percent' | 'hyphen'
47- [ key : string ] : any
51+ [ key : string ] : unknown
52+ }
53+
54+ interface HastNode {
55+ type ?: string
56+ value ?: string
57+ properties ?: {
58+ className ?: string [ ]
59+ [ key : string ] : unknown
60+ }
61+ children ?: HastNode [ ]
62+ data ?: {
63+ meta ?: {
64+ annotate ?: boolean
65+ [ key : string ] : unknown
66+ }
67+ }
4868}
4969
5070interface ElementNode {
5171 type : 'element'
5272 tagName : string
5373 properties : {
5474 className ?: string [ ]
55- [ key : string ] : any
75+ [ key : string ] : unknown
5676 }
57- children : any [ ]
77+ children : HastNode [ ]
5878 data ?: {
5979 meta ?: {
6080 annotate ?: boolean
61- [ key : string ] : any
81+ [ key : string ] : unknown
6282 }
6383 }
6484}
@@ -92,27 +112,27 @@ const commentRegexes = {
92112 hyphen : / ^ \s * - - \s * / ,
93113}
94114
95- // Using 'any' for node because unist-util-visit requires broad type compatibility
96- const matcher = ( node : any ) : node is ElementNode =>
97- node . type === 'element' && node . tagName === 'pre' && Boolean ( getPreMeta ( node ) . annotate )
115+ const matcher = ( node : Node ) : boolean =>
116+ node . type === 'element' &&
117+ ( node as unknown as ElementNode ) . tagName === 'pre' &&
118+ Boolean ( getPreMeta ( node as unknown as ElementNode ) . annotate )
98119
99- // Using 'any' for context because unified plugins receive different context types depending on processor configuration
100- export default function annotate ( context : any ) {
101- // Using 'any' for tree because unified's AST types are complex and vary between processors
102- return ( tree : any ) => {
103- // Using 'any' for parent because unist-util-visit's callback typing doesn't provide specific parent types
104- visit ( tree , matcher , ( node : ElementNode , index : number | undefined , parent : any ) => {
120+ export default function annotate ( context : Context ) {
121+ return ( tree : Node ) => {
122+ visit ( tree , matcher as Test , ( node , index , parent ) => {
105123 if ( index !== undefined && parent ) {
106- parent . children [ index ] = createAnnotatedNode ( node , context )
124+ ; ( parent as Parent ) . children [ index ] = createAnnotatedNode (
125+ node as unknown as ElementNode ,
126+ context ,
127+ ) as unknown as Node
107128 }
108129 } )
109130 }
110131}
111132
112- // Using 'any' for context to match the plugin signature, and return type because hastscript returns complex hast types
113- function createAnnotatedNode ( node : ElementNode , context : any ) : any {
114- const lang = node . children [ 0 ] . properties . className [ 0 ] . replace ( 'language-' , '' )
115- const code = node . children [ 0 ] . children [ 0 ] . value
133+ function createAnnotatedNode ( node : ElementNode , context : Context ) : Element {
134+ const lang = node . children [ 0 ] . properties ! . className ! [ 0 ] . replace ( 'language-' , '' )
135+ const code = node . children [ 0 ] . children ! [ 0 ] . value as string
116136
117137 // Check the code is parse-able
118138 validate ( lang , code )
@@ -189,8 +209,7 @@ function matchComment(lang: string): (line: string) => boolean {
189209 return ( line ) => regex . test ( line )
190210}
191211
192- // Using 'any' return type because hastscript's h() function returns complex hast element types
193- function getSubnav ( ) : any {
212+ function getSubnav ( ) : Element {
194213 const besideBtn = h (
195214 'button' ,
196215 {
@@ -215,7 +234,6 @@ function getSubnav(): any {
215234 return h ( 'div' , { className : 'annotate-toggle' } , [ besideBtn , inlineBtn ] )
216235}
217236
218- // Using 'any' for context and return type due to hastscript's complex type definitions
219237function template ( {
220238 lang,
221239 code,
@@ -225,8 +243,8 @@ function template({
225243 lang : string
226244 code : string
227245 rows : string [ ] [ ] [ ]
228- context : any
229- } ) : any {
246+ context : Context
247+ } ) : Element {
230248 return h (
231249 'div' ,
232250 { class : 'annotate beside' } ,
@@ -257,8 +275,7 @@ function template({
257275 )
258276}
259277
260- // Using 'any' for context and return type to maintain compatibility with mdast-util-to-hast complex types
261- function mdToHast ( text : string , context : any ) : any {
278+ function mdToHast ( text : string , context : Context ) : Nodes {
262279 const mdast : Root = fromMarkdown ( text )
263280
264281 // Process AUTOTITLE links
@@ -269,8 +286,7 @@ function mdToHast(text: string, context: any): any {
269286
270287// Helper method to process AUTOTITLE links in MDAST
271288// This can be reused for other MDAST processing that needs AUTOTITLE support
272- // Using 'any' for context because it may or may not have pages/redirects properties depending on usage
273- function processAutotitleInMdast ( mdast : Root , context : any ) : void {
289+ function processAutotitleInMdast ( mdast : Root , context : Context ) : void {
274290 visit ( mdast , 'link' , ( node ) => {
275291 if ( node . url && node . url . startsWith ( '/' ) ) {
276292 for ( const child of node . children ) {
@@ -300,7 +316,7 @@ function removeComment(lang: string): (line: string) => string {
300316 return ( line ) => line . replace ( regex , '' )
301317}
302318
303- function getPreMeta ( node : ElementNode ) : { annotate ?: boolean ; [ key : string ] : any } {
319+ function getPreMeta ( node : ElementNode ) : { annotate ?: boolean ; [ key : string ] : unknown } {
304320 // Here's why this monstrosity works:
305321 // https://github.com/syntax-tree/mdast-util-to-hast/blob/c87cd606731c88a27dbce4bfeaab913a9589bf83/lib/handlers/code.js#L40-L42
306322 return node . children [ 0 ] ?. data ?. meta || { }
0 commit comments