Skip to content

Add TypeScript support for RFC 6570 URI Template expressions (e.g., {+identifier}) #426

@dahlia

Description

@dahlia

Summary

Currently, Fedify's TypeScript types only allow simple string expansion ({identifier}) for URI template parameters, but the runtime already supports all RFC 6570 expression types. This causes type errors when using other valid RFC 6570 expressions like {+identifier} (reserved string expansion), which is the recommended solution for URI-containing identifiers.

Background

This issue was discovered in #416 where a user needed to use {+identifier} to properly handle URI identifiers with special characters. While the runtime works correctly, TypeScript throws errors because the current type definitions are too restrictive.

Current type constraint:

type ParamPath<Param extends string> = `${string}{${Param}}${string}`;

Runtime support: Already supports all RFC 6570 expressions via uri-template-router and url-template libraries.

Expected behavior

TypeScript should accept all valid RFC 6570 expression types:

  • {identifier} - Simple string expansion
  • {+identifier} - Reserved string expansion (recommended for URI identifiers)
  • {#identifier} - Fragment expansion
  • {.identifier} - Label expansion with dot-prefix
  • {/identifier} - Path segments
  • {;identifier} - Path-style parameters
  • {?identifier} - Query component
  • {&identifier} - Query continuation

Current behavior

Using any expression other than simple string expansion causes TypeScript errors:

// ❌ Type error
federation.setFollowersDispatcher(
  `/users/{+identifier}/followers`, // Type error here
  async (ctx, identifier, cursor) => { /* ... */ },
)

Proposed solution

  1. Create RFC 6570 expression type helper:

    type Rfc6570Expression<Param extends string> =
      | `{${Param}}`     // Simple string expansion
      | `{+${Param}}`    // Reserved string expansion
      | `{#${Param}}`    // Fragment expansion
      | `{.${Param}}`    // Label expansion with dot-prefix
      | `{/${Param}}`    // Path segments
      | `{;${Param}}`    // Path-style parameters
      | `{?${Param}}`    // Query component
      | `{&${Param}}`;   // Query continuation
  2. Update ParamPath type:

    type ParamPath<Param extends string> = `${string}${Rfc6570Expression<Param>}${string}`;
  3. Update documentation to clarify when to use different expression types (especially {+identifier} for URI identifiers).

Implementation details

Files to modify:

  • packages/fedify/src/federation/federation.ts (lines ~1180) - Update type definitions
  • Documentation to include RFC 6570 expression usage examples

Testing:

  • Verify all existing simple expansion usage continues to work
  • Add test cases for different RFC 6570 expression types
  • Ensure runtime behavior remains unchanged (type-only change)

Impact

  • Breaking change: No - this is additive type improvement
  • Runtime impact: None - runtime already supports these expressions
  • Documentation: Update needed to explain when to use different expressions

Related issues

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions