Code Monkey home page Code Monkey logo

loopback4-soft-delete's Introduction

ARC By SourceFuse logo

npm version Sonar Quality Gate Synk Status GitHub contributors downloads License Powered By LoopBack 4

Install

npm install loopback4-soft-delete

Quick Starter

For a quick starter guide, you can refer to our loopback 4 starter application which utilizes this package for soft-deletes in a multi-tenant application.

Usage

The package exports following classes and mixins:

  1. SoftDeleteEntity - To add required soft delete props in the model.
  2. SoftCrudRepository - Class providing soft crud capabilitiies (to be used in place of DefaultCrudRepository).
  3. SoftCrudRepositoryMixin - Mixin accepting any respository that extends the DefaultCrudRepository to add soft delete functionality to. Can be used as a wrapper for DefaultCrudRepository, DefaultTransactionalRepository etc.
  4. SoftDeleteEntityMixin
  5. DefaultTransactionSoftCrudRepository (Deprecated) - Class providing soft crud capabilitiies. To be used in place of DefaultTransactionalRepository.
  6. SequelizeSoftCrudRepository - Class providing soft crud capabilitiies for @loopback/sequelize package. To be used in place of SequelizeCrudRepository.

Following are more details on the usage of above artifcats:

SoftDeleteEntity

An abstract base class for all models which require soft delete feature. This class is a wrapper over Entity class from @loopback/repository adding three attributes to the model class for handling soft-delete, namely, deleted, deletedOn, deletedBy. The column names needed to be there in DB within that table are - 'deleted', 'deleted_on', 'deleted_by'. If you are using auto-migration of loopback 4, then, you may not need to do anything specific to add this column. If not, then please add these columns to the DB table.

SequelizeSoftCrudRepository

An abstract base class providing soft delete capabilities for projects using @loopback/sequelize package. All the other workings are similar to SoftCrudRepository, except it's imported using directory import syntax from loopback4-soft-delete/sequelize.

SoftCrudRepository

An abstract base class for all repositories which require soft delete feature. This class is going to be the one which handles soft delete operations and ensures soft deleted entries are not returned in responses, However if there is a need to query soft deleted entries as well, there is an options to achieve that and you can use findAll() in place of find() , findOneIncludeSoftDelete() in place of findOne() and findByIdIncludeSoftDelete() in place of findById(), these will give you the responses including soft deleted entries. This class is a wrapper over DefaultCrudRepository class from @loopback/repository.

DefaultTransactionSoftCrudRepository (Deprecated)

Note: DefaultTransactionSoftCrudRepository is deprecated in favour of SoftCrudRepositoryMixin and will be removed in future releases.

An abstract base class similar to SoftCrudRepository but with transaction support.

This class is a wrapper over DefaultTransactionalRepository class from @loopback/repository.

In order to use this extension in your application, please follow below steps.

  1. Extend models with SoftDeleteEntity class replacing Entity. Like below:
import {model, property} from '@loopback/repository';
import {SoftDeleteEntity} from 'loopback4-soft-delete';

@model({
  name: 'users',
})
export class User extends SoftDeleteEntity {
  @property({
    type: 'number',
    id: true,
  })
  id?: number;

  // .... More properties
}
  1. Extend repositories with SoftCrudRepository class replacing DefaultCrudRepository. Like below:
import {Getter, inject} from '@loopback/core';
import {SoftCrudRepository} from 'loopback4-soft-delete';
import {AuthenticationBindings, IAuthUser} from 'loopback4-authentication';

import {PgdbDataSource} from '../datasources';
import {User, UserRelations} from '../models';

export class UserRepository extends SoftCrudRepository<
  User,
  typeof User.prototype.id,
  UserRelations
> {
  constructor(
    @inject('datasources.pgdb') dataSource: PgdbDataSource,
    @inject.getter(AuthenticationBindings.CURRENT_USER, {optional: true})
    protected readonly getCurrentUser: Getter<IAuthUser | undefined>,
  ) {
    super(User, dataSource, getCurrentUser);
  }
}
  1. For transaction support, use the SoftCrudRepositoryMixin and wrap it around DefaultTransactionalRepository. Like below:
import {Getter, inject} from '@loopback/core';
import {SoftCrudRepository} from 'loopback4-soft-delete';
import {AuthenticationBindings, IAuthUser} from 'loopback4-authentication';

import {PgdbDataSource} from '../datasources';
import {User, UserRelations} from '../models';

export class UserRepository extends SoftCrudRepositoryMixin<
  User,
  typeof User.prototype.id,
  UserRelations
>(DefaultTransactionalRepository) {
  constructor(
    @inject('datasources.pgdb') dataSource: PgdbDataSource,
    @inject.getter(AuthenticationBindings.CURRENT_USER, {optional: true})
    protected readonly getCurrentUser: Getter<IAuthUser | undefined>,
  ) {
    super(User, dataSource, getCurrentUser);
  }
}

Mixins Usage

The package also provides the following mixins which can be used for soft delete functionality:

SoftDeleteEntityMixin

This mixin adds the soft delete properties to your model. The properties added are represented by the IBaseEntity interface:

There is also an option to provide config for the @property decorator for all these properties.

Usage of SoftDeleteEntityMixin is as follows:

class Item extends Entity {
  @property({
    type: 'number',
    id: true,
    generated: true,
  })
  id?: number;

  @property({
    type: 'string',
    required: true,
  })
  name: string;

  constructor(data?: Partial<Item>) {
    super(data);
  }
}

@model()
export class ItemSoftDelete extends SoftDeleteEntityMixin(Item, {
  deletedBy: {
    name: 'deleted_by_userid',
  },
}) {}

IBaseEntity

The soft deleted properties added by SoftDeleteEntityMixin are represented by IBaseEntity interface.

interface IBaseEntity {
  deleted?: boolean;
  deletedOn?: Date;
  deletedBy?: string;
}

SoftCrudRepositoryMixin

You can make use of this mixin to get the soft delete functionality for DefaultCrudRepository or any respository that extends the DefaultCrudRepository. You need to extend your repository with this mixin and provide DefaultCrudRepository (or any repository that extends DefaultCrudRepository) as input. This means that this same mixin can also be used to provide soft delete functionality for DefaultTransactionSoftCrudRepository (as DefaultTransactionSoftCrudRepository extends DefaultCrudRepository). You will have to inject the getter for IAuthUser in the contructor of your repository.

Example:

import {Constructor, Getter, inject} from '@loopback/core';
import {DefaultCrudRepository} from '@loopback/repository';
import {AuthenticationBindings, IAuthUser} from 'loopback4-authentication';
import {SoftCrudRepositoryMixin} from 'loopback4-soft-delete';
import {TestDataSource} from '../datasources';
import {ItemSoftDelete, ItemSoftDeleteRelations} from '../models';

export class ItemRepository extends SoftCrudRepositoryMixin<
  ItemSoftDelete,
  typeof ItemSoftDelete.prototype.id,
  Constructor<
    DefaultCrudRepository<
      ItemSoftDelete,
      typeof ItemSoftDelete.prototype.id,
      ItemSoftDeleteRelations
    >
  >,
  ItemSoftDeleteRelations
>(DefaultCrudRepository) {
  constructor(
    @inject('datasources.test') dataSource: TestDataSource,
    @inject.getter(AuthenticationBindings.CURRENT_USER)
    public getCurrentUser: Getter<IAuthUser>,
  ) {
    super(ItemSoftDelete, dataSource);
  }
}

Additional Repository Methods

Following are some additional methods that you can use when working with repositories in your application, either by extending the base repositories provided or by using the SoftCrudRepositoryMixin:

  1. findAll - This method is similar to find, but it returns entries including soft deleted ones.
  2. deleteHard - This method is used to perform a hard delete on a specified entity.
  3. deleteByIdHard - This method is used to perform a hard delete of an entity based on the provided ID.
  4. findByIdIncludeSoftDelete - This method is similar to findById, but it returns the entity even if it is soft deleted.
  5. deleteAllHard - This method is used to perform a hard delete of multiple entities based on a specified condition.
  6. findOneIncludeSoftDelete - This method is similar to findOne, but it returns a single entity even if it is soft deleted.
  7. countAll - This method is similar to count, but it returns the total count of all entities including soft deleted ones.

deletedBy

Whenever any entry is deleted using deleteById, delete and deleteAll repository methods, it also sets deletedBy column with a value with user id whoever is logged in currently. Hence it uses a Getter function of IUser type. However, if you want to use some other attribute of user model other than id, you can do it by overriding deletedByIdKey. Here is an example.

import {Getter, inject} from '@loopback/core';
import {SoftCrudRepository, IUser} from 'loopback4-soft-delete';
import {AuthenticationBindings} from 'loopback4-authentication';

import {PgdbDataSource} from '../datasources';
import {User, UserRelations} from '../models';

export class UserRepository extends SoftCrudRepository<
  User,
  typeof User.prototype.id,
  UserRelations
> {
  constructor(
    @inject('datasources.pgdb') dataSource: PgdbDataSource,
    @inject.getter(AuthenticationBindings.CURRENT_USER, {optional: true})
    protected readonly getCurrentUser: Getter<User | undefined>,
  ) {
    super(User, dataSource, getCurrentUser);
  }
}

Model class for custom identifier case. Notice the getIdentifier() method and IUser interface implemented.

@model()
class User extends SoftDeleteEntity implements IUser {
  @property({
    id: true,
  })
  id: string;

  @property()
  username: string;

  getIdentifier() {
    return this.username;
  }

  constructor(data?: Partial<User>) {
    super(data);
  }
}

License

MIT

loopback4-soft-delete's People

Contributors

akshatdubeysf avatar ankurbansalsf avatar arpit1503khanna avatar barleendhaliwal avatar bhupesh-sf avatar dependabot[bot] avatar faizan1620 avatar gautam23-sf avatar jyoti-13 avatar mateusmeyer avatar nareshkharola123 avatar prernagp avatar raghavarorasf avatar sachin6161 avatar samarpan-b avatar semantic-release-bot avatar sf-kansara avatar sf-sahil-jassal avatar sfdevops avatar shubhamp-sf avatar sumiter92 avatar surbhi-sharma1 avatar tejinder8585 avatar tyagi-sunny avatar yeshamavani avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

loopback4-soft-delete's Issues

Correction to the changelog format

Describe the bug
The changelog is not genearted properly.
To Reproduce
Steps to reproduce the behavior:

  1. Release a new tag all.
  2. Check the changelog.
  3. The issue description is not present

Expected behavior
All the formatting should be proper

Screenshots

image

findById() fetches the record which is soft deleted in DB

Describe the bug
findById returns the record successfully, even if the record is soft deleted in DB.

To Reproduce
Steps to reproduce the behavior:

  1. Call method findById()
  2. it will return the record even if the record is soft deleted.

Expected behavior
If the record is soft-deleted, it should not return the record.

Ability to query soft deleted records

Is your feature request related to a problem? Please describe.
It could be useful in some use cases to query for deleted records. E.g.: Send notification to all users of tenant A that tenant A was deleted. On tenant A soft delete, all its user tenants will also be deleted so querying that information after delete will yield no results.

Describe the solution you'd like
By default deleted: false is applied whenever a query to database is made. E.g.:
{where: {'firstName': 'John'}} is modified to {where: {'firstName': 'John', deleted: false}}
Before modifying this query directly, we can check if query has a deleted parameter. If it has then don't modify the query.
{where: {'firstName': 'John'}} is modified to {where: {'firstName': 'John', deleted: false}}
but
{where: {'firstName': 'John', deleted: true}} is not modified because user is explicitly searching for deleted records

Pseudo code for implementation could look like:

modifyQuery(where: Where<SoftDeleteEntity>) {
  const modifiedWhere = {...where, deleted: where?.deleted ? where.deleted : false}
}

Describe alternatives you've considered
No alternatives considered yet.

Remove support for node v14

Is your feature request related to a problem? Please describe.
Node v14 reaching its end of life this month. Loopback removes support for node v14 in all of its packages we depend on.

Sourceloop packages/services also currently have v12 and v14 as the supported versions.

Describe the solution you'd like
Remove the support for node v14 and v12. And add the support for the latest LTS version v18.

Describe alternatives you've considered
__

Additional context
__

Test case coverage lacking

Describe the bug
Test case coverage missing and not up to the mark

To Reproduce
We should have at least 75% unit test case coverage for this package.

When using SoftCrudRepository can't use relations in findById

When using SoftCrudRepository can't use relations in findById.
The find(filter, filter) works fine. But findById(id, filter) don't work.

To Reproduce

  1. Create an model with BelongsTo or any relation
  2. Extends the repository with SoftCrudRepository
  3. In the controller use find({include: {relation: ['RELATION_NAME']}} -> this will work
  4. In the controller use findById(id, {include: {relation: ['RELATION_NAME']}} -> this will not work

multiple DB calls while using findById

FindById has the below statement which can be reduced by checking the deleted flag and in turn improving performance
const entityToRemove = await super.findOne(filter, options);
if (entityToRemove) {
// Now call super
return super.findById(id, filter, options);
}
else {
throw new rest_1.HttpErrors.NotFound("EntityNotFound" /* ErrorKeys.EntityNotFound */);
}

Unable to get count of all instances of an entity

Describe the bug
Unable to get count of all instances of an entity, as the soft deleted entities are never counted and their is no way to override this functionality like one is provided for other methods like delete.

To Reproduce
Steps to reproduce the behavior:

  1. Call the delete method with filter to include delete=true instances as well.
  2. The returned array only contains non deleted instances.

Expected behavior
There should be a way to override this behaviour, to allow fetching or counting all the records, deleted or not.

The deletedBy column value should be configurable.

Is your feature request related to a problem? Please describe.

  1. Right now when a entity is soft-deleted in the deleted by column we insert the userId by default.
    Also many applications use userTenantId in the createdBy and modifyBy columns. So to maintain uniformity it should be configurable.

  2. loopback4-authentication : should not a part of peer-dependency in here.
    As it makes mandatory for user to use only this particular package for authentication.
    All our sourecloop packages should be independent.

Can't use migrate in loopback when use this module

When we implement class SoftCrudRepository from this module
When run migrate script, it always return an error
image

Migrating schemas (alter existing schema) Cannot migrate database schema { ResolutionError: The argument 'BaseEntityDigitalAssetRepository.constructor[0]' is not decorated for dependency injection but no value was supplied by the caller. Did you forget to apply @inject () to the argument? (context: MainApplication-llRl2lIGS2mNtF2YxaD_Vw-0, resolutionPath: repositories.BaseEntityDigitalAssetRepository)

explicitly setting `deleted` column to `false` strips out other fields in the response

Describe the bug

In the find() function and others when we specify the fields filter and set deleted: false it actually ends up only selecting deleted due to the imposing behaviour of fields (i.e. we require fields to include deleted column, after this issue #91)

To Reproduce
Steps to reproduce the behavior:

  1. Pass { "fields": { "deleted": false } } in the filter of a request.
  2. See the response, It won't include other fields except deleted.

Expected behavior

It should have included all the model properties except deleted since it is set to false in the fields filter.

Additional context

Requiring fields to include deleted to make soft-delete work shouldn't be required as I've just tried for postgres and found out that to run condition like deleted: false loopback didn’t require me to have “deleted” column in the fields.

Methods like: `findAll`, `deleteHard`, `deleteByIdHard` etc. have no documentation.

Is your feature request related to a problem? Please describe.
Methods like: findAll, deleteHard, deleteByIdHard etc. have no documentation for users to know that they exists and what they do.

Describe the solution you'd like
Include extra functions provided by soft-delete package in documentation with their usage.

Describe alternatives you've considered
__

Additional context
__

findById return EntityNotFound when we using mongodb

When we using loopback4 with database mongodb
We also using id generate by MongoDb with field name _id, without using id field
In SoftCrudRepository into this package , when findById, it using id only

`//As parent method findById have filter: FilterExcludingWhere
//so we need add check here.
const entityToRemove = await super.findOne(filter, options);

if (entityToRemove) {
  // Now call super
  return super.findById(id, filter, options);
} else {
  throw new HttpErrors.NotFound(ErrorKeys.EntityNotFound);
}`

That take entityToRemove always null then it return an error

Deprecate `DefaultTransactionSoftCrudRepository` to improve code maintainability

Is your feature request related to a problem? Please describe.

Currently we provide separate base class for soft crud capabilities for loopback's DefaultTransactionRepository which is not needed because same can be achieved using already provided SoftCrudRepositoryMixin.
Keeping duplicate code in SoftCrudRepository, Mixin and this transaction soft crud repository adds duplication and degrades code maintainability.

Describe the solution you'd like

Deprecate DefaultTransactionSoftCrudRepository in favour of SoftCrudRepositoryMixin which will help in keeping our code in sync between repository and mixin method implementations.

Request for more detailed and customizable changelog

Is your feature request related to a problem? Please describe.
Right now the changelog created for releases is not well in detail and informative.
Request to generate detailed changelog.

Describe the solution you'd like
Can use different npm packages available

Add capability for deleted_on, deleted_by attributes

Its a good practice to track the deleted timestamp and deletion actor on every soft delete of row. We should have it.

Describe the solution you'd like
We should have 2 new columns added to the model deletedOn and deletedBy. deletedOn should update automatically on soft delete operations for every row from repository. deletedBy should update if current user id is available. current user will come from one of the bindings of loopback4-authentication package. deletedBy should be set only if loopback4-authentication package is sued by consumer, or else, it should stay null.

Filter mixup in find function when using an or/and condition.

Describe the bug
In soft-crud.repository.base.ts, the find function update the 'filter' parameter to add a 'deleted:false' condition. However, in some case, this is not done correctly and the filter is incorrectly updated...and so the final query is incorrect.

To Reproduce
Example of my filter:

in   find(filter?: Filter<T>, options?: Options): Promise<(T & Relations)[]> {
filter is filled like below
{
  order: {[ 'xxx ASC']},
  where: {
    id: {eq: 2},
    myColumn: 42,
    or: {[
       {a:1},
       {b:2}
    ]}
  }

The "find" function expect a where filter to start with where:{AND: or where: {OR. If the where filter doesn't start with an AND array or OR array, the filter expect an object (which is an implicit AND), and add "deleted:false"

When the object contain an AND / OR property, with other properties in the object, the filter is incorrectly updated...and so the final query is incorrect.

in soft-crud.repository.base.ts
find(filter?: Filter<T>, options?: Options): Promise<(T & Relations)[]> {
    // Filter out soft deleted entries
    if (
      filter?.where &&
      (filter.where as AndClause<T>).and &&
      (filter.where as AndClause<T>).and.length > 0
    ) {
      (filter.where as AndClause<T>).and.push({
        deleted: false,
      } as Condition<T>);
    } else if (
      filter?.where &&
      (filter.where as OrClause<T>).or &&
      (filter.where as OrClause<T>).or.length > 0
    ) {
      filter.where = {
        and: [
          {
            deleted: false,
          } as Condition<T>,
          {
            or: (filter.where as OrClause<T>).or,
          },
        ],
      };
    } else {
      filter = filter ?? {};
      filter.where = filter.where ?? {};
      (filter.where as Condition<T>).deleted = false;
    **}**

Expected behavior
The find function should better detect when AND/OR/{} is used, and when or or and is not alone in the object.

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context
Add any other context about the problem here.

Add support for Sequelize as base repository from `loopback4-sequelize` package

Problem

Potential projects utilizing loopback4-sequelize package won't be able to use soft-delete capabilities as for now, because the base here is DefaultCrudRepository which needs to be changed.

Solution

  1. Export a repository factory that can be used in place of SoftCrudRepository (from loopback4-soft-delete) but with utilizing sequelize capabilities.
  2. Export a repository factory that can be used in place of DefaultUserModifyCrudRepository (from @sourceloop/core package) but with utilizing sequelize capabilities.

Alternatives

Solution no. 2 can be also implemented in @sourceloop/core repository.

trying to implement softdelete entity error in migration

i'm trying to use your model to check when a user erase a entity but running migrate

/home/georman/Documents/fullStackTemplate/crm-api/dist/models/agency.model.js:13
let Agency = Agency_1 = class Agency extends _1.SoftDeleteEntity {
^

TypeError: Class extends value undefined is not a constructor or null
at /home/georman/Documents/fullStackTemplate/crm-api/dist/models/agency.model.js:13:53
at Object. (/home/georman/Documents/fullStackTemplate/crm-api/dist/models/agency.model.js:128:3)

Stale Bot missing in the repository

Describe the bug
Currently the issues and PR never closed even if inactive.
They should be closed automatically.

To Reproduce
Steps to reproduce the behavior:

  1. Create a new issue/Pr
  2. Observe it.
  3. Even after no activity it stays open.

Expected behavior
Inactive issues/Pr should be closed automatically.

Can I extend MyBaseCrudRepository to use SoftCrudRepository

I have a base repository class

export class BaseCrudRepository<
    E extends Entity,
    IdType,
    Relations extends object
    > extends DefaultCrudRepository<E, IdType, Relations> {

    constructor(
        public entityClass: typeof Entity & {prototype: E},
        public dataSource: juggler.DataSource,
    ) {
        super(entityClass, dataSource);
    }

   addMetaInfo(
      conditions: Where<E>
    ): Promise<TBaseCrudRepositoryMeta> {
      ...
    }
}

And I want to use SoftCrudRepository as an extension for my BaseCrudRepository but not for DefaultCrudRepository. Can I achieve it?

I am trying to do something like that

export class SoftDeleteCrudRepository<
  E extends Entity,
  IdType,
  Relations extends object
> extends SoftCrudRepository<E, IdType, Relations> {
  baseRepository: any;

  constructor(
      entityClass: typeof SoftDeleteEntity & { prototype: E },
      dataSource: juggler.DataSource
  ) {
    super(entityClass, dataSource);
    this.baseRepository = defineRepositoryClass<
        typeof Feed,
        BaseCrudRepository<Feed, typeof Feed.prototype.id, FeedRelations>
        >(Feed, BaseCrudRepository);
  }

  addMetaInfo(
    conditions: Where<E>
  ) {
    return this.baseRepository.addMetaInfo(conditions);
  }
}

cant install loopback4-soft-delete : dependency tree problem because of bad loopback/repository version.

Describe the bug
You cant install loopback4-soft-delete because of a dependency tree problem

To Reproduce
npm install loopback4-soft-delete

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: @loopback/[email protected]
npm ERR! node_modules/@loopback/repository
npm ERR! @loopback/repository@"^3.7.1" from the root project
npm ERR! @loopback/repository@"^3.7.1" from @loopback/[email protected]
npm ERR! node_modules/@loopback/boot
npm ERR! @loopback/boot@"^3.4.2" from the root project
npm ERR! peer @loopback/boot@"^3.4.0" from [email protected]
npm ERR! node_modules/loopback4-soft-delete
npm ERR! loopback4-soft-delete@"" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer @loopback/repository@"^3.16.0" from [email protected]
npm ERR! node_modules/loopback4-soft-delete
npm ERR! loopback4-soft-delete@"
" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

Expected behavior
Should install normally without any error

Additional context
The problem come from
#30 where loopback/repository version was setted from "@loopback/repository": "^3.2.0" -> "^3.16.0". Currently, loopback repository version is 3.7.1
https://github.com/loopbackio/loopback-next/blob/master/packages/repository/package.json

findById returns soft deleted record when fields filter is used

Describe the bug
findById returns soft deleted record when fields filter is used. If "deleted" field is not included to be part of the record object, then soft deleted record also gets returned.

To Reproduce
Steps to reproduce the behavior:

  1. Create a filter using loopback "fields" filter, by not including deleted property to be part of the entity. For example:-
    fields: { id: true, header: true, content: true, wordsCount: true, modifiedOn: true, },
  2. Try to pass the id of a soft-deleted record in findById.
  3. The object of the soft-deleted entry will be returned.

Expected behavior
The soft-deleted record should not be returned. It should throw "Entity not found".

v7.2.0 throws error when loopback4-sequelize is not installed

Describe the bug

Due to the Sequelize soft crud repository being exported by default in the repository/index.ts and the sequelize package being an optional peer dependency. It throws the following error:

Error: Can not find module 'loopback4-sequelize'

To Reproduce
Steps to reproduce the behavior:

  1. Install the v7.2.0 of this package.
  2. Try starting the the target loopback app
  3. See the error

Expected behavior
It should allow using the soft-delete package without loopback4-sequelize being installed in the project. As it's optional.

Screenshots

image

Additional context
Add any other context about the problem here.

sync test cases across repositories

Is your feature request related to a problem? Please describe.
Recently added countAll method has test cases written only in mixin. This should be done for all repositories.

Describe the solution you'd like
Sync test cases across repositories we provide like transaction, sequelize etc.

Describe alternatives you've considered
__

Additional context
This is not problematic but needed some commits to release previously unpublished changes.

Create Mixins for SoftDeleteEntity, DefaultTransactionSoftCrudRepository and SoftCrudRepository classes

Is your feature request related to a problem? Please describe.
As of now, the package provides SoftDeleteEntity model, DefaultTransactionSoftCrudRepository and SoftCrudRepository that can be extended by the user, but the properties in the model are not configurable. Exporting the model and repositories as Mixin would provide an option to make them configurable, as well as make it easier to work with other classes.

Describe the solution you'd like
Create mixin for SoftDeleteEntity, DefaultTransactionSoftCrudRepository and SoftCrudRepository

Refactor Codebase to Improve Flexibility and Maintainability

Is your feature request related to a problem? Please describe.

The main exports in the package are SoftCrudRepositoryMixin, the SoftCrudRepository class and one for transaction repo. Aiming to serve the same purpose with different underlying class but with mixin it's possible to pass any other class as base having similar interface as DefaultCrudRepository from loopback.

Recently a requirement arrived to make it compatible to somewhat different repository from loopback4-sequelize package called SequelizeCrudRepository. It doesn't completely follows the DefaultCrudRepository's interface as it lacks some irrelevant properties, preventing user from using the mixin wrapping sequelize repository.

What we ended up doing is to solve this is, we created a copy of the soft-delete logic code and created new class similar to SoftCrudRepository by just replacing the extended class to the sequelize one and exported it as SequelizeSoftCrudRepository.

The issue with above approach

This brought up major challenge when it comes to maintaining the code. Like any bug fix or any sort of change is supposed to be made in all four places (mixin, main soft crud, transaction repo and sequelize soft crud repo) plus the additional effort for every change in respective test cases as well.
More than maintainability, users won't be able to utilize soft-delete capabilities in any custom class like the sequelize one that doesn't have all the props like default crud repo, due to the strictness of mixin accepting DefaultCrudRepository constructor as a base class's type (where as the mixin only needs few methods to work correctly namelyfindOne, findById, find, updateAll, updateById, deleteById, deleteAll and count ).

Describe the solution you'd like

By behaviour the soft-delete package only adds extra logic before calling the main crud methods. Like modifying the where filter before the super.find is invoked. It doesn't care if the base class received is DefaultCurdRepository or the transaction repo or the sequelize one. All it wants is that, it should have a find method (and few others) that it can call.

So having the type more explicit than Constructor<DefaultCrudRepository> would be more flexible and would cover all the extension cases for Transaction, Sequelize and others we may encounter in future. Doing so will eliminate the need of exporting other classes as everyone can use the mixin universally for each of current and future use cases. Leading us to have no duplicate code.

Additional context

Implementing the above-described solution will result in a BREAKING CHANGE, but it solves two major problems:

  1. It improves the maintainability of the code by removing duplicates.
  2. It makes the mixin more adaptable to different base classes beyond just the DefaultCrudRepository class.

findById returns keys with undefined when fields filter is array

Describe the bug
findById returns keys with undefined when fields filter is array. if fields filter is array it return empty object

To Reproduce
Steps to reproduce the behavior:

  1. Create a filter using loopback "fields" filter, fields with array of property. For example:-
    fields: [ "id", "header", "content"],
  2. when we call findById with this fields filter
  3. The object keys with undefined values will returned
    returned values: {id:undefined, header: undefined, content: undefined }

Expected behavior
It should return object with keys that we pass with fields with array

Package Update - loopback4-soft-delete

Describe the bug
remove all current vilnenrability of loopback4-soft-delete

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context
Add any other context about the problem here.

semantic-release : patch release via chore

Describe the bug
Changes for semantic-release
when dependencies are updated with chore type new version is not released

To Reproduce
try updating the dependencies using chore(deps)

Expected behavior
when dependencies are updated with chore type new version must be released

Semantic Release

Is your feature request related to a problem? Please describe.
Adding semantic release for automatic release of packages.

Describe the solution you'd like
Using npm semantic-release

Describe alternatives you've considered

Additional context

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.