@teacss/config
v0.10.11
Published
TeaCSS config loader — discovers the CSS entry and resolves its directives into a config (no teacss.config file).
Readme
@teacss/config
Discovery and parsing for TeaCSS CSS-entry configuration.
TeaCSS has no teacss.config.* file. Entry discovery checks
package.json#teacss.entry, index.css, then src/index.css.
@presets "standard";
@source "./src/**/*.{ts,tsx}";
@custom {
--color-brand-500: #58a6ff;
}
@teacss;The built-in preset names are standard, official, and icons.
Official does not enable Standard. Package and local-file preset
specifiers are also supported.
@source globs match files. A path that names a directory, such as "./src",
matches every file under it, as "./src/**" does. As in teacss-rs, the scan
never walks into .git or any other entry whose name starts with . below the
entry's directory, even when a glob spells the name. It walks a node_modules
the glob's path spells, such as "./node_modules/pkg/dist/**", but no other
node_modules, including any below the spelled one.
import { createRecoveryConfigLoader } from "@teacss/config";
const loadConfig = createRecoveryConfigLoader();
const { config, sources } = await loadConfig(process.cwd());sources contains the CSS entry, imported and sourced CSS, package preset entry
files, and static local preset dependency graphs. Build integrations watch this
list. Package dependency trees and dynamic imports are excluded. Local preset
entries may use top-level await; transitive
dependencies must stay synchronous and statically discoverable.
The recovery loader keeps the last valid configuration during temporary edit
errors. Recovery state is isolated by entry path or inline-config identity, and
missing dependency candidates remain in sources so file creation can trigger
a retry.
Failed loads also retain imported stylesheets, resolved package entries, and
dependencies found before a later specifier failed to resolve.
Local preset transforms use a bounded content-addressed cache under the nearest
node_modules/.cache/teacss/preset-transform. Set
TEACSS_PRESET_TRANSFORM_CACHE=false to disable it.
Lower-level APIs:
| API | Purpose |
| ------------------------------------- | ------------------------------------------------------------ |
| resolveEntryConfig | Resolves an entry and returns its source graph. |
| entryDiscoveryFiles | Lists files an integration should watch for entry selection. |
| getConfigSourcesFromError | Recovers bounded source candidates from a failed load. |
| parseEntry | Parses a complete CSS entry. |
| scanTopLevelAtRules | Finds top-level TeaCSS directives safely. |
| scanCustomBlocks / diagnoseCustom | Parses and diagnoses @custom blocks. |
The internal @teacss/config/internal/source-scan export provides
scanSourceFiles(patterns, { cwd, ignore, expandDirectories, skipBelowBase }) for
TeaCSS integrations. It returns unique absolute lexical filenames through one
tinyglobby traversal. skipBelowBase names the entries no traversal lists or
enters below a pattern's base, while the base's own path is still walked; a
pattern whose base lies below another's through such a name gets a traversal of
its own, so each pattern matches only what its own traversal reaches. The
filesystem adapter avoids listing ordinary ancestors when bounded metadata
queries establish one directory's native spelling. It compares native
canonical results for the original and alternate ASCII case. Uncertain identity,
metadata errors, symlinks, exact file leaves and multiple planned siblings require
a cached, one-level parent-name query. These queries retain native names and
sibling order, but filter out unplanned children before the crawler processes
them. A proven strict-ancestor directory alias can be presented as a directory
when a later alias on the same route would otherwise create a false crawler cycle;
positive recursive source boundaries retain their native types. A necessary query
may read the filesystem root; it does not enter unrelated
directory trees. Input-preserving canonical APIs and non-ASCII names can require
more parent queries. Exact files do not depend on a planning stat succeeding.
A followed source symlink admits its target only along that traversal's callbacks.
Excluded links cannot authorize reads on other branches. Exclusions retain their
original matching coordinates. Parent files precede descendant files; independent
subtree completion remains asynchronous. Callers own default patterns, file reads,
extraction and dependency registration.
The direct picomatch dependency parses static prefixes, including escapes, braces
and extglobs; tinyglobby owns all matching and crawler behavior.
Internal watch planning returns verified plans and original permission errors
separately. Native stat, lstat, or readlink EACCES preserves accessible
shallow ancestry and healthy source plans without inventing directory identities
or recursive permission. The registry reports those errors after committing
the usable watches; existing native events observe source-only permission repair.
Other unexpected planning errors still propagate immediately.
This package does not extract application utilities, generate CSS, or manage a build tool's lifecycle.
When an entry changes, resolve it again and replace the generator configuration with the complete new result:
const next = await resolveEntryConfig(nextCss, entryDirectory, entryFile);
await generator.setConfig(next.config);For staged updates, pass next.config to prepareConfig() and commit the
prepared result. Do not merge the new entry result with a previous entry snapshot:
presets with the same name retain the first occurrence, which can preserve old
palette candidates after a list changes or is removed. Apply application options
to each fresh result instead. The built-in runtime reloads entries this way.
Pre-1.0. Keep behavior aligned across build, CLI, and editor integrations.
Palette configuration
@presets "standard,icons,official"; preserves ordered, quoted CSV module names.
Repeated declarations append; imported relative paths rebase per item.
Old @preset, malformed lists and nested configuration directives fail.
With Standard enabled, @primary "red,blue"; enables DOM selections through
data-css-primary. The same syntax applies to neutral, success, warning,
failure and general. Focused follows neutral by default; the site binds it once
with @custom focused "primary"; or a palette target. @focused lists are removed. Repeated/imported lists union; sources are complete physical palettes
with no role dependencies. @custom defines base values, @custom dark color
overrides. Whole-theme variants are removed. Configuration failures retain original alias source ranges and
import/preset dependency paths for editor and development-server recovery.
Color alias statements
@custom office "indigo"; expands all 12 scale steps plus 000 into
var(--color-indigo-<step>) references (000 has a white fallback). It registers
in the entry and followed imports, never through @source. Color utilities,
alpha and conditions consume the alias normally. Mode blocks override base
values regardless of their position; within a base or mode block, later values win.
Names use lowercase kebab-case and cannot end in a numeric segment. Non-role
aliases cannot reuse built-in palettes, prior aliases or a complete custom base
palette formed before the statement. Sparse earlier declarations and later
per-step overrides are allowed. Targets must have all 12 effective steps in
base and modes and cannot be aliases or roles; only focused may follow
primary or neutral, including rebound roles. Targets may be declared later.
Seven role names can be rebound repeatedly, with the last binding winning.
Alias names never become selectable role-list candidates.
customToTheme(blocks, themeKeys) retains its low-level patch interface.
The shared semantic compiler resolveCustomTheme(blocks, baseline) validates
against resolved preset values and palette identities and reports
EntryConfigError.diagnostics with original file/range locations.
Source declaration loading requires a complete enumeration. Native enumeration
errors retain the original cause after the traversal finishes, so recovery keeps
the accepted shortcuts and safelists. Missing paths, non-directory components, and
link cycles remain topology absence. Generic scanSourceFiles callers retain
tinyglobby's existing error suppression.
