Skip to content

Commit ab6e71f

Browse files
the-ultclaude
andcommitted
fix(core,angular): route default-bucket exports and empty tags through the canonical helper
Generalize the tag-identity fix to two more call sites so they agree with `isOperationInTagBucket`, the single source of truth for tag-bucket identity: - core/target-tags: the footer `operationNames` filter excluded untagged operations (`tags.length > 0`), so the implicit `default` bucket file could miss its per-operation `*ClientResult` exports. Filter the already default-normalised `operations` array via `isOperationInTagBucket`. - angular/utils: `getRelevantVerbOptionsForTag` treated an empty-string tag as "no filter" (`if (!tag)`); guard on `tag == null` so an empty/whitespace tag normalises to the `default` bucket like the core writer. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 807ee97 commit ab6e71f

4 files changed

Lines changed: 23 additions & 7 deletions

File tree

.impeccable/hook.cache.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"version":1,"sessions":{"d4d1b3f6-0228-46ed-be83-2a11eaabb747":{"updatedAt":1782236815641,"files":{"/Users/arjenalthoff/dev/copilot-worktrees/orval/the-ult-probable-eureka/packages/core/src/writers/target-tags.ts":{"editCount":2,"findings":[]},"/Users/arjenalthoff/dev/copilot-worktrees/orval/the-ult-probable-eureka/packages/angular/src/utils.ts":{"editCount":1,"findings":[]},"/Users/arjenalthoff/dev/copilot-worktrees/orval/the-ult-probable-eureka/packages/angular/src/utils.test.ts":{"editCount":1,"findings":[]}}}}}

packages/angular/src/utils.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,4 +514,14 @@ describe('getRelevantVerbOptionsForTag', () => {
514514
it('returns empty array for empty verbOptions', () => {
515515
expect(getRelevantVerbOptionsForTag({}, 'pets')).toHaveLength(0);
516516
});
517+
518+
it('treats an empty-string tag as the default bucket, not as "no filter"', () => {
519+
const verbOptions = {
520+
untagged: makeVerb('untagged', []),
521+
tagged: makeVerb('tagged', ['pets']),
522+
};
523+
const result = getRelevantVerbOptionsForTag(verbOptions, '');
524+
expect(result).toHaveLength(1);
525+
expect(result[0].operationId).toBe('untagged');
526+
});
517527
});

packages/angular/src/utils.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,10 @@ export const getRelevantVerbOptionsForTag = (
152152
tag?: string,
153153
): GeneratorVerbOptions[] => {
154154
const allVerbOptions = Object.values(verbOptions);
155-
if (!tag) return allVerbOptions;
155+
// Only an absent tag means "no filter"; an empty/whitespace tag is a real
156+
// bucket key that `isOperationInTagBucket` normalises to `default`, matching
157+
// the core writer instead of silently matching every operation.
158+
if (tag == null) return allVerbOptions;
156159

157160
return allVerbOptions.filter((verbOption) =>
158161
isOperationInTagBucket(verbOption, tag),

packages/core/src/writers/target-tags.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
import {
1313
compareVersions,
1414
getOperationTagKey,
15-
getTagKey,
15+
isOperationInTagBucket,
1616
pascal,
1717
} from '../utils';
1818

@@ -204,11 +204,13 @@ export function generateTargetForTags(
204204
const isMutator = !!target.mutators?.some((mutator) =>
205205
isAngularClient ? mutator.hasThirdArg : mutator.hasSecondArg,
206206
);
207-
const operationNames = Object.values(builder.operations)
208-
// Operations can have multiple tags, but they are grouped by the first
209-
// tag, therefore we only want to handle the case where the tag
210-
// is the first in the list of tags.
211-
.filter(({ tags }) => tags.length > 0 && getTagKey(tags[0]) === tag)
207+
const operationNames = operations
208+
// Operations can have multiple tags, but they are grouped by their
209+
// primary (first) tag. Filtering through the canonical
210+
// `isOperationInTagBucket` keeps this in lockstep with how the
211+
// buckets above were built, including untagged operations that were
212+
// routed into the implicit `default` bucket by `addDefaultTagIfEmpty`.
213+
.filter((operation) => isOperationInTagBucket(operation, tag))
212214
.map(({ operationName }) => operationName);
213215

214216
const typescriptVersion =

0 commit comments

Comments
 (0)