FoalTS / foal

Full-featured Node.js framework, with no complexity. 🚀 Simple and easy to use, TypeScript-based and well-documented.
https://foalts.org/
MIT License
1.88k stars 137 forks source link

AJV @ValidateBody schema regression in FoalTS 3.0 #1192

Closed warren-gallagher closed 1 year ago

warren-gallagher commented 1 year ago

Version of FoalTS: 3.0

The following worked in Foal 2.x but fails in 3.0. To get it to work in Foal 3.0, I had to remove the use of the "example" keyword from each of the schema properties.

import { Context, Post, HttpResponseOK, HttpResponseCreated, dependency, Get, Delete, HttpResponseNotFound, HttpResponseServerError, HttpResponseInternalServerError, HttpResponseUnauthorized, HttpResponseBadRequest, HttpResponseConflict, HttpResponseForbidden, ApiDefineHeader, ApiSecurityRequirement, MergeHooks } from '@foal/core';
import { ValidatePathParam, ValidateQueryParam, ValidateBody, ValidateHeader } from '@foal/core';
import { ApiUseTag, ApiOperationId, ApiOperationDescription, ApiOperationSummary, ApiResponse, ApiDefineSchema, IApiSchema } from '@foal/core';
import { DidPosture } from '../services/organization.service';
import { OrganizationService } from '../services';
import { Organization } from '../entities';

const organizationCreateSchema : IApiSchema = {
  additionalProperties: false,
  properties: {
      name: { type: 'string', example: 'My Organization Name', description: 'The name of the new organization.'},
      logoUrl: { type: 'string', example: 'http://issuer-website.com/issuer-image.png', description: 'The URL to an image representing the logo for this organization.' },
      organizationId: { type: 'string', example: '5b3d3536-f44a-4492-bb40-0a5bbf288176', description: 'The AffinitiQuest.io organization identifier.' },
      didPosture: {type: 'string', enum: [DidPosture.public, DidPosture.private], example: 'public', description: 'will the Did for this organization be publically published on the ledger or not.'}
  },
  required: ['name', 'logoUrl', 'organizationId', 'didPosture'],
  type: 'object',
}

@ApiDefineSchema('organization-create-schema', organizationCreateSchema)

@ApiUseTag('organization - Operations related to managing organizations')
export class OrganizationController {

  @dependency
  organizationService: OrganizationService;

  @Post('/')
  @ApiOperationId('createOrganization')
  @ApiOperationDescription('Creates a new organization/wallet, creates a Did in the wallet and optionally on the ledger (if query parameter didposture=public). ')
  @ApiOperationSummary('Create an organization')
  @ApiResponse(201, { description: 'Organization created.', content: {'application/json': {schema: { $ref: '#/components/schemas/organization-response-schema' }}}  })
  @ApiResponse(400, { description: 'Bad Request. Error while attempting to create, typically due to bad parameters'})
  @ApiResponse(401, { description: 'Unauthorized. Probably due to an invalid api key'})
  @ApiResponse(409, { description: 'Conflict. Duplicate name'})
  @ApiResponse(500, { description: 'Internal Server Error. Probably due to Aries API being down'})
  @ValidateBody({$ref: '#/components/schemas/organization-create-schema'})
  async createOrganization(ctx: Context) {
    const organizationId = ctx.request.body.organizationId;
    const organizationName = ctx.request.body.name;
    const logoUrl = ctx.request.body.logoUrl;
    const didPosture = ctx.request.body.didPosture;
    const httpResponse = await this.organizationService.createOrganization(organizationId, organizationName, logoUrl, didPosture);
    return httpResponse;
  }
}
LoicPoullain commented 1 year ago

Thank you for reporting this issue! It comes from the version 8 of AJV which has the strict mode enabled.

The PR has been merged and the fix will be released with version 3.1.0 👍