Skip to content

Commit 86078bf

Browse files
authored
Merge pull request #3635 from hey-api/copilot/fix-symbolonce-bug
fix: symbol() and symbolOnce() correctly deduplicate external symbols by name
2 parents c3e497c + 6c1120c commit 86078bf

20 files changed

Lines changed: 403 additions & 170 deletions

File tree

.changeset/rude-rules-fly.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@hey-api/openapi-ts": patch
3+
"@hey-api/shared": patch
4+
---
5+
6+
**plugin**: fix: `symbolOnce()` method correctly handles multiple symbols with the same metadata

packages/codegen-core/src/__tests__/symbols.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,22 @@ describe('SymbolRegistry', () => {
106106
const result = r.query(meta({ a: { b: { c: 123 } } }));
107107
expect(result).toEqual([a]);
108108
});
109+
110+
it('query() returns all symbols sharing the same meta but with different names', () => {
111+
const r = new SymbolRegistry();
112+
113+
const sharedMeta = meta({ category: 'external', resource: '@shared/types' });
114+
115+
const a = r.register({ meta: sharedMeta, name: 'CustomNumber' });
116+
const b = r.register({ meta: sharedMeta, name: 'FlakeIdString' });
117+
118+
const results = r.query(sharedMeta);
119+
expect(results).toHaveLength(2);
120+
expect(results).toContain(a);
121+
expect(results).toContain(b);
122+
123+
// filtering by name correctly identifies each symbol independently
124+
expect(results.find((s) => s.name === 'CustomNumber')).toBe(a);
125+
expect(results.find((s) => s.name === 'FlakeIdString')).toBe(b);
126+
});
109127
});

packages/openapi-python/src/plugins/@hey-api/sdk/v1/plugin.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,13 @@ export const handlerV1: HeyApiSdkPlugin['Handler'] = ({ plugin }) => {
1616
plugin.symbol('build_client_params', {
1717
external: clientModule,
1818
meta: {
19-
category: 'external',
2019
resource: 'client.build_client_params',
2120
tool: client.name,
2221
},
2322
});
2423
plugin.symbol('Client', {
2524
external: clientModule,
2625
meta: {
27-
category: 'external',
2826
resource: 'client.Client',
2927
tool: client.name,
3028
},
@@ -33,26 +31,14 @@ export const handlerV1: HeyApiSdkPlugin['Handler'] = ({ plugin }) => {
3331
// functools
3432
plugin.symbol('cached_property', {
3533
external: 'functools',
36-
meta: {
37-
category: 'external',
38-
resource: 'functools.cached_property',
39-
},
4034
});
4135

4236
// typing
4337
plugin.symbol('Any', {
4438
external: 'typing',
45-
meta: {
46-
category: 'external',
47-
resource: 'typing.Any',
48-
},
4939
});
5040
plugin.symbol('Union', {
5141
external: 'typing',
52-
meta: {
53-
category: 'external',
54-
resource: 'typing.Union',
55-
},
5642
});
5743

5844
const structure = new StructureModel();

packages/openapi-python/src/plugins/pydantic/v2/plugin.ts

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,77 +7,37 @@ export const handlerV2: PydanticPlugin['Handler'] = ({ plugin }) => {
77
// enum
88
plugin.symbol('Enum', {
99
external: 'enum',
10-
meta: {
11-
category: 'external',
12-
resource: 'enum.Enum',
13-
},
1410
});
1511

1612
// typing
1713
plugin.symbol('Any', {
1814
external: 'typing',
19-
meta: {
20-
category: 'external',
21-
resource: 'typing.Any',
22-
},
2315
});
2416
plugin.symbol('Literal', {
2517
external: 'typing',
26-
meta: {
27-
category: 'external',
28-
resource: 'typing.Literal',
29-
},
3018
});
3119
plugin.symbol('NoReturn', {
3220
external: 'typing',
33-
meta: {
34-
category: 'external',
35-
resource: 'typing.NoReturn',
36-
},
3721
});
3822
plugin.symbol('Optional', {
3923
external: 'typing',
40-
meta: {
41-
category: 'external',
42-
resource: 'typing.Optional',
43-
},
4424
});
4525
plugin.symbol('TypeAlias', {
4626
external: 'typing',
47-
meta: {
48-
category: 'external',
49-
resource: 'typing.TypeAlias',
50-
},
5127
});
5228
plugin.symbol('Union', {
5329
external: 'typing',
54-
meta: {
55-
category: 'external',
56-
resource: 'typing.Union',
57-
},
5830
});
5931

6032
// Pydantic
6133
plugin.symbol('BaseModel', {
6234
external: 'pydantic',
63-
meta: {
64-
category: 'external',
65-
resource: 'pydantic.BaseModel',
66-
},
6735
});
6836
plugin.symbol('ConfigDict', {
6937
external: 'pydantic',
70-
meta: {
71-
category: 'external',
72-
resource: 'pydantic.ConfigDict',
73-
},
7438
});
7539
plugin.symbol('Field', {
7640
external: 'pydantic',
77-
meta: {
78-
category: 'external',
79-
resource: 'pydantic.Field',
80-
},
8141
});
8242

8343
const processor = createProcessor(plugin);

packages/openapi-ts/src/plugins/@angular/common/plugin.ts

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,15 @@ export const handler: AngularCommonPlugin['Handler'] = ({ plugin }) => {
1717
plugin.symbol('HttpRequest', {
1818
external: '@angular/common/http',
1919
kind: 'type',
20-
meta: {
21-
category: 'external',
22-
resource: '@angular/common/http.HttpRequest',
23-
},
2420
});
2521
plugin.symbol('inject', {
2622
external: '@angular/core',
27-
meta: {
28-
category: 'external',
29-
resource: '@angular/core.inject',
30-
},
3123
});
3224
plugin.symbol('Injectable', {
3325
external: '@angular/core',
34-
meta: {
35-
category: 'external',
36-
resource: '@angular/core.Injectable',
37-
},
3826
});
3927
plugin.symbol('httpResource', {
4028
external: '@angular/common/http',
41-
meta: {
42-
category: 'external',
43-
resource: '@angular/common/http.httpResource',
44-
},
4529
});
4630

4731
const httpRequestStructure = new StructureModel();

packages/openapi-ts/src/plugins/@hey-api/sdk/shared/typeOptions.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export const createTypeOptions = ({ plugin }: { plugin: HeyApiSdkPlugin['Instanc
1919
external: clientModule,
2020
kind: 'type',
2121
meta: {
22-
category: 'external',
2322
resource: 'client.Client',
2423
tool: client.name,
2524
},

packages/openapi-ts/src/plugins/@hey-api/sdk/v1/plugin.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,20 @@ export const handlerV1: HeyApiSdkPlugin['Handler'] = ({ plugin }) => {
1919
plugin.symbol('formDataBodySerializer', {
2020
external: clientModule,
2121
meta: {
22-
category: 'external',
2322
resource: 'client.formDataBodySerializer',
2423
tool: client.name,
2524
},
2625
});
2726
plugin.symbol('urlSearchParamsBodySerializer', {
2827
external: clientModule,
2928
meta: {
30-
category: 'external',
3129
resource: 'client.urlSearchParamsBodySerializer',
3230
tool: client.name,
3331
},
3432
});
3533
plugin.symbol('buildClientParams', {
3634
external: clientModule,
3735
meta: {
38-
category: 'external',
3936
resource: 'client.buildClientParams',
4037
tool: client.name,
4138
},
@@ -45,7 +42,6 @@ export const handlerV1: HeyApiSdkPlugin['Handler'] = ({ plugin }) => {
4542
external: clientModule,
4643
kind: 'type',
4744
meta: {
48-
category: 'external',
4945
resource: 'client.Composable',
5046
tool: client.name,
5147
},
@@ -54,10 +50,6 @@ export const handlerV1: HeyApiSdkPlugin['Handler'] = ({ plugin }) => {
5450
if (isAngularClient) {
5551
plugin.symbol('Injectable', {
5652
external: '@angular/core',
57-
meta: {
58-
category: 'external',
59-
resource: '@angular/core.Injectable',
60-
},
6153
});
6254
}
6355

packages/openapi-ts/src/plugins/@pinia/colada/queryKey.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,6 @@ export const createQueryKeyFunction = ({ plugin }: { plugin: PiniaColadaPlugin['
4747
const clientModule = clientFolderAbsolutePath(getTypedConfig(plugin));
4848
const symbolSerializeQueryValue = plugin.symbol('serializeQueryKeyValue', {
4949
external: clientModule,
50-
meta: {
51-
category: 'external',
52-
resource: `${clientModule}.serializeQueryKeyValue`,
53-
},
5450
});
5551

5652
const fn = $.const(symbolCreateQueryKey).assign(

packages/openapi-ts/src/plugins/@pinia/colada/v0/plugin.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,22 @@ import type { PiniaColadaPlugin } from '../types';
55
export const handlerV0: PiniaColadaPlugin['Handler'] = ({ plugin }) => {
66
plugin.symbol('defineQueryOptions', {
77
external: plugin.name,
8-
meta: {
9-
category: 'external',
10-
resource: `${plugin.name}.defineQueryOptions`,
11-
},
128
});
139
plugin.symbol('UseMutationOptions', {
1410
external: plugin.name,
1511
kind: 'type',
16-
meta: {
17-
category: 'external',
18-
resource: `${plugin.name}.UseMutationOptions`,
19-
},
2012
});
2113
plugin.symbol('UseQueryOptions', {
2214
external: plugin.name,
2315
kind: 'type',
24-
meta: {
25-
category: 'external',
26-
resource: `${plugin.name}.UseQueryOptions`,
27-
},
2816
});
2917
plugin.symbol('_JSONValue', {
3018
external: plugin.name,
3119
kind: 'type',
32-
meta: {
33-
category: 'external',
34-
resource: `${plugin.name}._JSONValue`,
35-
},
3620
});
3721
plugin.symbol('AxiosError', {
3822
external: 'axios',
3923
kind: 'type',
40-
meta: {
41-
category: 'external',
42-
resource: 'axios.AxiosError',
43-
},
4424
});
4525

4626
plugin.forEach(

packages/openapi-ts/src/plugins/@tanstack/query-core/v5/plugin.ts

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,10 @@ export const handlerV5: PluginHandler = ({ plugin }) => {
99
plugin.symbol('DefaultError', {
1010
external: plugin.name,
1111
kind: 'type',
12-
meta: {
13-
category: 'external',
14-
resource: `${plugin.name}.DefaultError`,
15-
},
1612
});
1713
plugin.symbol('InfiniteData', {
1814
external: plugin.name,
1915
kind: 'type',
20-
meta: {
21-
category: 'external',
22-
resource: `${plugin.name}.InfiniteData`,
23-
},
2416
});
2517
const mutationsType =
2618
plugin.name === '@tanstack/angular-query-experimental' ||
@@ -32,45 +24,24 @@ export const handlerV5: PluginHandler = ({ plugin }) => {
3224
external: plugin.name,
3325
kind: 'type',
3426
meta: {
35-
category: 'external',
3627
resource: `${plugin.name}.MutationOptions`,
3728
},
3829
});
3930
plugin.symbol('infiniteQueryOptions', {
4031
external: plugin.name,
41-
meta: {
42-
category: 'external',
43-
resource: `${plugin.name}.infiniteQueryOptions`,
44-
},
4532
});
4633
plugin.symbol('queryOptions', {
4734
external: plugin.name,
48-
meta: {
49-
category: 'external',
50-
resource: `${plugin.name}.queryOptions`,
51-
},
5235
});
5336
plugin.symbol('useMutation', {
5437
external: plugin.name,
55-
meta: {
56-
category: 'external',
57-
resource: `${plugin.name}.useMutation`,
58-
},
5938
});
6039
plugin.symbol('useQuery', {
6140
external: plugin.name,
62-
meta: {
63-
category: 'external',
64-
resource: `${plugin.name}.useQuery`,
65-
},
6641
});
6742
plugin.symbol('AxiosError', {
6843
external: 'axios',
6944
kind: 'type',
70-
meta: {
71-
category: 'external',
72-
resource: 'axios.AxiosError',
73-
},
7445
});
7546

7647
plugin.forEach(

0 commit comments

Comments
 (0)