loopbackio / loopback-next

LoopBack makes it easy to build modern API applications that require complex integrations.
https://loopback.io
Other
4.96k stars 1.07k forks source link

Options param in SequelizeRepository create methods issue #10278

Open Akanksha13-dev opened 10 months ago

Akanksha13-dev commented 10 months ago

Describe the bug

options = { fields: { privateKey: false, publicKey: false, }, };

const result = await this.certificatesRepository.create( certificate, this.options, ); when we pass this.option param in create method getting error options.attributes.map is not a function. But working for findById.

Logs

[2023-12-28T08:09:29.630Z] error :: App_Log -> Request POST /tenants/f5408ba4-521f-4f96-fe87-bf0e6092ea16/certificates/ errored out. Error :: {} TypeError: options.attributes.map is not a function
Request POST /tenants/f5408ba4-521f-4f96-fe87-bf0e6092ea16/certificates/ failed with status code 500. TypeError: options.attributes.map is not a function
    at new Model (/Users/akanksha.singh/Desktop/telescope/telescope-health-backend-api/node_modules/sequelize/src/model.js:117:47)
    at new certificates (/Users/akanksha.singh/Desktop/telescope/telescope-health-backend-api/node_modules/sequelize/src/sequelize.js:466:19)
    at Function.build (/Users/akanksha.singh/Desktop/telescope/telescope-health-backend-api/node_modules/sequelize/src/model.js:2255:12)
    at Function.create (/Users/akanksha.singh/Desktop/telescope/telescope-health-backend-api/node_modules/sequelize/src/model.js:2305:23)
    at CertificatesRepository.create (/Users/akanksha.singh/Desktop/telescope/telescope-health-backend-api/node_modules/@loopback/sequelize/src/sequelize/sequelize.repository.base.ts:151:44)
    at CertificatesRepository.create (/Users/akanksha.singh/Desktop/telescope/telescope-health-backend-api/node_modules/@sourceloop/core/src/repositories/sequelize/sequelize-user-modify-crud.repository.base.ts:41:18)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at CommonHelperService.createCertificate (/Users/akanksha.singh/Desktop/telescope/telescope-health-backend-api/services/cbi-service/src/services/common-helper.service.ts:112:20)
    at ServiceSequence.handle (/Users/akanksha.singh/Desktop/telescope/telescope-health-backend-api/node_modules/@sourceloop/core/src/service-sequence.ts:113:22)
    at HttpHandler._handleRequest (/Users/akanksha.singh/Desktop/telescope/telescope-health-backend-api/node_modules/@loopback/rest/src/http-handler.ts:115:5)
[2023-12-28T08:09:29.652Z] info :: App_Log -> Request POST /tenants/f5408ba4-521f-4f96-fe87-bf0e6092ea16/certificates/ Completed in 1895ms

Additional information

No response

Reproduction

provided information is enough to understand the problem.

KalleV commented 10 months ago

I tested this one and it looks like you can pass an array of strings for the field names:

const result = await this.certificatesRepository.create(
certificate,
  {
    fields: [ "a", "b", "c" ]
  }
);

The loopback-style syntax would require the "fields" to be remapped here: https://github.com/loopbackio/loopback-next/blob/56201c5505a4e5b5b67022c02c98356a4b864862/extensions/sequelize/src/sequelize/sequelize.repository.base.ts#L170-L176

For example (note that the existing buildSequelizeAttributeFilter has a Typescript interface conflict with the create parameters):

  async create(entity: DataObject<T>, options?: AnyObject): Promise<T> {
    const data = await this.sequelizeModel.create(
      entity as MakeNullishOptional<T>,
      {
        ...options,
        fields: this.buildSequelizeAttributeFilter(options?.fields),
      },
    );
    return new this.entityClass(data.toJSON()) as T;
  }
major-winter commented 2 months ago

I believe that fields is a preserved word for the option and it's of type array. You may try to use another word instead of fields.