Skip to content

Commit b8124ae

Browse files
author
nx-plugin-for-aws
committed
fix(open-api#ts-client): address review feedback
- rewriteConstToEnum now uses the cloneDeepWith customiser pattern that the rest of normalise.ts follows, returning a new spec tree instead of mutating in place. - Tighten the FastAPI const regression test: assert the concrete current shape (kind: string via the languages.ts defence-in-depth) so any future tightening that restores the Literal narrowing is a deliberate, visible change rather than silently accepted.
1 parent 78fd171 commit b8124ae

2 files changed

Lines changed: 20 additions & 21 deletions

File tree

packages/nx-plugin/src/open-api/ts-client/generator.composite-types.spec.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,14 +1265,18 @@ describe('openApiTsClientGenerator - composite schemas', () => {
12651265

12661266
// Phantom references synthesised from `const` must not leak through.
12671267
// Previously the const shape caused hey-api-openapi to reference a
1268-
// non-existent `_String` (or `Kind`) type, breaking tsc in strict mode.
1268+
// non-existent `_String` type, breaking tsc in strict mode.
12691269
expect(types).not.toMatch(/\b_String\b/);
12701270
expect(client).not.toMatch(/\b_String\b/);
12711271
expect(types).not.toMatch(/:\s*undefined\b/);
12721272

1273-
// Circle.kind should resolve to something tsc can type-check (either the
1274-
// literal 'circle' or bare string with the defence-in-depth fix).
1275-
expect(types).toMatch(/kind:\s*('circle'|"circle"|string|Kind\b)/);
1273+
// After rewriteConstToEnum + languages.ts defence-in-depth the property
1274+
// resolves to bare `string` (the generator does not currently propagate
1275+
// the literal back to the reference site — it's compiled cleanly by tsc
1276+
// but loses the Literal narrowing). Assert the concrete current shape so
1277+
// any future tightening of this path is a deliberate, visible change.
1278+
expect(types).toMatch(/kind:\s*string\b/);
1279+
expect(types).not.toMatch(/kind:\s*'circle'/);
12761280

12771281
expect(types).toMatchSnapshot();
12781282
expect(client).toMatchSnapshot();

packages/nx-plugin/src/open-api/utils/normalise.ts

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -265,24 +265,19 @@ const hoistInlineObjectSubSchemas = (
265265
* downstream hey-api/openapi-ts handles the enum shape but synthesises
266266
* phantom named references for the const shape.
267267
*/
268-
const rewriteConstToEnum = (spec: Spec): Spec => {
269-
const walk = (obj: any): void => {
270-
if (!obj || typeof obj !== 'object') {
271-
return;
272-
}
273-
if (Array.isArray(obj)) {
274-
obj.forEach(walk);
275-
return;
276-
}
277-
if ('const' in obj && !('enum' in obj)) {
278-
obj.enum = [obj.const];
279-
delete obj.const;
268+
const rewriteConstToEnum = (spec: Spec): Spec =>
269+
cloneDeepWith(spec, (v) => {
270+
if (
271+
v &&
272+
typeof v === 'object' &&
273+
!Array.isArray(v) &&
274+
'const' in v &&
275+
!('enum' in v)
276+
) {
277+
const { const: constValue, ...rest } = v;
278+
return cloneDeepWith({ ...rest, enum: [constValue] });
280279
}
281-
Object.values(obj).forEach(walk);
282-
};
283-
walk(spec);
284-
return spec;
285-
};
280+
});
286281

287282
/**
288283
* In order to ensure we generate models consistently whether or not users used refs or inline schemas,

0 commit comments

Comments
 (0)