From ad9231534207e86b3abe8f81d8ec3ea59c34e4ac Mon Sep 17 00:00:00 2001 From: Simon Hofer Date: Mon, 20 Apr 2026 09:33:52 +0200 Subject: [PATCH] chore: make properties of *_Some_References deeply optional --- src/generator/04-services/endpoints/some.ts | 8 ++++---- src/ts/generateObject.spec.ts | 17 +++++++++++++++++ src/ts/generateObject.ts | 9 ++++++--- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/generator/04-services/endpoints/some.ts b/src/generator/04-services/endpoints/some.ts index 3d98888..9d4fc43 100644 --- a/src/generator/04-services/endpoints/some.ts +++ b/src/generator/04-services/endpoints/some.ts @@ -68,7 +68,7 @@ const resolveArrayReferenceProperties = ( ([property, propertyMetaData]): ObjectProperty[] => { if (propertyMetaData.type === 'array') { if (propertyMetaData.entity === 'onlyId') { - return [{ key: property, value: [{ key: 'id', value: 'boolean' }] }]; + return [{ key: property, value: [{ key: 'id', value: 'boolean', optional: true }], optional: true }]; } if (!propertyMetaData.entity) { @@ -85,11 +85,11 @@ const resolveArrayReferenceProperties = ( return []; } - return [{ key: property, value: nestedProperties }]; + return [{ key: property, value: nestedProperties, optional: true }]; } if (property.endsWith('Id')) { - return [{ key: property, value: 'boolean' }]; + return [{ key: property, value: 'boolean', optional: true }]; } return []; @@ -114,7 +114,7 @@ const resolveReferences = (entity: string, entities: Map { expect(result).toContain('/** A number */'); expect(result).toContain('x: 1'); }); + + it('renders optional properties with a question mark', () => { + const result = generateObject([{ key: 'x', value: 1, optional: true }]); + expect(result).toContain('x?: 1'); + }); + + it('does not render question mark when optional is false', () => { + const result = generateObject([{ key: 'x', value: 1, optional: false }]); + expect(result).toContain('x: 1'); + expect(result).not.toContain('x?'); + }); + + it('does not render question mark when optional is not set', () => { + const result = generateObject([{ key: 'x', value: 1 }]); + expect(result).toContain('x: 1'); + expect(result).not.toContain('x?'); + }); }); diff --git a/src/ts/generateObject.ts b/src/ts/generateObject.ts index e4fd172..aa24f1a 100644 --- a/src/ts/generateObject.ts +++ b/src/ts/generateObject.ts @@ -5,12 +5,13 @@ export interface ObjectProperty { key: string; value: string | number | undefined | null | boolean | ObjectProperty[]; comment?: string; + optional?: boolean; } export const generateObject = (properties: ObjectProperty[]): string => { const body = []; - for (const { key, value, comment } of properties) { + for (const { key, value, comment, optional } of properties) { if (value === undefined) { continue; } @@ -19,10 +20,12 @@ export const generateObject = (properties: ObjectProperty[]): string => { const str = generateObject(value); if (str.length > 2) { - body.push(`${comment ? generateInlineComment(comment) + '\n' : ''}${key}: ${str}`); + body.push(`${comment ? generateInlineComment(comment) + '\n' : ''}${key}${optional ? '?' : ''}: ${str}`); } } else { - body.push(`${comment ? generateInlineComment(comment) + '\n' : ''}${key}: ${String(value)}`); + body.push( + `${comment ? generateInlineComment(comment) + '\n' : ''}${key}${optional ? '?' : ''}: ${String(value)}` + ); } }