1+ // @ts -ignore - markdownlint-rule-helpers doesn't provide TypeScript declarations
12import { addError } from 'markdownlint-rule-helpers'
23
34import {
@@ -17,14 +18,15 @@ import {
1718 isInAllGhes ,
1819} from '@/ghes-releases/scripts/version-utils'
1920import { deprecated , oldestSupported } from '@/versions/lib/enterprise-server-releases'
21+ import type { RuleParams , RuleErrorCallback } from '@/content-linter/types'
2022
2123export const liquidIfversionVersions = {
2224 names : [ 'GHD022' , 'liquid-ifversion-versions' ] ,
2325 description :
2426 'Liquid `ifversion`, `elsif`, and `else` tags should be valid and not contain unsupported versions.' ,
2527 tags : [ 'liquid' , 'versioning' ] ,
2628 asynchronous : true ,
27- function : async ( params , onError ) => {
29+ function : async ( params : RuleParams , onError : RuleErrorCallback ) => {
2830 // The versions frontmatter object or all versions if the file
2931 // being processed is a data file.
3032 const fm = getFrontmatter ( params . lines )
@@ -34,7 +36,7 @@ export const liquidIfversionVersions = {
3436 ? { ghec : '*' , ghes : '*' , fpt : '*' }
3537 : fm
3638 ? fm . versions
37- : getFrontmatter ( params . frontMatterLines ) . versions
39+ : getFrontmatter ( params . frontMatterLines ) ? .versions
3840 // This will only contain valid (non-deprecated) and future versions
3941 const fileVersions = getApplicableVersions ( fileVersionsFm , '' , {
4042 doNotThrow : true ,
@@ -45,7 +47,8 @@ export const liquidIfversionVersions = {
4547 // Array of arrays - each array entry is an array of items that
4648 // make up a full if/elsif/else/endif statement.
4749 // [ [ifversion, elsif, else, endif], [nested ifversion, elsif, else, endif] ]
48- const condStmtStack = [ ]
50+ // Using any[] because these are complex dynamic objects with properties added at runtime
51+ const condStmtStack : any [ ] = [ ]
4952
5053 // Tokens are in the order they are read in file, so we need to iterate
5154 // through and group full if/elsif/else/endif statements together.
@@ -76,25 +79,28 @@ export const liquidIfversionVersions = {
7679 // The versions of an else tag are the set of file versions that are
7780 // not supported by the previous ifversion or elsif tags.
7881 const siblingVersions = condTagItems
79- . filter ( ( item ) => item . name === 'ifversion' || item . name === 'elsif' )
80- . map ( ( item ) => item . versions )
82+ // Using any because condTagItems contains dynamic objects from initTagObject
83+ . filter ( ( item : any ) => item . name === 'ifversion' || item . name === 'elsif' )
84+ . map ( ( item : any ) => item . versions )
8185 . flat ( )
82- condTagItem . versions = difference ( fileVersions , siblingVersions )
86+ // Using any because versions property is added dynamically to condTagItem
87+ ; ( condTagItem as any ) . versions = difference ( fileVersions , siblingVersions )
8388 condTagItems . push ( condTagItem )
8489 condStmtStack . push ( condTagItems )
8590 } else if ( token . name === 'endif' ) {
8691 defaultProps . parent = undefined
8792 const condTagItems = condStmtStack . pop ( )
8893 const condTagItem = await initTagObject ( token , defaultProps )
8994 condTagItems . push ( condTagItem )
90- decorateCondTagItems ( condTagItems , params . lines )
95+ decorateCondTagItems ( condTagItems )
9196 setLiquidErrors ( condTagItems , onError , params . lines )
9297 }
9398 }
9499 } ,
95100}
96101
97- function setLiquidErrors ( condTagItems , onError , lines ) {
102+ // Using any[] because condTagItems contains dynamic objects with properties added at runtime
103+ function setLiquidErrors ( condTagItems : any [ ] , onError : RuleErrorCallback , lines : string [ ] ) {
98104 for ( let i = 0 ; i < condTagItems . length ; i ++ ) {
99105 const item = condTagItems [ i ]
100106 const tagNameNoCond = item . name === 'endif' || item . name === 'else'
@@ -175,8 +181,9 @@ function setLiquidErrors(condTagItems, onError, lines) {
175181 }
176182}
177183
178- async function getApplicableVersionFromLiquidTag ( conditionStr , filename ) {
179- const newConditionObject = { }
184+ async function getApplicableVersionFromLiquidTag ( conditionStr : string ) {
185+ // Using Record<string, any> because version object keys are dynamic (fpt, ghec, ghes, feature, etc.)
186+ const newConditionObject : Record < string , any > = { }
180187 const condition = conditionStr . replace ( 'not ' , '' )
181188 const liquidTagVersions = condition . split ( ' or ' ) . map ( ( item ) => item . trim ( ) )
182189 for ( const ver of liquidTagVersions ) {
@@ -227,7 +234,8 @@ async function getApplicableVersionFromLiquidTag(conditionStr, filename) {
227234 return newConditionObject
228235}
229236
230- async function initTagObject ( token , props ) {
237+ // Using any for token and props because they come from markdownlint library without full type definitions
238+ async function initTagObject ( token : any , props : any ) {
231239 const condTagItem = {
232240 name : token . name ,
233241 cond : token . content . replace ( `${ token . name } ` , '' ) . trim ( ) ,
@@ -245,15 +253,17 @@ async function initTagObject(token, props) {
245253 parent : props . parent ,
246254 }
247255 if ( token . name === 'ifversion' || token . name === 'elsif' ) {
248- condTagItem . versionsObj = await getApplicableVersionFromLiquidTag (
249- condTagItem . cond ,
250- props . filename ,
251- )
252- condTagItem . featureVersionsObj = condTagItem . versionsObj . feature
253- ? getFeatureVersionsObject ( condTagItem . versionsObj . feature )
256+ // Using any because these properties (versionsObj, featureVersionsObj, versionsObjAll, versions)
257+ // are added dynamically to condTagItem and not part of its initial type definition
258+ ; ( condTagItem as any ) . versionsObj = await getApplicableVersionFromLiquidTag ( condTagItem . cond )
259+ ; ( condTagItem as any ) . featureVersionsObj = ( condTagItem as any ) . versionsObj . feature
260+ ? getFeatureVersionsObject ( ( condTagItem as any ) . versionsObj . feature )
254261 : undefined
255- condTagItem . versionsObjAll = { ...condTagItem . versionsObj , ...condTagItem . featureVersionsObj }
256- condTagItem . versions = getApplicableVersions ( condTagItem . versionsObj , '' , {
262+ ; ( condTagItem as any ) . versionsObjAll = {
263+ ...( condTagItem as any ) . versionsObj ,
264+ ...( condTagItem as any ) . featureVersionsObj ,
265+ }
266+ ; ( condTagItem as any ) . versions = getApplicableVersions ( ( condTagItem as any ) . versionsObj , '' , {
257267 doNotThrow : true ,
258268 includeNextVersion : true ,
259269 } )
@@ -270,7 +280,8 @@ async function initTagObject(token, props) {
270280 Then create flaws per stack item.
271281 newCond
272282 */
273- function decorateCondTagItems ( condTagItems , lines ) {
283+ // Using any[] because condTagItems contains dynamic objects with action property added at runtime
284+ function decorateCondTagItems ( condTagItems : any [ ] ) {
274285 for ( const item of condTagItems ) {
275286 item . action = {
276287 type : 'none' ,
@@ -287,7 +298,8 @@ function decorateCondTagItems(condTagItems, lines) {
287298 return
288299}
289300
290- function updateConditionals ( condTagItems ) {
301+ // Using any[] because condTagItems contains dynamic objects with various properties added at runtime
302+ function updateConditionals ( condTagItems : any [ ] ) {
291303 // iterate through the ifversion, elsif, and else
292304 // tags but NOT the endif tag. endif tags have
293305 // no versions associated with them and are handled
@@ -470,7 +482,8 @@ function updateConditionals(condTagItems) {
470482 }
471483}
472484
473- function processConditionals ( item , condTagItems , indexOfAllItem ) {
485+ // Using any for item and any[] for condTagItems because they contain dynamic objects with action property
486+ function processConditionals ( item : any , condTagItems : any [ ] , indexOfAllItem : number ) {
474487 item . action . type = 'all'
475488 // if any tag in a statement is 'all', the
476489 // remaining tags are obsolete.
0 commit comments