feat: add custom directives API and @json-render/directives package#279
Merged
feat: add custom directives API and @json-render/directives package#279
Conversation
Add a `defineDirective` API that lets users register custom `$`-prefixed dynamic values with schemas, resolvers, and prompt instructions — extending the spec language without forking core.
Contributor
…ect keys
Flip the loop from O(object-keys) to O(registry-size) by iterating
the directive registry and checking `key in value` rather than scanning
all object keys with Object.keys() and startsWith("$").
… coercion
$format relative dates now support future timestamps ("2h from now")
and return "just now" for zero diff. $math emits a console.warn in
dev mode when a non-numeric value is silently coerced to 0.
The directives package doesn't include @types/node, so referencing process.env fails during tsup's DTS generation. The console.warn is unconditional now — it only fires on actual misuse (non-numeric input) so the cost is negligible.
… in prompt, add docs - Rename `prompt` to `description` on DirectiveDefinition — a short behavioral label rather than the full AI prompt blob - Auto-generate directive schema signatures in the system prompt using formatZodType, so the AI always sees every field, type, and optionality - Add docs: guide page, API reference page, nav/title entries, docs-chat
Export a pre-assembled standardDirectives array (all 7 non-factory directives) for convenience. Add a composition hint to the generated AI prompt so agents know directives can nest inside each other.
- Add skills/directives/SKILL.md with full directive API reference - Add @json-render/directives row to root README packages table - Add "directives" to the Available skills list in docs-chat prompt
Resolvers are already defensive (coercion, fallbacks, switch defaults), so runtime validation on every render adds overhead without safety. The schema remains used for prompt generation and TypeScript inference.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
defineDirectiveAPI to@json-render/corethat lets users register custom$-prefixed dynamic values with Zod schemas, resolver functions, and AI prompt instructions — extending the spec language from userland without modifying core.directivesprop on providers andcreateRenderer.@json-render/directivespackage with 8 pre-built directives:$format,$math,$concat,$count,$truncate,$pluralize,$join, andcreateI18nDirective(factory for$t).Renderer changes
Each renderer (React, Vue, Svelte, Solid) now:
directivesprop (array ofDirectiveDefinition)DirectiveRegistry(Map)fullCtx.directives@json-render/directivespackage$formatIntl$math$concat$count$truncate$pluralize$joincreateI18nDirective$ttranslation directive with{{param}}interpolationDirectives compose naturally — each resolver calls
resolvePropValueon its inputs, so$formatcan wrap$mathwhich reads from$state.