ESLint rule collection for AbsoluteJS applications and packages.
absolute/progressbar-has-state requires Vue progressbars to make their state
explicit: determinate meters expose aria-valuenow, while indeterminate
loaders use aria-busy or data-beacon-loading. This preserves valid ARIA
semantics and lets runtime watchdogs distinguish persistent meters from loads.
absolute/modal-has-focus-management requires every Vue element that declares
aria-modal="true" to expose the structural hooks a host needs for the modal
focus lifecycle: a template ref for initial focus and restoration coordination,
a tabindex fallback when it has no focusable children, and a keydown handler
for Tab containment. The rule cannot prove runtime focus behavior; pair it with
an accessibility runtime signal or browser test.
absolute/dialog-has-focus-restoration covers the complementary close side of
the lifecycle for modal and non-modal dialogs. Every literal role="dialog" or
native <dialog> must expose a template ref and a @vue:before-unmount
handler. The ref lets the handler determine whether the dialog owns focus, and
the lifecycle hook covers local conditional removal as well as a parent
unmounting the complete dialog component. The rule is structural: the
handler's runtime focus destination still requires a browser test or
accessibility signal.
absolute/elysia-composition-boundaries prevents a route application from
being extended through a second variable such as
const adminApp = publicApp.get(...). Each route surface must start from its
own named new Elysia(...), install shared dependencies explicitly, and be
mounted at a shallow root. This keeps TypeScript from repeatedly instantiating
the accumulated server graph and preserves real sub-app types for Eden.
The rule also auto-fixes adjacent plugin chains:
new Elysia().use(auth).use(metrics);becomes:
new Elysia().use([auth, metrics]);Chains containing comments are reported without an automatic rewrite so the ordering rationale cannot be lost.
absolute/no-inline-prop-types remains the narrow compatibility rule for
destructured component props. It is intentionally distinct from the broader
absolute/no-inline-object-types policy so upgrades do not silently expand a
repository's lint surface.
absolute/elysia-route-boundaries makes the corresponding file architecture
enforceable without filename or symbol-name conventions. It detects Elysia
route registration chains, exported route factories, their actual inferred
type references, and terminal composed graphs from AST structure and symbol
resolution. Configured composition entrypoints may assemble route surfaces but
may not register routes themselves; configured route directories require
isolated exported contracts. Route factories elsewhere remain valid. The rule
reports cross-file extractions without autofixing them because captured services
and route closures must become explicit factory dependencies.
absolute/eden-requires-react-query requires browser Eden Treaty requests to
execute inside a TanStack React Query queryFn or mutationFn. The rule follows
aliased React Query imports, same-file helper functions, and request closures
passed through mutate or mutateAsync, without depending on application client,
component, or endpoint names.
absolute/elysia-no-response-return prevents Elysia application handlers from
returning Response.json(...) or new Response(...), including through
same-file helpers. Routes retain their inferred Eden contract by returning plain
typed data, status(...), or redirect(...). Exact streaming, file, and HTML
route paths can allow new Response(...); Response.json(...) remains forbidden
because JSON application data never needs the Fetch escape hatch.
absolute/no-unsafe-schema-types rejects TypeBox Any, Unknown, and
Unsafe escape hatches, plus Drizzle $type declarations containing any or
unknown. Drizzle JSON annotations are compile-time promises, not runtime
validation; use a bounded type derived from the runtime schema and validate
untrusted input before persistence.
absolute/prefer-drizzle-query-builders rejects .unsafe() and sql.raw()
calls, and recognizes raw Drizzle SQL templates that have direct typed
equivalents such as eq, gte, isNull, inArray, like, and desc.
It also rejects arrays interpolated directly into sql templates because
Drizzle expands them as SQL tuples rather than encoded database-array values.
Use inArray or sql.join for lists and sql.param(value, columnEncoder) for
one database array value.
Generic row annotations on raw client queries are only compile-time assertions;
they do not apply Drizzle's runtime column decoders. SQL templates remain
available for database features that Drizzle cannot express, including JSONPath
and aggregate/window expressions.
absolute/timestamp-with-timezone requires withTimezone: true on every
Drizzle timestamp column, and fixes the ones it can.
A timestamp column holds an instant, and timestamp without time zone cannot.
The driver writes a Date as its UTC wall clock and reads a naive value back
as local, so a process outside UTC reads every one of them late by its own
offset. Postgres compares them correctly — it reads them in the session's zone,
which is what they were written in — so nothing looks wrong until something
compares one against the clock in JavaScript. Then a token that expired hours
ago reads as valid, a lease nobody holds reads as held, and a scheduled run is
skipped, with the data insisting all three are fine.
The fix is the same every time and costs nothing, so the rule asks for it on
every column rather than waiting for one to become load-bearing. date and
time columns are untouched: a birthday and an opening hour are wall clocks,
and a zone on either would be a different kind of wrong. Settings handed over
as a variable are skipped, since they can be neither read nor appended to.