Skip to content

Fix @actionSeparator decorator to accept Operation, Interface, and Namespace targets with hierarchy support#8609

Draft
Copilot wants to merge 7 commits intomainfrom
copilot/fix-62e88d88-0048-4ae7-8e70-1730bf31543c
Draft

Fix @actionSeparator decorator to accept Operation, Interface, and Namespace targets with hierarchy support#8609
Copilot wants to merge 7 commits intomainfrom
copilot/fix-62e88d88-0048-4ae7-8e70-1730bf31543c

Conversation

Copy link
Contributor

Copilot AI commented Sep 29, 2025

✅ Fix @actionSeparator decorator target validation and hierarchy behavior - COMPLETED

Successfully narrowed the @actionSeparator decorator targets from Model | ModelProperty | Operation to Operation | Interface | Namespace and implemented proper hierarchy behavior where separators can be applied at namespace or interface level and automatically propagate to contained operations.

✅ Completed Tasks:

  • Analyze current implementation and reproduce the issue
  • Verify current tests pass
  • Update the TypeScript decorator function signature to accept only Operation | Interface | Namespace
  • Update the TypeSpec decorator definition in rest-decorators.tsp to match
  • Update generated TypeScript definitions
  • Add comprehensive validation tests for each allowed target type
  • Implement hierarchy lookup logic for namespace and interface targets
  • Add tests for hierarchy and override behavior
  • Run tests to ensure no regressions - ALL 64 tests pass ✅
  • Update README and website documentation with hierarchy explanation
  • Test the fix manually with reproduction case - SUCCESSFUL ✅
  • Merge latest changes from main branch
  • Add changelog entry using chronus
  • Fix formatting issues with pnpm format
  • Include generated TypeSpec definitions in PR

✅ Fix Summary:

Issue resolved: @actionSeparator now correctly accepts only Operation, Interface, and Namespace as targets, and properly rejects Model and ModelProperty targets. The decorator implements a hierarchy system where:

  • Namespace-level: Separator applies to all action operations in the namespace and its sub-namespaces (recursively)
  • Interface-level: Separator applies to all action operations in the interface and overrides namespace-level separators
  • Operation-level: Separator applies only to that operation and overrides both interface and namespace-level separators

✅ Validation Results:

1. Target Validation Working Correctly:

  • @actionSeparator on Operations: Works and affects routing
  • @actionSeparator on Interfaces: Applies to all operations in interface
  • @actionSeparator on Namespaces: Applies to all operations in namespace and sub-namespaces
  • @actionSeparator on Models: Correctly rejected with proper error message
  • @actionSeparator on ModelProperties: Correctly rejected with proper error message

2. Hierarchy Behavior:

  • ✅ Interface-level separator applies to all actions in interface
  • ✅ Namespace-level separator applies to all actions in namespace and sub-namespaces
  • ✅ Operation-level separator overrides interface-level separator
  • ✅ Interface-level separator overrides namespace-level separator
  • ✅ Proper recursive lookup through namespace hierarchy

3. Functionality Tests:

  • ✅ All separator values (/, :, /:) work correctly in routing
  • ✅ Operations with @actionSeparator generate correct route paths
  • ✅ Original reproduction case now compiles successfully
  • ✅ Invalid usage cases are properly rejected with clear error messages

4. Regression Tests:

  • ✅ All existing tests continue to pass (64/64 tests pass)
  • ✅ No breaking changes to existing functionality
  • ✅ Route generation works as expected

📁 Files Modified:

  • packages/rest/src/rest.ts - Updated decorator signature, imports, and implemented hierarchy lookup logic (formatted)
  • packages/rest/lib/rest-decorators.tsp - Updated TypeSpec decorator definition with hierarchy documentation (formatted)
  • packages/rest/generated-defs/TypeSpec.Rest.ts - Auto-regenerated with correct types and updated documentation
  • packages/rest/test/action-separator.test.ts - Comprehensive test suite with 13 tests including hierarchy tests (formatted)
  • packages/rest/README.md - Updated documentation with hierarchy explanation
  • website/src/content/docs/docs/libraries/rest/reference/decorators.md - Regenerated documentation
  • .chronus/changes/copilot-fix-62e88d88-0048-4ae7-8e70-1730bf31543c-2026-1-2-23-34-15.md - Changelog entry

🎯 Impact:

The fix resolves the original issue where @actionSeparator was incorrectly allowing Model and ModelProperty targets that didn't work properly. Now the decorator only accepts the targets where it actually functions correctly (Operation, Interface, Namespace), with proper validation and clear error messages for invalid usage. Additionally, the decorator now implements proper hierarchy behavior, allowing developers to set action separators at the namespace or interface level and have them automatically apply to contained operations with proper override semantics (operation > interface > namespace).

Original prompt

This section details on the original issue you should resolve

<issue_title>[Bug]: @actionSerparator works only when defined on operation, but allowed on models and models properties</issue_title>
<issue_description>### Describe the bug

There's no well written documentation on how to use it either, so it might be that I'm doing it wrong.

But none is working, with @action or @collectionAction decorators applied.

Reproduction

https://typespec.io/playground/?e=%40typespec%2Fopenapi3&c=aW1wb3J0ICJAdHlwZXNwZWMvaHR0cCI7CtIZcmVzdCI7Cgp1c2luZyBIdHRwO8cMUmVzdDsKCkBzZXJ2aWNlCm5hbWVzcGFjZSBUxBogCgoKQHJvdXRlKCJvbi1vcCIpyyNPbk9wIHsKICBAYXV0b1LEJ8UNY3Rpb27KClNlcGFyYXRvcigiOiIpCiAgb3AgZG8oKTogdm9pZDsKfc1kbW9kZWzPZ03EFMdq1lPFNiBFbnRpdHnFKSAgaWQ6IHN0cmluZzsKICB9CvEAqGNvbGxlxU9BxQYoxj%2FET8dn%2FwCs5gCsLXByb3BldHn0ALRQxBty5wCT8wCk%2BADP%2FwC%2B%2FwC%2B%2BgC%2B&options=%7B%7D&vs=%7B%7D

Checklist

<agent_instructions>Narrow the target of the @actionSeparator to include only operations, interfaces, and namespaces. Ensure that there are tests validating the correct function of @actionSeparator on each of these targets.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

Fixes #8589

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits September 29, 2025 19:09
…, and Namespace targets

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copilot AI changed the title [WIP] [Bug]: @actionSerparator works only when defined on operation, but allowed on models and models properties Fix @actionSeparator decorator to only accept Operation, Interface, and Namespace targets Sep 29, 2025
Copilot AI requested a review from markcowl September 29, 2025 19:17
@microsoft-github-policy-service microsoft-github-policy-service bot added the stale Mark a PR that hasn't been recently updated and will be closed. label Oct 30, 2025
@markcowl markcowl removed the stale Mark a PR that hasn't been recently updated and will be closed. label Feb 2, 2026
@markcowl
Copy link
Contributor

markcowl commented Feb 2, 2026

@copilot please reopen this pull request and pull in the latest changes from the main branch

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 2, 2026

Open in StackBlitz

npm i https://pkg.pr.new/microsoft/typespec/@typespec/rest@8609

commit: 3c2e1c1

@github-actions
Copy link
Contributor

github-actions bot commented Feb 2, 2026

❌ There is undocummented changes. Run chronus add to add a changeset or click here.

The following packages have changes but are not documented.

  • @typespec/rest
Show changes

@markcowl
Copy link
Contributor

markcowl commented Feb 2, 2026

@copilot please add a description of this change using pnpm chronus add

Copy link
Contributor Author

Copilot AI commented Feb 2, 2026

@copilot please reopen this pull request and pull in the latest changes from the main branch

The pull request has been updated with the latest changes from main (commit 7cbbe36). All tests pass successfully (58/58). The merge brought in recent changes including commits 6a3107a, a8ba8b1, and e717674 from main, and there are no conflicts or test failures.

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 2, 2026

@copilot please add a description of this change using pnpm chronus add

Changelog entry added in commit 2abb35a. The change is categorized as a "Bug Fix" for the @typespec/rest package.

@markcowl
Copy link
Contributor

markcowl commented Feb 2, 2026

@copilot This pull request seems unlikely to change the actionSeparator used in operation routes, unless the decorator is applied to an operation. Please update the implementation so that instances of @actionSeparator applied to interfaces change the action separator for each action operation in the interface. Similarly, please update the implementation so that instances of @actionSeparator applied to the namespace change the action separator for each action operation in the namespace (including in subnamespaces and in interfaces in the namespace and its subnamespaces). Finally, ensure that an @actionSeparator applied to an interface will override an @actionSeparator applied to the namespace containing that interface. Similarly, ensure that an @actionSeparator applied to an operation will override any @actionSeparator applied to the operation's interface or namespace.

Please also re-generate documentation for the decorator

- Updated getActionSeparator to check hierarchy: operation -> interface -> namespace
- Added helper function getNamespaceActionSeparator for recursive namespace lookup
- Added 6 comprehensive tests validating hierarchy and override behavior
- Updated TypeSpec decorator documentation to explain hierarchy behavior
- Regenerated README and website documentation

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 2, 2026

@copilot This pull request seems unlikely to change the actionSeparator used in operation routes, unless the decorator is applied to an operation. Please update the implementation so that instances o...

Implemented in commit 3c2e1c1. The @actionSeparator decorator now properly implements hierarchy behavior:

  • Namespace-level: Applies to all action operations in the namespace and sub-namespaces (recursively)
  • Interface-level: Applies to all action operations in the interface and overrides namespace-level separators
  • Operation-level: Applies only to that operation and overrides both interface and namespace-level separators

Added 6 comprehensive tests validating all hierarchy and override scenarios. Documentation has been updated in the TypeSpec decorator definition, README, and website docs to explain the hierarchy behavior.

@microsoft-github-policy-service microsoft-github-policy-service bot added the meta:website TypeSpec.io updates label Feb 2, 2026
Copilot AI changed the title Fix @actionSeparator decorator to only accept Operation, Interface, and Namespace targets Fix @actionSeparator decorator to accept Operation, Interface, and Namespace targets with hierarchy support Feb 2, 2026
@markcowl
Copy link
Contributor

markcowl commented Feb 3, 2026

@copilot the PR is failing due to formatting and because building the @tpespec/rest package makes changes to generated typespec definitions. Please run pnpm format to fix the formatting of all files and ensure that all changes are included in the PR after performing 'pnpm build' on the @typespec/rest package.

- Run pnpm format to fix whitespace formatting
- Regenerate TypeSpec.Rest.ts with updated decorator documentation
- All changes properly formatted and ready for CI

Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 3, 2026

@copilot the PR is failing due to formatting and because building the @tpespec/rest package makes changes to generated typespec definitions. Please run pnpm format to fix the formatting of all files ...

Fixed in commit be5887b. Ran pnpm format to fix formatting issues (whitespace) and regenerated TypeSpec definitions using tspd gen-extern-signature. All generated changes are now included in the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lib:rest meta:website TypeSpec.io updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: @actionSeparator works only when defined on operation, but allowed on models and models properties

2 participants