Skip to content

Commit 3ff8f76

Browse files
committed
refactor: extract warnDuplicatePlugins to @hey-api/shared and apply in openapi-python
1 parent 9f9cf09 commit 3ff8f76

File tree

4 files changed

+68
-38
lines changed

4 files changed

+68
-38
lines changed

packages/openapi-python/src/config/plugins.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import type { AnyPluginName, PluginContext, PluginNames } from '@hey-api/shared';
2-
import { dependencyFactory, valueToObject } from '@hey-api/shared';
2+
import {
3+
dependencyFactory,
4+
valueToObject,
5+
warnDuplicatePlugins,
6+
} from '@hey-api/shared';
37

48
import { defaultPluginConfigs } from '../plugins/config';
59
import type { Config, UserConfig } from './types';
@@ -143,6 +147,8 @@ export function getPlugins({
143147
}
144148
}
145149

150+
warnDuplicatePlugins(definedPlugins as ReadonlyArray<never>);
151+
146152
const userPlugins = definedPlugins
147153
.map((plugin) => {
148154
if (typeof plugin === 'string') {

packages/openapi-ts/src/config/plugins.ts

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
import { log } from '@hey-api/codegen-core';
21
import type { AnyPluginName, PluginContext, PluginNames } from '@hey-api/shared';
3-
import { dependencyFactory, valueToObject } from '@hey-api/shared';
2+
import {
3+
dependencyFactory,
4+
valueToObject,
5+
warnDuplicatePlugins,
6+
} from '@hey-api/shared';
47

58
import { defaultPluginConfigs } from '../plugins/config';
69
import type { Config, UserConfig } from './types';
@@ -147,51 +150,17 @@ export function getPlugins({
147150
}
148151
}
149152

150-
const seenPlugins = new Map<string, string>();
151-
152-
const stableStringify = (value: unknown): string =>
153-
JSON.stringify(value, (_, v) => {
154-
if (typeof v === 'function') {
155-
return `[function:${(v as () => unknown).toString()}]`;
156-
}
157-
if (v && typeof v === 'object' && !Array.isArray(v)) {
158-
return Object.fromEntries(
159-
Object.entries(v as Record<string, unknown>).sort(([a], [b]) =>
160-
a.localeCompare(b),
161-
),
162-
);
163-
}
164-
return v;
165-
});
166-
167-
const checkDuplicate = (name: string, config: Record<string, unknown>) => {
168-
const serialized = stableStringify(config);
169-
const previous = seenPlugins.get(name);
170-
if (previous !== undefined && previous !== serialized) {
171-
log.warn(
172-
`Plugin "${name}" is configured more than once with conflicting options. Only the last occurrence will take effect.`,
173-
);
174-
}
175-
seenPlugins.set(name, serialized);
176-
};
153+
warnDuplicatePlugins(definedPlugins as ReadonlyArray<never>);
177154

178155
const userPlugins = definedPlugins
179156
.map((plugin) => {
180157
if (typeof plugin === 'string') {
181-
checkDuplicate(plugin, {});
182158
return plugin;
183159
}
184160

185161
const pluginName = plugin.name;
186162

187163
if (pluginName) {
188-
const config = Object.fromEntries(
189-
Object.entries(plugin as unknown as Record<string, unknown>).filter(
190-
([key]) => key !== 'name',
191-
),
192-
);
193-
checkDuplicate(pluginName, config);
194-
195164
// @ts-expect-error
196165
if (plugin.handler) {
197166
// @ts-expect-error

packages/shared/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ export type {
9797
OpenApiSchemaObject,
9898
} from './openApi/types';
9999
export type { GetNameContext, Hooks } from './parser/hooks';
100+
export { warnDuplicatePlugins } from './plugins/duplicate';
100101
export type { SchemaWithType } from './plugins/shared/types/schema';
101102
export { definePluginConfig, mappers } from './plugins/shared/utils/config';
102103
export type { PluginInstanceTypes } from './plugins/shared/utils/instance';
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { log } from '@hey-api/codegen-core';
2+
3+
type PluginEntry = string | ({ name: string } & Record<string, unknown>);
4+
5+
const stableStringify = (value: unknown): string =>
6+
JSON.stringify(value, (_, v) => {
7+
if (typeof v === 'function') {
8+
return `[function:${(v as () => unknown).toString()}]`;
9+
}
10+
if (v && typeof v === 'object' && !Array.isArray(v)) {
11+
return Object.fromEntries(
12+
Object.entries(v as Record<string, unknown>).sort(([a], [b]) =>
13+
a.localeCompare(b),
14+
),
15+
);
16+
}
17+
return v;
18+
});
19+
20+
export const warnDuplicatePlugins = (
21+
plugins: ReadonlyArray<PluginEntry>,
22+
): void => {
23+
const seen = new Map<string, string>();
24+
25+
for (const plugin of plugins) {
26+
if (typeof plugin === 'string') {
27+
const previous = seen.get(plugin);
28+
if (previous !== undefined && previous !== '{}') {
29+
log.warn(
30+
`Plugin "${plugin}" is configured more than once with conflicting options. Only the last occurrence will take effect.`,
31+
);
32+
}
33+
seen.set(plugin, '{}');
34+
continue;
35+
}
36+
37+
const name = plugin.name;
38+
if (!name) continue;
39+
40+
const config = Object.fromEntries(
41+
Object.entries(plugin as Record<string, unknown>).filter(
42+
([key]) => key !== 'name',
43+
),
44+
);
45+
const serialized = stableStringify(config);
46+
const previous = seen.get(name);
47+
if (previous !== undefined && previous !== serialized) {
48+
log.warn(
49+
`Plugin "${name}" is configured more than once with conflicting options. Only the last occurrence will take effect.`,
50+
);
51+
}
52+
seen.set(name, serialized);
53+
}
54+
};

0 commit comments

Comments
 (0)