Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .doxygen/frame.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
document.addEventListener("DOMContentLoaded", () => {
if (window.parent.location == window.location) {
if (window.parent.location === window.location) {
document.body.classList.add("not-inside-iframe")
} else {
document.body.classList.add("inside-iframe")
Expand Down
6 changes: 3 additions & 3 deletions oxlint.json → .oxlintrc.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/crates/oxc_linter/src/schemas/oxlint.json",
"rules": {
"@typescript-eslint/no-unused-vars": "error",
"no-unused-vars": ["error", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_", "caughtErrorsIgnorePattern": "^_" }],
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_", "caughtErrorsIgnorePattern": "^_" }],
"@typescript-eslint/prefer-nullish-coalescing": "warn",
"@typescript-eslint/prefer-optional-chain": "warn",
"no-console": "off",
"no-debugger": "error",
"no-unused-vars": "error",
"prefer-const": "error",
"eqeqeq": "error"
},
Expand All @@ -18,7 +18,7 @@
"globals": {
"globalThis": "readonly"
},
"ignore": [
"ignorePatterns": [
"**/node_modules/**",
"**/dist/**",
"**/build/**",
Expand Down
6 changes: 0 additions & 6 deletions docs/.vitepress/generate-rules.mts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@ export function generateRuleWrappers() {
const ruleFiles = files.filter(file => file.endsWith(".md") && file !== "README.md")

ruleFiles.forEach(file => {
const ruleName = file.replace(".md", "")
const displayName = ruleName
.split("-")
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ")

const wrapperContent = `<!-- @include: ../../../../javascript/packages/linter/docs/rules/${file} -->`

const targetPath = path.join(targetRulesDir, file)
Expand Down
1 change: 0 additions & 1 deletion docs/.vitepress/theme/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { EnhanceAppContext } from "vitepress"
import Theme from "vitepress/theme"
import { h } from "vue"
import { onMounted, watch, nextTick } from 'vue'
import { useRoute } from 'vitepress'
import mediumZoom from 'medium-zoom'
Expand Down
5 changes: 2 additions & 3 deletions docs/.vitepress/transformers/herb-linter-transformer.mts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { createPositionConverter } from "twoslash-protocol"

import { Herb } from '@herb-tools/node'
import { Linter } from '@herb-tools/linter'
import type { LintContext } from '@herb-tools/linter'

export interface LinterDiagnostic {
line: number
Expand All @@ -17,8 +16,8 @@ export interface LinterDiagnostic {
}

// Create custom Twoslash function for linter diagnostics
function createCustomTwoslashFunction(optionse) {
return (code, lang, options) => {
function createCustomTwoslashFunction(_options) {
return (code, lang, _options) => {
let fileName = undefined

// kind of a hack to make sure we pass a `fileName` for the `erb-require-trailing-newline` rule
Expand Down
1 change: 0 additions & 1 deletion javascript/packages/config/rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import typescript from "@rollup/plugin-typescript"
import json from "@rollup/plugin-json"
import { nodeResolve } from "@rollup/plugin-node-resolve"
import { readFileSync } from "fs"
import { yaml } from "./yaml-plugin.mjs"

export default [
Expand Down
101 changes: 49 additions & 52 deletions javascript/packages/config/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ export class Config {
}
}

if (/^ [a-z][\w-]*:/.test(line) && prevLine && /^ /.test(prevLine)) {
if (/^ [a-z][\w-]*:/.test(line) && prevLine && prevLine.startsWith(' ')) {
result.push('')
}

Expand Down Expand Up @@ -976,7 +976,7 @@ export class Config {
if (!silent) {
console.error(`✓ Created default configuration at ${configPath}`)
}
} catch (error) {
} catch (_error) {
if (!silent) {
console.error(`⚠ Could not create config file at ${configPath}, using defaults in-memory`)
}
Expand Down Expand Up @@ -1090,69 +1090,66 @@ export class Config {
version: string,
exitOnError: boolean = false
): Promise<Config> {
try {
const content = await fs.readFile(configPath, "utf8")
const content = await fs.readFile(configPath, "utf8")

let parsed: any
try {
parsed = parse(content)
} catch (error) {
if (exitOnError) {
console.error(`\n✗ Invalid YAML syntax in ${configPath}`)
let parsed: any

if (error instanceof Error) {
console.error(` ${error.message}\n`)
}
process.exit(1)
} else {
throw new Error(`Invalid YAML syntax in ${configPath}: ${error instanceof Error ? error.message : String(error)}`)
try {
parsed = parse(content)
} catch (error) {
if (exitOnError) {
console.error(`\n✗ Invalid YAML syntax in ${configPath}`)

if (error instanceof Error) {
console.error(` ${error.message}\n`)
}
process.exit(1)
} else {
throw new Error(`Invalid YAML syntax in ${configPath}: ${error instanceof Error ? error.message : String(error)}`)
}
}

if (parsed === null || parsed === undefined) {
parsed = {}
}
if (parsed === null || parsed === undefined) {
parsed = {}
}

if (!parsed.version) {
parsed.version = version
}
if (!parsed.version) {
parsed.version = version
}

try {
HerbConfigSchema.parse(parsed)
} catch (error) {
if (error instanceof ZodError) {
const validationError = fromZodError(error, {
prefix: `Configuration errors in ${configPath}`,
})

if (exitOnError) {
console.error(`\n✗ ${validationError.toString()}\n`)

process.exit(1)
} else {
throw new Error(validationError.toString())
}
}
try {
HerbConfigSchema.parse(parsed)
} catch (error) {
if (error instanceof ZodError) {
const validationError = fromZodError(error, {
prefix: `Configuration errors in ${configPath}`,
})

throw error
}
if (exitOnError) {
console.error(`\n✗ ${validationError.toString()}\n`)

if (parsed.version && parsed.version !== version) {
console.error(`\n⚠️ Configuration version mismatch in ${configPath}`)
console.error(` Config version: ${parsed.version}`)
console.error(` Current version: ${version}`)
console.error(` Consider updating your .herb.yml file.\n`)
process.exit(1)
} else {
throw new Error(validationError.toString())
}
}

const defaults = this.getDefaultConfig(version)
const resolved = deepMerge(defaults, parsed as Partial<HerbConfig>)

resolved.version = version

return new Config(projectRoot, resolved)
} catch (error) {
throw error
}

if (parsed.version && parsed.version !== version) {
console.error(`\n⚠️ Configuration version mismatch in ${configPath}`)
console.error(` Config version: ${parsed.version}`)
console.error(` Current version: ${version}`)
console.error(` Consider updating your .herb.yml file.\n`)
}

const defaults = this.getDefaultConfig(version)
const resolved = deepMerge(defaults, parsed as Partial<HerbConfig>)

resolved.version = version

return new Config(projectRoot, resolved)
}

/**
Expand Down
2 changes: 1 addition & 1 deletion javascript/packages/config/src/vscode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function readExtensionsJson(filePath: string): VSCodeExtensionsJson {
}

return parsed
} catch (error) {
} catch (_error) {
console.warn(`Warning: Could not parse ${filePath}, creating new file`)

return { recommendations: [] }
Expand Down
2 changes: 1 addition & 1 deletion javascript/packages/core/src/ast-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export function isERBCommentNode(node: Node): node is ERBCommentNode {
if (!isERBNode(node)) return false
if (!node.tag_opening?.value) return false

return node.tag_opening?.value === "<%#" || (node.tag_opening?.value !== "<%#" && (node.content?.value || "").trimStart().startsWith("#"))
return node.tag_opening?.value === "<%#" || (node.tag_opening?.value !== "<%#" && (node.content?.value || "").trimStart().startsWith("#"))
}


Expand Down
2 changes: 1 addition & 1 deletion javascript/packages/core/test/node-type-guards.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ describe('Node Type Guards', () => {
})

it('should handle large arrays', () => {
const manyLiterals = new Array({ length: 100 }).fill(literalNode)
const manyLiterals = Array.from({ length: 100 }).fill(literalNode)
expect(areAllOfType(manyLiterals, LiteralNode)).toBe(true)
expect(areAllOfType(manyLiterals, HTMLTextNode)).toBe(false)
})
Expand Down
2 changes: 1 addition & 1 deletion javascript/packages/dev-tools/src/error-overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export class ErrorOverlay {

htmlTemplates.forEach((template, _index) => {
try {
let htmlContent = template.innerHTML?.trim() || template.textContent?.trim();
const htmlContent = template.innerHTML?.trim() || template.textContent?.trim();

if (htmlContent) {
this.displayParserErrorOverlay(htmlContent);
Expand Down
8 changes: 4 additions & 4 deletions javascript/packages/dev-tools/src/herb-overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ export class HerbOverlay {
if (element.localName === 'html' || window.getComputedStyle(element).overflowY !== 'visible') {
label.style.top = '0';
}

if (window.getComputedStyle(element).position === 'static') {
element.style.position = 'relative';
}
Expand Down Expand Up @@ -586,7 +586,7 @@ export class HerbOverlay {
const elements = document.querySelectorAll('[data-herb-debug-showing-erb')

elements.forEach(element => {
const originalContent = element.getAttribute('data-herb-debug-original') || "";
const originalContent = element.getAttribute('data-herb-debug-original') || "";

element.innerHTML = originalContent;
element.removeAttribute("data-herb-debug-showing-erb")
Expand Down Expand Up @@ -617,7 +617,7 @@ export class HerbOverlay {
this.addTooltipHoverHandler(element);
}
} else {
const originalContent = element.getAttribute('data-herb-debug-original') || "";
const originalContent = element.getAttribute('data-herb-debug-original') || "";

if (element && element.hasAttribute("data-herb-debug-showing-erb")) {
element.innerHTML = originalContent;
Expand Down Expand Up @@ -1055,7 +1055,7 @@ export class HerbOverlay {
if (url) {
try {
window.open(url, '_self');
} catch (error) {
} catch (_error) {
console.log(`Open in editor: ${absolutePath}:${line}:${column}`);
}
} else {
Expand Down
9 changes: 4 additions & 5 deletions javascript/packages/formatter/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ export class CLI {
this.determineProjectPath(positionals)

const file = positionals[0]
const startPath = file || process.cwd()

if (isInitMode) {
const configPath = configFile || this.projectPath
Expand Down Expand Up @@ -220,8 +219,8 @@ export class CLI {
formatterConfig.maxLineLength = maxLineLength
}

let preRewriters: ASTRewriter[] = []
let postRewriters: StringRewriter[] = []
const preRewriters: ASTRewriter[] = []
const postRewriters: StringRewriter[] = []
const rewriterNames = { pre: formatterConfig.rewriter?.pre || [], post: formatterConfig.rewriter?.post || [] }

if (formatterConfig.rewriter && (rewriterNames.pre.length > 0 || rewriterNames.post.length > 0)) {
Expand Down Expand Up @@ -420,7 +419,7 @@ export class CLI {
}

let formattedCount = 0
let unformattedFiles: string[] = []
const unformattedFiles: string[] = []

for (const filePath of files) {
const displayPath = relative(process.cwd(), filePath)
Expand Down Expand Up @@ -468,7 +467,7 @@ export class CLI {
}

let formattedCount = 0
let unformattedFiles: string[] = []
const unformattedFiles: string[] = []

for (const filePath of files) {
const displayPath = relative(process.cwd(), filePath)
Expand Down
6 changes: 3 additions & 3 deletions javascript/packages/formatter/src/format-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export function isClosingPunctuation(word: string): boolean {
* Check if a line ends with opening punctuation
*/
export function lineEndsWithOpeningPunctuation(line: string): boolean {
return /[(\[]$/.test(line)
return /[([]$/.test(line)
}

/**
Expand All @@ -185,14 +185,14 @@ export function isERBTag(text: string): boolean {
export function endsWithERBTag(text: string): boolean {
const trimmed = text.trim()

return /%>$/.test(trimmed) || /%>\S+$/.test(trimmed)
return trimmed.endsWith('%>') || /%>\S+$/.test(trimmed)
}

/**
* Check if a string starts with an ERB tag
*/
export function startsWithERBTag(text: string): boolean {
return /^<%/.test(text.trim())
return text.trim().startsWith('<%')
}

/**
Expand Down
6 changes: 3 additions & 3 deletions javascript/packages/formatter/src/format-printer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,11 +309,11 @@ export class FormatPrinter extends Printer {
* and a trailing space (or newline for heredoc content starting with "<<").
*/
private formatERBContent(content: string): string {
let trimmedContent = content.trim();
const trimmedContent = content.trim();

// See: https://github.com/marcoroth/herb/issues/476
// TODO: revisit once we have access to Prism nodes
let suffix = trimmedContent.startsWith("<<") ? "\n" : " "
const suffix = trimmedContent.startsWith("<<") ? "\n" : " "

return trimmedContent ? ` ${trimmedContent}${suffix}` : ""
}
Expand Down Expand Up @@ -1264,7 +1264,7 @@ export class FormatPrinter extends Printer {
return
}

let text = node.content.trim()
const text = node.content.trim()

if (!text) return

Expand Down
2 changes: 1 addition & 1 deletion javascript/packages/formatter/src/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export class Formatter {
* Format a source string, optionally overriding format options per call.
*/
format(source: string, options: FormatOptions = {}, filePath?: string): string {
let result = this.parse(source)
const result = this.parse(source)

if (result.failed) return source
if (isScaffoldTemplate(result)) return source
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { describe, test, expect, beforeAll } from "vitest"
import { describe, test, beforeAll } from "vitest"
import { Herb } from "@herb-tools/node-wasm"
import { Formatter } from "../../src"
import { createExpectFormattedToMatch } from "../helpers"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ describe("ERB whitespace formatting", () => {

expect(result).toEqual(expected)
})
}),
})

test("documents current behavior for ERB logic tags", () => {
const logicCases = ['<% if condition%>', '<%end%>']
Expand Down
Loading
Loading