chore: new config schema setup - #5357
Conversation
🦋 Changeset detectedLatest commit: dd0a5c7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 5 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Preview deployments for this pull request: storybook - themebuilder - www - |
There was a problem hiding this comment.
🟡 Changes recommended
Public-schema rejection, size-step validation, deprecation warnings, and release compatibility need correction.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Centralizes configuration defaults and validation in a unified schema, then drives token generation from the fully populated configuration.
Changes:
- Adds public and full schema views with validation and generated documentation.
- Makes token dimensions, typography, sizing, shadows, borders, and opacity configuration-driven.
- Updates CLI, Figma plugin, and theme builder integrations.
File summaries
| File | Description |
|---|---|
plugins/designsystemet/src/plugin/code.ts |
Uses two-stage config validation and dynamic dimensions. |
packages/cli/src/tokens/utils.ts |
Adds record-to-token and numeric-key helpers. |
packages/cli/src/tokens/types.ts |
Adds configuration-derived token types. |
packages/cli/src/tokens/process/platform.ts |
Determines typography defaults dynamically. |
packages/cli/src/tokens/process/output/theme.ts |
Orders arbitrary typography CSS sections. |
packages/cli/src/tokens/process/configs/typography.ts |
Supports configurable typography sets. |
packages/cli/src/tokens/process/configs/type-scale.ts |
Filters arbitrary typography primitives. |
packages/cli/src/tokens/process/configs/shared.ts |
Adds typography primitive detection. |
packages/cli/src/tokens/generate-config.ts |
Uses the public schema input type. |
packages/cli/src/tokens/format.ts |
Derives token dimensions per theme. |
packages/cli/src/tokens/create/generators/themes/theme.ts |
Generates configured radius and font-weight tokens. |
packages/cli/src/tokens/create/generators/semantic/style.ts |
Generates semantic tokens from configuration. |
packages/cli/src/tokens/create/generators/primitives/typography.ts |
Generates configurable typography primitives. |
packages/cli/src/tokens/create/generators/primitives/size.ts |
Generates configurable size scales. |
packages/cli/src/tokens/create/generators/primitives/globals.ts |
Generates configurable global primitives. |
packages/cli/src/tokens/create/generators/primitives/color-scheme.ts |
Updates schema import. |
packages/cli/src/tokens/create/generators/primitives/color-scheme.test.ts |
Updates schema type import. |
packages/cli/src/tokens/create/generators/$themes.ts |
Generates dynamic modes and identifiers. |
packages/cli/src/tokens/create/generators/$metadata.ts |
Generates dynamic token-set ordering. |
packages/cli/src/tokens/create.ts |
Builds token sets from schema values. |
packages/cli/src/scripts/update-preview-tokens.ts |
Uses the unified schema and dimensions. |
packages/cli/src/scripts/createJsonSchema.ts |
Generates the public JSON schema. |
packages/cli/src/scripts/create-full-json-schema.ts |
Generates the full JSON schema. |
packages/cli/src/scripts/create-example-config.ts |
Generates documented default configuration. |
packages/cli/src/schemas/v1/schema.ts |
Removes the legacy v1 schema. |
packages/cli/src/schemas/v1.1/schema.ts |
Removes the legacy v1.1 schema. |
packages/cli/src/schemas/schema.ts |
Defines full and public configuration schemas. |
packages/cli/src/schemas/schema.test.ts |
Tests schema validation and public contract. |
packages/cli/src/schemas/schema-typography.ts |
Defines typography defaults and normalization. |
packages/cli/src/schemas/schema-size.ts |
Defines size configuration defaults. |
packages/cli/src/schemas/schema-shadow.ts |
Defines shadow defaults. |
packages/cli/src/schemas/schema-overrides.ts |
Extracts override validation. |
packages/cli/src/schemas/schema-output.ts |
Defines output configuration and deprecations. |
packages/cli/src/schemas/schema-opacity.ts |
Defines opacity defaults. |
packages/cli/src/schemas/schema-color.ts |
Adds strict color-name validation. |
packages/cli/src/schemas/schema-border-width.ts |
Defines border-width defaults. |
packages/cli/src/schemas/schema-border-radius.ts |
Defines radius shorthand and full form. |
packages/cli/src/schemas/__snapshots__/config.schema.json |
Captures the public JSON schema. |
packages/cli/src/index.ts |
Re-exports the public unified schema. |
packages/cli/package.json |
Updates schema-generation scripts and exports. |
packages/cli/docs/designsystemet.config.defaults.json |
Documents the fully defaulted configuration. |
packages/cli/docs/design-tokens-structure.drawio |
Documents token architecture. |
packages/cli/bin/designsystemet.ts |
Integrates two-stage validation and dimensions. |
packages/cli/bin/config.ts |
Validates and populates CLI configuration. |
designsystemet.config.json |
References the full generated schema. |
biome.jsonc |
Excludes generated snapshots from formatting. |
apps/themebuilder/app/_components/token-modal/use-token-modal.ts |
Uses the external configuration input type. |
.changeset/ten-rabbits-relax.md |
Adds an empty changeset marker. |
.changeset/strict-color-names.md |
Records stricter color-name validation. |
Review details
- Files reviewed: 47/49 changed files
- Comments generated: 4
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
b69204b to
9d32e7d
Compare
91e6412 to
9013921
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Reserved or empty dimension names can overwrite token sets, and some invalid typography references bypass validation.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (2)
packages/cli/src/schemas/schema-size.ts:10
stepscurrently accepts both an empty record and the reserved nameglobal. An empty record creates no Size group and later producessize-mode/undefined.css; aglobalmode collides withprimitives/modes/size/globalincreate.ts, so the mode token set is overwritten. Reject both states in the schema.
steps: z
.record(
z.string(),
plugins/designsystemet/src/plugin/code.ts:64
- This comment says the public-schema result is discarded, but
externalConfigis passed directly toconfigSchemabelow. Update it to describe that the normalized/sanitized result is intentionally reused; the current wording contradicts the two-stage validation flow.
- Files reviewed: 48/50 changed files
- Comments generated: 2
- Review effort level: Balanced
d541235 to
24ab9bb
Compare
There was a problem hiding this comment.
🟡 Changes recommended
New full-schema fields permit invalid dimensions and unsafe or empty token-set identifiers that can produce invalid output or downstream build failures.
Get a fresh assessment by requesting another Copilot review.
Review details
Suppressed comments (1)
plugins/designsystemet/src/plugin/code.ts:64
- This comment says the public-schema result is discarded and that the full schema parses the original input, but the code correctly passes
externalConfigintoconfigSchema. Update the comment so it describes the actual normalization flow.
- Files reviewed: 48/50 changed files
- Comments generated: 4
- Review effort level: Balanced
There was a problem hiding this comment.
🔵 Needs a closer look
Empty typography sets pass validation, custom size-mode typing is unsound, and normalized CSS output settings break CSS-only generation.
Review details
Suppressed comments (2)
Previously missed (2) — in code that hasn't changed since the last review.
packages/cli/src/schemas/schema-typography.ts:109
- The full schema accepts
typography.fonts: {}, but every downstream generation path requires a first typography set (createTokensthrows attokens/create.ts:34-35). This makes a configuration pass schema validation and then fail during token generation. Require at least one entry here, as is already done forsize.steps.
packages/cli/src/tokens/create.ts:19 - Custom size-mode names are now valid, but this assertion hides that
SizeModesis still the closed'small' | 'medium' | 'large'union intokens/types.ts:42. For a validcompactmode, the exportedTokenSetDimensionsvalue contains data its type says is impossible. Broaden or deriveSizeModesfrom the new record-based schema instead of asserting here.
- Files reviewed: 48/50 changed files
- Comments generated: 0 new
- Review effort level: Balanced
|
waiting after release before merging this. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Michael Marszalek <mimarz@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Michael Marszalek <mimarz@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Michael Marszalek <mimarz@gmail.com>
30338f4 to
dd0a5c7
Compare
resolves #3807
In our current setup "defaults" and validation are handled in multiple places, split between the config schema and hard-coded values in the design-tokens generators.
As a first step this expands the schema with fields for all defaults that were defined in design-tokens (except colors, saved for a separate PR). This lays the groundwork for more configuration options for end users in JSON, JS and the theme builder.
The goal is to make it easier to:
Summary
One schema, two views
v1,v1.1andnext) are replaced by a single source inpackages/cli/src/schemas/, with one part file per area.configSchemais the full schema.externalConfigSchemais the public schema, derived from it withomit+pick+extend: the same top-level fields (outDir,clean,themes) and theme keys (colors,typography,borderRadius,overrides) users have today, withtypographylimited to the{ fontFamily }shorthand andborderRadiusto a number.config.schema.jsonis generated from the public schema.config-next.schema.jsonis renamed toconfig-full.schema.jsonand generated from the full schema. The rootdesignsystemet.config.jsonpoints its$schemaat the full one.src/schemas/__snapshots__/config.schema.json) guards the public JSON schema against accidental changes.configSchema/ConfigSchemaexports are unchanged and still refer to the public schema. Deep imports ofschemas/v1/schema.js,schemas/v1.1/schema.jsandschemas/next/schema.jsno longer resolve. The Figma plugin and the theme builder import fromschemas/schema.js.Validate with the public schema, populate with the full schema
tokens create --config, the (not yet enabled)configcommand and the Figma plugin validate a config in two steps:externalConfigSchemavalidates what the user wrote. Theme fields and shapes that are not part of the public config are rejected with a user-facing error, and shorthands (typography: { fontFamily },borderRadius: 4) are normalized.configSchemaparses the config to populate every internal default (size modes, size-mode typography, components, shadows, border widths, opacities).This keeps the public surface small while the generators always work on a fully defaulted config. Once a field is added to the public schema it flows through without further changes.
Output settings
outDirandcleanare unchanged and remain the public output settings, with the same defaults as before and no deprecation.outputarray from the oldnextschema now lives in the full schema only. It is not exposed yet, and is only read by theconfigcommand, which stays disabled.New config fields (full schema, not exposed)
typographyis restructured into named font sets, per-size-mode values and shared components:typography.fonts.<set>:fontFamilyandfontWeightper set (defaultsprimaryandsecondary).typography.size.<mode>:lineHeight,letterSpacingandfontSizeper size mode, mirroring theprimitives/modes/typography/size/<mode>token sets.typography.components: heading and body typography tokens, shared by all sets.{ fontFamily }shorthand still works and normalizes to this shape.size(scale formula and steps withbase,step,baseFontSize),borderWidth,shadowandopacityare new.borderRadiusalso accepts an object withsteps,baseandscale.packages/cli/docs/designsystemet.config.defaults.jsondocuments the fully defaulted config. It is regenerated bycreate-example-config.tsas part ofbuild:json-schema. A draw.io diagram of the design-tokens structure is added alongside it.Validation
typography.components(e.g.{font-size.4},{line-height.sm},{font-weight.medium}) are checked against the keys defined in the theme. Font-size and font-weight references must resolve in every size mode and every font set.size.stepsmust have a matching entry intypography.size.Design-tokens generation
$themes.jsonand$metadata.jsonare generated from the size modes and typography sets in the config instead of fixed lists. The known Figma ids are kept for the default modes and sets; custom ones get a hashed id.primaryandsecondary: the first typography set becomes the:rootdefault, primitives are filtered for any set name, and the entry-file section order follows default/non-default instead of the name.createTokenstakes the token set dimensions (color schemes, size modes, typography sets) derived from the first theme.--font-familyCLI option is only applied when explicitly supplied, so it does not clobber a config that defines named typography sets.Figma plugin and theme builder
ExternalConfigSchemaInputfor the config it generates.