Skip to content

Add object-literal plugin types and deprecate class-based plugins - #139

Merged
knowledgecode merged 8 commits into
masterfrom
develop
Sep 21, 2026
Merged

knowledgecode merged 8 commits into
masterfrom
develop

Conversation

@knowledgecode

@knowledgecode knowledgecode commented Sep 21, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Add FormatterPluginObject / ParserPluginObject, which let a plugin be written as a plain object literal (the v4 counterpart of 3.x date.extend(...)) and statically reject keys that collide with built-in tokens.
  • Rewrite the built-in formatter/parser and the nine bundled plugins as object literals. The reserved token set is an explicit union (ReservedFormatterToken / ReservedParserToken), and satisfies Record<Reserved…, …> on the built-in objects keeps it exactly in sync with their keys. The bundled plugins use satisfies rather than a type annotation, so each token keeps its own function type instead of widening to a string-indexed record.
  • Mark FormatterPlugin / ParserPlugin as @deprecated. The plugins option now accepts (FormatterPluginObject | FormatterPlugin)[] (likewise for the parser), so existing class-based plugins keep compiling until the classes are removed in the next major version.
  • Docs: add a "Writing Your Own Plugin" section and a 3.x to 4.x migration example, update the plugins option type in the format/parse API docs, and clarify that only annotated object literals are checked against built-in tokens, what a parser token can and cannot do, and that the class-based types are deprecated.
  • Chore: bump the version to 4.6.0 and update devDependencies (vitest / @vitest/coverage-v8 5.x, astro 7.3, @astrojs/starlight 0.42).
  • Docs build: fix the two warnings that appeared after the Astro/Starlight update (empty i18n collection, missing 404 entry). docs/404.md is added and disable404Route is set, so the 404 page is generated from a real entry.
  • Tests: enable fsModuleCache for faster local reruns and set isolate: true explicitly. The tests change process.env.TZ, which would leak across files if workers were shared.

Test plan

  • npm run ts
  • npm run lint
  • npm run test (72 files / 2310 tests)
  • npm run build
  • npm run docs:build (no warnings)
  • Type-check the built dist/*.d.ts from a consumer's perspective: object literals, class instances, and bundled plugins (with their per-token types) are accepted; a key redefining a built-in token and a non-function token are rejected

@codecov-commenter

codecov-commenter commented Sep 21, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.78%. Comparing base (f2495b0) to head (5a2069b).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #139   +/-   ##
=======================================
  Coverage   98.78%   98.78%           
=======================================
  Files          77       77           
  Lines        1233     1235    +2     
  Branches      357      357           
=======================================
+ Hits         1218     1220    +2     
  Partials       15       15           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…ate class-based plugins

Plugins can now be plain object literals typed as FormatterPluginObject or
ParserPluginObject, which statically reject keys that collide with built-in
tokens. The built-in formatter and parser are rewritten as object literals so
the reserved token set is derived from their keys instead of a hand-written
list. FormatterPlugin/ParserPlugin are marked @deprecated but still accepted
by the plugins option until the next major version.
Convert all nine bundled plugins from class-based to object literals typed
as FormatterPluginObject/ParserPluginObject so they are also protected from
built-in token collisions. Exported names and behavior are unchanged.
Add a "Writing Your Own Plugin" section, show the 3.x extend to 4.x plugins
migration, and update the plugins option type in the format/parse API docs.
Explain that only annotated object literals are checked against built-in
tokens, document what a parser token can and cannot do, and note that the
class-based plugin types are deprecated.
Notably vitest and @vitest/coverage-v8 to 5.x, astro to 7.3 and
@astrojs/starlight to 0.42.
Register an empty i18n entry so the optional collection is present in the
data store, and provide docs/404.md with disable404Route so the 404 page
comes from a real entry instead of Starlight's fallback.
Persist transformed modules under node_modules/.vitest-cache for faster
local reruns. Keep isolate enabled because the tests change process.env.TZ
and would leak it across files in shared workers.
@knowledgecode
knowledgecode merged commit b95de0e into master Sep 21, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants