Skip to content

Compile-time validation for string constraints (length, character set) via a pattern option #72

Description

@k0d13

Problem

Some strings have constraints beyond their literal content: a fixed max length (fits a button, a tab label), or a restricted character set (no punctuation, digits only). Translators can easily produce a string that's technically a valid translation but breaks the constraint - too long, too short, or containing characters the UI can't handle. Today that only surfaces at runtime (or visually, after the fact), not at compile time.

Idea

Let a string declare its own constraint, and catch violations against translated strings as part of the build/typecheck step rather than at runtime. Something like:

say({ pattern: /^.{1,12}$/ })`Save`

or as a component prop:

<Say pattern="^[A-Za-z0-9 ]{1,20}$">Save changes</Say>

Any translation that fails the pattern would fail the build (or at least surface as a lint-style warning) instead of shipping.

Prior art / is there a standard for this?

Checked whether existing i18n formats have a convention for this so saykit could align to it rather than invent something:

  • Gettext PO: no built-in support. Comments and flags exist (#, fuzzy, etc.) but nothing for length/charset validation.
  • WebExtension messages.json: supports placeholders with example content, but no validation/constraint fields.
  • ARB (Application Resource Bundle): supports @key metadata like description and placeholder example, but nothing for pattern/length constraints.

None of the major file formats have this as a first-class, standardized concept. Where it exists at all, it's a platform-level feature bolted on by a TMS - Crowdin, Lokalise, and Phrase all have their own proprietary "QA checks" / "validation rules" config (max length, forbidden characters, etc.), separate from and not portable across the underlying file format.

So there's no standard to match here - if saykit does this, it'd be one of the few tools offering it at the source/type level instead of as a TMS dashboard feature. Worth deciding whether the constraint should live in the source call (say/Say) or as metadata alongside the extracted string catalog, since a TMS-side check would need to read it from somewhere.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions