Skip to content

feat: add Unicode MessageFormat 1 support via a configurable format attribute - #37

Merged
jsahleen merged 8 commits into
mainfrom
msg-33
Jul 19, 2026
Merged

feat: add Unicode MessageFormat 1 support via a configurable format attribute#37
jsahleen merged 8 commits into
mainfrom
msg-33

Conversation

@jsahleen

@jsahleen jsahleen commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

Closes #33.

Adds support for formatting MF1, MF2, and NONE strings via a new, inheritable format attribute.

  • Why: consumers need to mix ICU MessageFormat 1 and MessageFormat 2 strings (and plain, non-formatted strings) within a single project.
  • What:
    • New MsgFormat union type ('MF1' | 'MF2' | 'NONE', not an enum) and a format attribute; defaults to MF2 for backwards compatibility.
    • Project-level format; resources inherit from the project and messages inherit from their resource unless they specify their own.
    • MsgMessage.format / formatToParts branch on the resolved format: MF2MessageFormat, MF1mf1ToMessage from @messageformat/icu-messageformat-1, NONE → the raw string (a single text part for formatToParts).
    • Serialization omits format on a resource when it equals the project's, and on a message when it equals its resource's.
    • translate() preserves the source resource's and each message's format unless the translation overrides it.
    • Aligns messageformat to 4.0.0 (stable) so mf1ToMessage's MessageFormat shares a single instance with ours; adds @messageformat/icu-messageformat-1.
    • Exports the shared types (MsgFormat, MsgAttributes, ...) from the package root.

Public API

Additive only: a new optional format attribute, a MsgProject.format accessor, and newly exported types. The MF2 default keeps existing behavior unchanged.

Test plan

  • npm test — 97 tests green (MF1/MF2/NONE formatting, inheritance, serialization, translation, plus integration/e2e)
  • npx tsc --noEmit — no type errors
  • npm run build — clean tsup build
  • npm run coverage — 100% statements/branches/functions/lines
  • CI green (added .github/workflows/ci.yml)

Docs

  • README.md updated (Message Formats section + API reference).
  • New GETTING_STARTED.md.
  • npm run docs (typedoc) generates browsable API docs into the gitignored docs/.

Notes

  • The MF2 formatToParts snapshot was updated for messageformat@4.0.0 (the number part no longer includes a source field).
  • Process/rules follow-ups (generated docs/ handling and documenting the CI workflow) will land in a separate meta-PR.

jsahleen and others added 8 commits July 19, 2026 14:32
Introduce the `MsgFormat` union ('MF1' | 'MF2' | 'NONE') and a
`format` attribute, plus a project-level `format` (default MF2) that
resources will inherit. Align messageformat to 4.0.0 stable and add
@messageformat/icu-messageformat-1 for MF1 support.

Refs #33

Co-authored-by: Cursor <cursoragent@cursor.com>
Cover project/resource/message format inheritance, MF1/MF2/NONE
formatting behavior, and format-aware serialization. Also update the
MF2 formatToParts snapshot for messageformat 4.0.0 (the `number` part
no longer includes a `source` field).

Refs #33

Co-authored-by: Cursor <cursoragent@cursor.com>
format/formatToParts now resolve the message's format (default MF2):
MF1 compiles via mf1ToMessage, MF2 uses MessageFormat, and NONE returns
the raw string / a single text part. Fix the MF1 formatToParts test to
match the real nested number part shape.

Refs #33

Co-authored-by: Cursor <cursoragent@cursor.com>
Resources inherit the project's format at creation; hasMatchingAttributes
accounts for format so inherited values collapse on serialization. getData
omits format on a resource when it equals the project's and on a message
when it equals its resource's.

Refs #33

Co-authored-by: Cursor <cursoragent@cursor.com>
translate() now carries the source resource's and each source message's
format into the translated copy unless the translation explicitly sets
its own, so MF1/NONE settings survive translation.

Refs #33

Co-authored-by: Cursor <cursoragent@cursor.com>
End-to-end coverage of MF1/MF2/NONE formatting, format-aware
serialization with round-trip, and translate preservation across a
single project, plus the default-fallback branches.

Refs #33

Co-authored-by: Cursor <cursoragent@cursor.com>
Add a CI workflow triggered on pull_request and pushes to main so the
Definition-of-done checks gate every PR (there was previously only a
release-triggered publish workflow).

Refs #33

Co-authored-by: Cursor <cursoragent@cursor.com>
Update README for the inheritable format attribute (MF1/MF2/NONE),
add a GETTING_STARTED guide, export the shared types (MsgFormat,
MsgAttributes, ...) from the package root, and add a typedoc `docs`
script. Generated docs/ output is gitignored like dist/coverage.

Refs #33

Co-authored-by: Cursor <cursoragent@cursor.com>
@jsahleen
jsahleen marked this pull request as ready for review July 19, 2026 20:51

@jsahleen jsahleen left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@jsahleen
jsahleen merged commit bb79d7e into main Jul 19, 2026
1 check passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 0.8.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@jsahleen
jsahleen deleted the msg-33 branch July 20, 2026 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for Unicode MessageFormat 1

1 participant