From 2164424c3a9b88d286dae27ff7077ca4c5eaff08 Mon Sep 17 00:00:00 2001 From: Leshchev Artem Date: Fri, 10 Nov 2023 09:27:59 +0100 Subject: [PATCH] fix Date type (#131) Co-authored-by: Artem Leshchev --- .github/workflows/pr.yml | 2 +- __tests__/services/UriBuilder.spec.ts | 12 ++++++++---- libs/mappers.ts | 8 ++++++-- package-lock.json | 4 ++-- package.json | 2 +- .../angular/AngularServicesMethodGenerator.ts | 3 ++- src/models/EnumModel.ts | 1 + src/models/IdentityModel.ts | 1 + src/models/ObjectModel.ts | 1 + src/models/TypeModel.ts | 1 + src/services/ModelFinder.ts | 11 +++++++---- src/services/ModelMappingService.ts | 4 +++- src/services/ServiceMappingService.ts | 9 +++++++-- src/services/TypesService.ts | 16 ++++++++++------ 14 files changed, 51 insertions(+), 24 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index fa596e2..015c853 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -5,7 +5,7 @@ name: Build & Test on: pull_request: - branches: [ master, develop ] + branches: [ master ] jobs: build: diff --git a/__tests__/services/UriBuilder.spec.ts b/__tests__/services/UriBuilder.spec.ts index e1b692d..8ef0456 100644 --- a/__tests__/services/UriBuilder.spec.ts +++ b/__tests__/services/UriBuilder.spec.ts @@ -31,7 +31,8 @@ describe('UriBuilder tests', () => { type: { dtoType: 'IProduct', kind: PropertyKind.Object, - type: 'Product' + type: 'Product', + isNullable: true } }, originUri: 'get/{id}' @@ -67,7 +68,8 @@ describe('UriBuilder tests', () => { type: { dtoType: 'IProduct', kind: PropertyKind.Object, - type: 'Product' + type: 'Product', + isNullable: true } }, originUri: 'get' @@ -109,7 +111,8 @@ describe('UriBuilder tests', () => { type: { dtoType: 'IProduct', kind: PropertyKind.Object, - type: 'Product' + type: 'Product', + isNullable: true } }, originUri: 'get/{id}' @@ -157,7 +160,8 @@ describe('UriBuilder tests', () => { type: { dtoType: 'IProduct', kind: PropertyKind.Object, - type: 'Product' + type: 'Product', + isNullable: true } }, originUri: 'getByCustomer/{customer}/type/{type}' diff --git a/libs/mappers.ts b/libs/mappers.ts index d13fa22..7876987 100644 --- a/libs/mappers.ts +++ b/libs/mappers.ts @@ -9,7 +9,7 @@ export function mapCollection(dtoMapper: { fromDTO(value: TDTO): T } export function mapSingle(dtoMapper: { fromDTO(value: TDTO): TModel }): OperatorFunction, TypeOrUndefined> { - return map((z: TypeOrUndefined) => (z ? dtoMapper.fromDTO(z) : undefined)); + return map((x: TypeOrUndefined) => (x ? dtoMapper.fromDTO(x) : undefined)); } export function mapIdentityCollection(identity: { new (id: TypeOrUndefined): TModel }): OperatorFunction { @@ -17,9 +17,13 @@ export function mapIdentityCollection(identity: { new (id: TypeOrUndefin } export function mapIdentitySingle(identity: { new (id: TypeOrUndefined): TModel }): OperatorFunction, TypeOrUndefined> { - return map((z: TypeOrUndefined) => (z ? new identity(z.id) : undefined)); + return map((x: TypeOrUndefined) => (x ? new identity(x.id) : undefined)); } export function mapDate(): OperatorFunction> { return map(toDateIn); } + +export function mapDateStrict(): OperatorFunction { + return map((x) => toDateIn(x)!); +} diff --git a/package-lock.json b/package-lock.json index 831304c..35c82c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@luxbss/gengen", - "version": "1.2.0", + "version": "1.2.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@luxbss/gengen", - "version": "1.2.0", + "version": "1.2.3", "license": "MIT", "dependencies": { "commander": "11.1.0", diff --git a/package.json b/package.json index f1382b9..e161655 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@luxbss/gengen", - "version": "1.2.2", + "version": "1.2.3", "description": "Tool for generating models and Angular services based on OpenAPIs and Swagger's JSON", "bin": { "gengen": "./bin/index.js" diff --git a/src/generators/angular/AngularServicesMethodGenerator.ts b/src/generators/angular/AngularServicesMethodGenerator.ts index 3cf9764..c766721 100644 --- a/src/generators/angular/AngularServicesMethodGenerator.ts +++ b/src/generators/angular/AngularServicesMethodGenerator.ts @@ -114,13 +114,14 @@ export class AngularServicesMethodGenerator { return [PropertyKind.Object, PropertyKind.Identity, PropertyKind.Guid, PropertyKind.Date].includes(returnType.type.kind); } + protected createPipe(returnType: ITypeInfo): string { if (returnType.type.kind === PropertyKind.Guid) { return 'mapGuid()'; } if (returnType.type.kind === PropertyKind.Date) { - return `${MAPPERS_NAMESPACE}.mapDate()`; + return returnType.type.isNullable ? `${MAPPERS_NAMESPACE}.mapDate()` : `${MAPPERS_NAMESPACE}.mapDateStrict()`; } const type = `${MODELS_NAMESPACE}.${returnType.type.type}`; diff --git a/src/models/EnumModel.ts b/src/models/EnumModel.ts index 5ba83c1..3900be3 100644 --- a/src/models/EnumModel.ts +++ b/src/models/EnumModel.ts @@ -1,4 +1,5 @@ export interface IEnumModel { name: string; + isNullable: boolean; items: { key: string; value: number }[]; } diff --git a/src/models/IdentityModel.ts b/src/models/IdentityModel.ts index f91da89..600a453 100644 --- a/src/models/IdentityModel.ts +++ b/src/models/IdentityModel.ts @@ -2,6 +2,7 @@ import { IObjectPropertyModel } from './ObjectModel'; export interface IIdentityModel { name: string; + isNullable: boolean; dtoType: string; property: IObjectPropertyModel; } diff --git a/src/models/ObjectModel.ts b/src/models/ObjectModel.ts index b0c00cc..ff64ecd 100644 --- a/src/models/ObjectModel.ts +++ b/src/models/ObjectModel.ts @@ -9,5 +9,6 @@ export interface IObjectPropertyModel extends IType { export interface IObjectModel { name: string; dtoType: string; + isNullable: boolean; properties: IObjectPropertyModel[]; } diff --git a/src/models/TypeModel.ts b/src/models/TypeModel.ts index 5d3fa66..4ce6264 100644 --- a/src/models/TypeModel.ts +++ b/src/models/TypeModel.ts @@ -4,4 +4,5 @@ export interface IType { kind: PropertyKind; type: string; dtoType: string; + isNullable: boolean; } diff --git a/src/services/ModelFinder.ts b/src/services/ModelFinder.ts index 04f8ed7..e80083a 100644 --- a/src/services/ModelFinder.ts +++ b/src/services/ModelFinder.ts @@ -5,24 +5,27 @@ import { IOpenAPI3Reference } from '../swagger/v3/reference'; import { IModel } from './ServiceMappingService'; export class ModelFinder { - public constructor(private readonly openAPIService: OpenAPIService, private readonly models: IModelsContainer) {} + public constructor( + private readonly openAPIService: OpenAPIService, + private readonly models: IModelsContainer + ) {} public find(ref: IOpenAPI3Reference): IModel | undefined { const name = this.openAPIService.getSchemaKey(ref); const objectModel = this.models.objects.find((x) => x.name === name); if (objectModel) { - return { kind: PropertyKind.Object, name, dtoType: objectModel.dtoType }; + return { kind: PropertyKind.Object, name, dtoType: objectModel.dtoType, isNullable: objectModel.isNullable }; } const identityModel = this.models.identities.find((x) => x.name === name); if (identityModel) { - return { kind: PropertyKind.Identity, name, dtoType: identityModel.dtoType }; + return { kind: PropertyKind.Identity, name, dtoType: identityModel.dtoType, isNullable: identityModel.isNullable }; } const enumModel = this.models.enums.find((x) => x.name === name); if (enumModel) { - return { kind: PropertyKind.Enum, name, dtoType: name }; + return { kind: PropertyKind.Enum, name, dtoType: name, isNullable: enumModel.isNullable }; } return undefined; diff --git a/src/services/ModelMappingService.ts b/src/services/ModelMappingService.ts index 6c5d539..df89ea7 100644 --- a/src/services/ModelMappingService.ts +++ b/src/services/ModelMappingService.ts @@ -38,6 +38,7 @@ export class ModelMappingService { if (this.isIdentity(schema)) { identities.push({ name, + isNullable: false, dtoType: this.getInterfaceName(name), property: { ...this.typesService.getSimpleType(schema.properties['id'] as IOpenAPI3GuidSchema), @@ -63,6 +64,7 @@ export class ModelMappingService { private toEnumModel(name: string, schema: IOpenAPI3EnumSchema): IEnumModel { return { name, + isNullable: schema.nullable ?? false, items: schema.enum .map((value, index) => ({ key: schema['x-enumNames'][index], @@ -73,7 +75,7 @@ export class ModelMappingService { } private toObjectModel(name: string, schema: IOpenAPI3ObjectSchema): IObjectModel { - const model: IObjectModel = { name, dtoType: this.getInterfaceName(name), properties: [] }; + const model: IObjectModel = { name, isNullable: schema.nullable ?? false, dtoType: this.getInterfaceName(name), properties: [] }; if (!schema.properties) { return model; } diff --git a/src/services/ServiceMappingService.ts b/src/services/ServiceMappingService.ts index f9ad10d..86871db 100644 --- a/src/services/ServiceMappingService.ts +++ b/src/services/ServiceMappingService.ts @@ -29,6 +29,7 @@ import { TypesService } from './TypesService'; export interface IModel { name: string; dtoType: string; + isNullable: boolean; kind: PropertyKind; } @@ -132,7 +133,7 @@ export class ServiceMappingService { model.returnType = { isCollection: false, isModel: false, - type: { kind: PropertyKind.Object, type: 'IDownloadResult', dtoType: 'IDownloadResult' } + type: { kind: PropertyKind.Object, type: 'IDownloadResult', dtoType: 'IDownloadResult', isNullable: false } }; model.parameters.push({ @@ -220,7 +221,11 @@ export class ServiceMappingService { return undefined; } - return { isCollection, isModel: true, type: { kind: model.kind, dtoType: model.dtoType, type: model.name } }; + return { + isCollection, + isModel: true, + type: { kind: model.kind, dtoType: model.dtoType, type: model.name, isNullable: model.isNullable } + }; } private hasDownloadResponse(operation: IOpenAPI3Operation): boolean { diff --git a/src/services/TypesService.ts b/src/services/TypesService.ts index ab89386..ab1576b 100644 --- a/src/services/TypesService.ts +++ b/src/services/TypesService.ts @@ -5,25 +5,29 @@ import { OpenAPITypesGuard } from '../swagger/OpenAPITypesGuard'; import { OpenAPI3SimpleSchema } from '../swagger/v3/schemas/schema'; export class TypesService { - constructor(private readonly typesGuard: OpenAPITypesGuard, private readonly settings: IOptions) {} + constructor( + private readonly typesGuard: OpenAPITypesGuard, + private readonly settings: IOptions + ) {} public getSimpleType(schema: OpenAPI3SimpleSchema): IType { + const isNullable = schema.nullable ?? false; if (!this.settings.unstrictId && this.typesGuard.isGuid(schema)) { - return { kind: PropertyKind.Guid, type: 'Guid', dtoType: 'string' }; + return { kind: PropertyKind.Guid, type: 'Guid', dtoType: 'string', isNullable: isNullable }; } if (this.typesGuard.isDate(schema)) { - return { kind: PropertyKind.Date, type: 'Date', dtoType: 'string' }; + return { kind: PropertyKind.Date, type: 'Date', dtoType: 'string', isNullable: isNullable }; } if (this.typesGuard.isBoolean(schema)) { - return { kind: PropertyKind.None, type: 'boolean', dtoType: 'boolean' }; + return { kind: PropertyKind.None, type: 'boolean', dtoType: 'boolean', isNullable: isNullable }; } if (this.typesGuard.isNumber(schema)) { - return { kind: PropertyKind.None, type: 'number', dtoType: 'number' }; + return { kind: PropertyKind.None, type: 'number', dtoType: 'number', isNullable: isNullable }; } - return { kind: PropertyKind.None, type: 'string', dtoType: 'string' }; + return { kind: PropertyKind.None, type: 'string', dtoType: 'string', isNullable: isNullable }; } }