Skip to content
jess
api

@jess/style

jess's Luau style checker: findings with rule ids, spans, and severities, over Luau's own parser, from the built-in package jess carries.

require('@jess/style'): { check, checkFile, checkPackage, files, format, markdownBlocks, rules, run, analysis, analyze, workspace }

The Luau style as a checker. It's an export of jess's built-in package, jpk/builtin, layer jess.style, which the binary carries, so every script can require it.

jess run check-style.jsl src jpk/builtin
--!strict
-- check-style.jsl: the findings in one source, as data.
local style = require '@jess/style'
local findings = style.check 'local Total = 0\nTotal += 1\nprint("total", Total)\n'

for _, finding in findings do
  print(style.format(finding, 'example.jsl'))
end
example.jsl:1:7: error[naming.case]: 'Total' is reassigned, so it isn't a constant: name it in camelCase
example.jsl:3:7: error[quotes.double]: single quotes: double quotes are for a string that holds a single quote

It parses with @dream/luau, so a file that doesn't parse gets syntax findings at Luau's own error positions, and the rest of the tree, which the parser recovers, is still checked.

style.check§

style.check(source: string, options: Options?) -> { Finding }

Every finding in source, sorted by position.

Finding fieldIs
ruleThe rule's id, such as pcall.comment; style.rules has them all.
severity'error' or 'warning'.
messageWhat's wrong and what the style wants instead.
line, column, endLine, endColumnThe span, 1-based, the end column inclusive, columns in bytes.
OptionDoes
profile'jess', the default, or 'lua' for plain Lua sources: no hoisting rule, PascalCase allowed for module-level and member-alias locals, LuaLS ---@param types read for truthiness.
directivesHot comments the file must start with, such as { 'strict', 'native' }.
noAnyReport every any type (types.any).
declarationstrue parses definition-file syntax (declare, declare extern type), false doesn't; left out, a source that only parses with it is taken for a definitions file.
onlyOnly these rules, by id. An unknown id is an error.
fragmentThe source is an excerpt, such as a block on a docs page: no local is taken for a module constant, since what the rest of the module does with it isn't there to see.

style.checkFile§

style.checkFile(path: string, options: Options?) -> { Finding }

style.check on a file. A .md file is checked one ```luau block at a time, as a fragment, with each finding's lines counted from the top of the page.

style.files§

style.files(paths: { string }) -> { string }

The .jsl and .lua files under each path, sorted. A path that's a file is kept whatever its extension; folders named target and dot-folders are skipped.

style.run§

style.run(paths: { string }, options: Options?) -> (number, number)

Checks every file style.files(paths) finds, prints each finding with style.format, and returns how many errors and how many warnings there were.

style.checkPackage§

style.checkPackage(root: string, payload: Options?) -> { string }

Every finding under the package folder root, each formatted with style.format and its path: what a package's own style test checks. Files in the payload, <root>/src/, are also held to payload, by default --!strict and no any; tests, benches, and tools follow the style alone.

--!strict
local style = require '@jess/style'
local test = require '@jess/test'

local suite = test.new()

suite.it('passes @jess/style', function()
  local root = string.match(debug.info(1, 's'), '^[@=]?(.*)/tests/[^/]*$') or '.'
  test.expect(table.concat(style.checkPackage(root), '\n')).toBe ''
end)

return suite

style.format§

style.format(finding: Finding, path: string?) -> string

One finding on one line: path:line:column: severity[rule]: message, or without the path.

style.markdownBlocks§

style.markdownBlocks(text: string) -> { { line: number, source: string } }

A Markdown page's ```luau blocks, each with the line its opening fence is on.

style.rules§

style.rules: { [string]: { severity: 'error' | 'warning', summary: string } }

Every rule by id, frozen. Luau Style has the table.

style.analysis, style.analyze, style.workspace§

The same values as @jess/analysis exports, re-exported so a style tool that also wants the dependency analysis needs one require.