Skip to content

Commit 6554f77

Browse files
committed
Add JSDoc types to validate-snippets.js
1 parent 0e9c84e commit 6554f77

File tree

1 file changed

+52
-45
lines changed

1 file changed

+52
-45
lines changed

scripts/validate-snippets.js

Lines changed: 52 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,61 @@
11
#!/usr/bin/env node
2+
// @ts-check
23

34
import fs from "node:fs"
45
import path from "node:path"
5-
import glob from "glob"
6+
import glob from "fast-glob"
67
import { parse } from "graphql"
7-
import chalk from "chalk"
88
import { fileURLToPath } from "node:url"
99

1010
const __filename = fileURLToPath(import.meta.url)
1111
const __dirname = path.dirname(__filename)
1212
const projectRoot = path.resolve(__dirname, "../")
1313

14+
/** @type {string} Glob pattern for MDX files to validate */
1415
const MDX_GLOB = "./src/pages/learn/**/*.mdx"
16+
/** @type {RegExp} Regex to match code blocks in markdown */
1517
const CODE_BLOCK_REGEX = /^(`{3,})(\w+)\s*\n([\s\S]*?)\r?\n\1$/gm
18+
/** @type {string} Comment to ignore code snippets */
1619
const IGNORE_COMMENT = "snippet-ignore"
1720

21+
/** @type {number} */
1822
let totalFiles = 0
23+
/** @type {number} */
1924
let totalSnippets = 0
25+
/** @type {number} */
2026
let totalErrors = 0
2127

22-
// TODO: Add JS linting after JS code snippet modernization
23-
// async function lintJavaScript(code, filePath) {
24-
// const eslint = new ESLint({
25-
// useEslintrc: true,
26-
// baseConfig: {
27-
// parserOptions: {
28-
// ecmaVersion: "latest",
29-
// sourceType: "module",
30-
// },
31-
// },
32-
// })
33-
34-
// let preparedCode = code.trim()
35-
36-
// if (preparedCode.startsWith("function")) {
37-
// preparedCode = "/* eslint-disable no-unused-vars */\n" + preparedCode
38-
// }
39-
40-
// const results = await eslint.lintText(preparedCode, { filePath })
41-
// return results.flatMap(result => result.messages)
42-
// }
28+
/**
29+
* @typedef {{ message: string }} ParseError
30+
*/
4331

32+
/**
33+
* @param {string} code
34+
* @returns {ParseError[]}
35+
*/
4436
function validateGraphQL(code) {
4537
try {
4638
parse(code)
4739
return []
4840
} catch (error) {
49-
return [{ message: error.message }]
41+
return [{ message: error instanceof Error ? error.message : String(error) }]
5042
}
5143
}
5244

45+
/**
46+
* @typedef {{
47+
* lang: string,
48+
* code: string,
49+
* lineNumber: number,
50+
* filePath: string
51+
* }} Snippet
52+
53+
/**
54+
* Extracts code snippets from MDX content
55+
* @param {string} content - The MDX file content
56+
* @param {string} filePath - The path to the file being processed
57+
* @returns {Snippet[]} Array of extracted code snippets
58+
*/
5359
function extractSnippets(content, filePath) {
5460
const snippets = []
5561
let match
@@ -69,43 +75,48 @@ function extractSnippets(content, filePath) {
6975
return snippets
7076
}
7177

78+
/**
79+
* @typedef {{
80+
* type: string,
81+
* file: string,
82+
* line: number,
83+
* message: string
84+
* }} ValidationError
85+
*/
86+
87+
/**
88+
* @param {Snippet} snippet - The code snippet to validate
89+
* @returns {Promise<ValidationError[]>} Array of validation errors
90+
*/
7291
async function validateSnippet(snippet) {
7392
const { lang, code, lineNumber, filePath } = snippet
7493

7594
if (!code.trim()) return []
7695

77-
// TODO: Add section after JS code snippet modernization
78-
// if (["js", "javascript", "ts", "typescript"].includes(lang)) {
79-
// const messages = await lintJavaScript(code, filePath)
80-
// return messages.map(msg => ({
81-
// type: "JS/TS",
82-
// file: filePath,
83-
// line: lineNumber + (msg.line || 1),
84-
// message: msg.message,
85-
// }))
86-
// }
87-
8896
if (lang === "graphql") {
8997
const messages = validateGraphQL(code)
9098
return messages.map(msg => ({
9199
type: "GraphQL",
92100
file: filePath,
93-
line: lineNumber + (msg.line || 1),
101+
line: lineNumber,
94102
message: msg.message,
95103
}))
96104
}
97105

98106
return []
99107
}
100108

109+
/**
110+
* @returns {Promise<void>}
111+
*/
101112
async function main() {
102-
console.log(`Validating code snippets in: ${projectRoot}/${MDX_GLOB}`)
113+
console.log(`Validating code snippets in: ${MDX_GLOB}`)
103114

104115
const files = glob.sync(MDX_GLOB, { cwd: projectRoot })
105116
totalFiles = files.length
106117

107118
if (totalFiles === 0) {
108-
console.log(chalk.green("No MDX files found to validate."))
119+
console.log("No MDX files found to validate.")
109120
return
110121
}
111122

@@ -127,25 +138,21 @@ async function main() {
127138
if (totalErrors > 0) {
128139
errors.forEach(err => {
129140
const errorMessage = `${err.type} Error in ${err.file} at line ${err.line}: ${err.message}`
130-
console.error(chalk.red(errorMessage))
141+
console.error(errorMessage)
131142

132143
if (process.env.GITHUB_ACTIONS) {
133144
console.log(`::error file=${err.file},line=${err.line}::${err.message}`)
134145
}
135146
})
136147

137-
console.error(
138-
chalk.red("\nCode snippet validation failed. Check error logs."),
139-
)
148+
console.error("\nCode snippet validation failed. Check error logs.")
140149
console.error(`Files checked: ${totalFiles}`)
141150
console.error(`Snippets checked: ${totalSnippets}`)
142151
console.error(`Errors found: ${totalErrors}`)
143152
process.exit(1)
144153
} else {
145154
console.log(
146-
chalk.green(
147-
"\nCode snippet validation passed. All code snippets are valid.",
148-
),
155+
"\n✅ Code snippet validation passed. All code snippets are valid.",
149156
)
150157
console.log(`Files checked: ${totalFiles}`)
151158
console.log(`Snippets checked: ${totalSnippets}`)

0 commit comments

Comments
 (0)