Skip to content

Commit 76cec72

Browse files
committed
feat: wip implement toJSON scan
1 parent 9e5d8d9 commit 76cec72

File tree

4 files changed

+46
-1
lines changed

4 files changed

+46
-1
lines changed

src/metadataGeneration/typeResolver.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,22 @@ export class TypeResolver {
254254
return stringMetaType;
255255
}
256256

257+
const type = this.current.typeChecker.getTypeFromTypeNode(this.typeNode);
258+
const toJSON = this.current.typeChecker.getPropertyOfType(type, 'toJSON');
259+
if (toJSON) {
260+
const declaration = toJSON.declarations[0] as ts.MethodDeclaration;
261+
const signature = this.current.typeChecker.getSignatureFromDeclaration(declaration);
262+
const returnType = this.current.typeChecker.getReturnTypeOfSignature(signature!);
263+
try {
264+
const resolved = new TypeResolver(this.current.typeChecker.typeToTypeNode(returnType)!, this.current, this.parentNode, this.context).resolve() as Tsoa.ReferenceType;
265+
resolved.refName = typeReference.getText();
266+
this.current.AddReferenceType(resolved);
267+
return resolved;
268+
} catch {
269+
// ignore methods
270+
}
271+
}
272+
257273
if (this.context[typeReference.typeName.text]) {
258274
return new TypeResolver(this.context[typeReference.typeName.text], this.current, this.parentNode, this.context).resolve();
259275
}

tests/fixtures/controllers/getController.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Readable } from 'stream';
22
import { Controller, Example, Get, OperationId, Query, Request, Route, SuccessResponse, Tags } from '../../../src';
33
import '../duplicateTestModel';
4-
import { GenericModel, TestClassModel, TestModel, TestSubModel } from '../testModel';
4+
import { GenericModel, GetterClass, TestClassModel, TestModel, TestSubModel } from '../testModel';
55
import { ModelService } from './../services/modelService';
66

77
@Route('GetTest')
@@ -58,6 +58,11 @@ export class GetTestController extends Controller {
5858
return new ModelService().getClassModel();
5959
}
6060

61+
@Get('GetterClass')
62+
public async getGetterClass(): Promise<GetterClass> {
63+
return new GetterClass();
64+
}
65+
6166
@Get('Multi')
6267
public async getMultipleModels(): Promise<TestModel[]> {
6368
return [new ModelService().getModel(), new ModelService().getModel(), new ModelService().getModel()];

tests/fixtures/testModel.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,18 @@ export class TestClassModel extends TestClassBaseModel {
618618
}
619619
}
620620

621+
export class GetterClass {
622+
public a: 'b';
623+
624+
get foo() {
625+
return 'bar';
626+
}
627+
628+
public toJSON() {
629+
return Object.assign({}, { a: this.a }, { foo: this.foo });
630+
}
631+
}
632+
621633
export interface GenericModel<T = string> {
622634
result: T;
623635
union?: T | string;

tests/unit/swagger/definitionsGeneration/definitions.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,18 @@ describe('Definition generation', () => {
682682
`for a schema linked by property ${propertyName}`,
683683
);
684684

685+
const getterClass = getValidatedDefinition('GetterClass', currentSpec);
686+
expect(getterClass).to.deep.eq({
687+
properties: {
688+
a: { type: 'string', default: undefined, description: undefined, format: undefined, example: undefined, enum: ['b'], 'x-nullable': false },
689+
foo: { type: 'string', default: undefined, description: undefined, format: undefined, example: undefined },
690+
},
691+
required: ['foo', 'a'],
692+
type: 'object',
693+
description: undefined,
694+
additionalProperties: false,
695+
});
696+
685697
const omitHiddenReference = getValidatedDefinition('Pick_PrivateModel.Exclude_keyofPrivateModel.stringPropDec1__', currentSpec);
686698
expect(omitHiddenReference).to.deep.eq(
687699
{

0 commit comments

Comments
 (0)