Giter Club home page Giter Club logo

nestjs-library-crud's People

Contributors

csy1204 avatar dependabot[bot] avatar hseoy avatar jadenkim-dev avatar jiho-kr avatar kibae avatar lavelee avatar pigrabbit avatar thilllon avatar wbdc-phong-do 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

nestjs-library-crud's Issues

Cannot use package in commonJS

When I tried to use @nestjs-libary/crud version 0.4.6 in my cjs project, I got following error.

Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/dh.kang/workspace/woowa/nestjs-monorepo/node_modules/@nestjs-library/crud/dist/cjs/index.js from /Users/dh.kang/workspace/woowa/nestjs-monorepo/dist/packages/apps/opstool-hub/main.js not supported.
index.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which declares all .js files in that package scope as ES modules.
Instead rename index.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change "type": "module" to "type": "commonjs" in /Users/dh.kang/workspace/woowa/nestjs-monorepo/node_modules/@nestjs-library/crud/package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).

[Issue] Exception is not instance of HttpException

Hi there, I have some question about exception occurred in this library.
Is there a reason for the exception thrown by the library is not instance of HttpException?

It seems that if some exception occurs while processing the request, it responses 500 internal server error, even when the exception is instance of HttpException. (ex. NotFoundException, UnprocessableEntityException, ...)

For example, if I request not existing entity data with route like /user/999, it responses 500.

{
    "statusCode": 500,
    "message": "Internal server error"
}

NestJS default ExceptionFilter catch HttpException, so I expected it works, but it didn't.
I had to define my own ExceptionFilter that catches all Error, and apply it by using decorators option of @Crud.

@Crud({
  entity: User,
  routes: {
    [Method.READ_ONE]: {
      decorators: [UseFilters(new HttpExceptionFilter())],
    }
  }
})

In the catch method, I logged to check if the exception is instance of HttpException, and it says it is not instance of HttpException.

@Catch(Error)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    console.log(exception instanceof HttpException);  // false
    console.log(exception.name);  // 'NotFoundException'
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const status = exception.getStatus();  // it works, so it has properties of HttpException

    response.status(status).json({
      statusCode: status,
      message: "HttpException occurred",
    });
  }
}

Why is this happening?
If possible, I want to use default exception filter of NestJS.

add support for table inheritance

Hello, Jeongmin Lee, jiho-kr , all the woowabros, and all the maintainers of this repo, first of all thank you for this amazing library.
I'm a novice in nestjs and TypeORM especially, so id really appreciate if someone can guide me on how i can help resolve the issue of not being able to use table inheritance.
The route factory is unable to resolve the entity name (i tried matching if the type of the table is not entity-child, but that led to "Cannot read properties of undefined (reading 'ownColumns')").
I started with unit tests (read-many only for now).
PR: #388

[Regression]: 0.11.0 , nested entity update support broke readMany

Hello, as always, thank you for the amazing lib,

Last week's feature #389 to be able to support table inheritence has rendered readMany and readOne to break, the lib wasnt able to read the metadata of the entity thus making it break them, reverted to 0.10.2 and everything works...

I can provider a minimal reproduction repo if necessary

Error: Cannot find Entity name from TypeORM

Hello,

First off love the library and am excited to use it in a new project my company is working on. But I'm having some trouble with my user entity and I can't figure out why.

I'm following your guide, except my user is in a company NPM package and looks like this:
image

Extended from a BaseEntity which also extends BaseEntity:
image

Here's the error I'm getting:
image

package.json deps:

{ "@liaoliaots/nestjs-redis": "^9.0.5", "@nestjs-library/crud": "^0.8.8", "@nestjs/bull": "^10.0.1", "@nestjs/common": "^10.2.10", "@nestjs/config": "^3.1.1", "@nestjs/core": "^10.2.10", "@nestjs/jwt": "^10.2.0", "@nestjs/passport": "^10.0.2", "@nestjs/platform-express": "^10.2.10", "@nestjs/swagger": "^7.1.16", "@nestjs/throttler": "^5.0.1", "@nestjs/typeorm": "^10.0.1", "@sentry/node": "^7.85.0", "@sentry/tracing": "^7.85.0", "@swc/jest": "^0.2.29", "axios": "^1.6.2", "bcrypt": "^5.1.1", "bull": "^4.11.5", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", "cookie": "^0.6.0", "cookie-parser": "^1.4.6", "express": "^4.18.2", "fast-xml-parser": "^4.3.2", "fastify": "^4.24.3", "joi": "^17.11.0", "jsonwebtoken": "^9.0.2", "nanoid": "3", "nestjs-paginate": "^8.5.0", "nestjs-pino": "^3.5.0", "passport-apple": "^2.0.2", "passport-facebook": "^3.0.0", "passport-google-oauth20": "^2.0.0", "passport-jwt": "^4.0.1", "pg": "^8.11.3", "pino": "^8.16.2", "pino-http": "^8.5.1", "pino-webpack-plugin": "^2.0.0", "rxjs": "^7.8.1", "supertest": "^6.3.3", "typeorm": "^0.3.17" }

I'd appreciate any support you can lend since I feel I'm close and I don't wanna crud everything manually!

CrudService.getRepository getter 관련

Discussed in #24

Originally posted by woowahan-kibae February 11, 2023
CrudService에서 getRepository 라는 public getter로 저장소를 노출하고 있습니다.
get accessor 이름으로 getRepository 는 안맞는것 같아서 아래 두가지 방식 중 하나를 제안해 봅니다~

  • getter가 아닌 getRepository() 메쏘드로 바꾸기
getRepository(): Repository<T> {
    return this.repository;
}
  • getRepository가 아닌 CrudService.repository로 바꾸기(readonly 만 추가)
constructor(protected readonly repository: Repository<T>) {...}
```</div>

Cursor pagination of search method is not working with ViewEntity which lacks PK

Hi, there 👋🏼

I tried to use @crud with TypeORM's ViewEntity and found out that Cursor pagination of search method is not working as I expected.

I'll share the test code I have written to let you recognize the problem below.

import { Controller, INestApplication, Module } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { InjectRepository, TypeOrmModule, getDataSourceToken } from '@nestjs/typeorm';
import { IsNumber } from 'class-validator';
import request from 'supertest';
import { DataSource, Repository, ViewColumn, ViewEntity } from 'typeorm';

import { Crud, CrudService, Method } from '../../src';
import { BaseEntity } from '../base/base.entity';
import { TestHelper } from '../test.helper';

@ViewEntity('view_base_name', {
    expression: `
        SELECT DISTINCT id, name, type % 2 as category FROM base
    `,
})
export class BaseNameView {
    @ViewColumn()
    id: string;

    @ViewColumn()
    name: string;

    @ViewColumn()
    @IsNumber({}, { groups: [Method.READ_MANY, Method.SEARCH] })
    category: number;
}

class BaseNameViewService extends CrudService<BaseNameView> {
    constructor(@InjectRepository(BaseNameView) repository: Repository<BaseNameView>) {
        super(repository);
    }
}

@Crud({ entity: BaseNameView, only: [Method.READ_MANY, Method.SEARCH] })
@Controller('base-name')
class BaseNameViewController {
    constructor(public readonly crudService: BaseNameViewService) {}
}

@Module({
    imports: [TypeOrmModule.forFeature([BaseEntity, BaseNameView])],
    controllers: [BaseNameViewController],
    providers: [BaseNameViewService],
})
class BaseNameViewModule {}

describe('Cursor Pagination View', () => {
    let app: INestApplication;
    let dataSource: DataSource;

    beforeAll(async () => {
        const module = await Test.createTestingModule({
            imports: [TestHelper.getTypeOrmPgsqlModule([BaseEntity, BaseNameView]), BaseNameViewModule],
        }).compile();

        app = module.createNestApplication();
        await app.init();

        dataSource = module.get<DataSource>(getDataSourceToken('default'));
        await dataSource.query('DELETE FROM base');
        await dataSource.query(`
            INSERT INTO base (name, type, description) VALUES 
                ('apple', 1, 'This is an apple'), 
                ('bear', 2, 'This is a bear'), 
                ('charlie', 3, 'This is charlie'),
                ('dog', 4, 'This is a dog'),
                ('elephant', 5, 'This is an elephant'),
                ('frog', 6, 'This is a frog'),
                ('giraffe', 7, 'This is a giraffe'),
                ('horse', 8, 'This is a horse'),
                ('iguana', 9, 'This is an iguana'),
                ('jaguar', 10, 'This is a jaguar'),
                ('kangaroo', 11, 'This is a kangaroo'),
                ('lion', 12, 'This is a lion'),
                ('monkey', 13, 'This is a monkey'),
                ('newt', 14, 'This is a newt'),
                ('owl', 15, 'This is an owl'),
                ('penguin', 16, 'This is a penguin'),
                ('quail', 17, 'This is a quail'),
                ('rabbit', 18, 'This is a rabbit'),
                ('snake', 19, 'This is a snake'),
                ('tiger', 20, 'This is a tiger'),
                ('unicorn', 21, 'This is a unicorn'),
                ('vulture', 22, 'This is a vulture'),
                ('whale', 23, 'This is a whale'),
                ('xerus', 24, 'This is a xerus'),
                ('yak', 25, 'This is a yak'),
                ('zebra', 26, 'This is a zebra')
        `);
    });

    afterAll(async () => {
        await dataSource.query('DELETE FROM base');
        await app.close();
    });

    it('should be able to paginate', async () => {
        const firstResponse = await request(app.getHttpServer())
            .post('/base-name/search')
            .send({ take: 5, order: { id: 'ASC' } });
        expect(firstResponse.status).toBe(200);
        expect(firstResponse.body.data.length).toBe(5);

        const secondResponse = await request(app.getHttpServer()).post('/base-name/search').send({
            nextCursor: firstResponse.body.metadata.nextCursor,
        });
        expect(secondResponse.status).toBe(200);
        expect(secondResponse.body.data.length).toBe(5);

        // each and every item in the second response should not be in the first response
        for (const item of secondResponse.body.data) {
            expect(firstResponse.body.data.every((firstItem: { id: any }) => firstItem.id !== item.id)).toBeTruthy();
        }
    });
});

`routes` option should match with `only` option in `@crud` decorator

routes option should match with only option in @crud decorator. This could make this lib more robust I think.

image

@Crud({
    entity: SkuBmartProductEntity,
    only: [Method.CREATE, Method.UPDATE],
    routes: {
        create: {
            decorators: [ApiOperation({ summary: 'some description' })],
        },
        // should show possible options only
        // thus `delete?`... should not appear
    },
})

README instructions do not work as expected

I may have made a mistake, but I was able to resolve the issue by making the following modifications.

Step 1: Define a TypeORM entity

not work:

...
@Entity()
export class User {
...

You may encounter an error message error TS2344: Type 'User' does not satisfy the constraint 'BaseEntity'. or Error: Cannot find Entity name from TypeORM.

try this:

import { 
 ...,
 BaseEntity 
} from "typeorm";

@Entity('user')
export class User extends BaseEntity {
...

Step 2: Create Service and Controller

not work:

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { CrudService } from '@nestjs-library/crud';
import { Repository } from 'typeorm';

import { User } from './user.entity';

@Injectable()
export class UserService extends CrudService<User> {
    constructor(@InjectRepository(BaseEntity) repository: Repository<User>) {
        super(repository);
    }
}

try this:

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { CrudService } from '@nestjs-library/crud';
import { Repository } from "typeorm";

import { User } from './user.entity';

@Injectable()
export class UsersService extends CrudService<User> {
  constructor(@InjectRepository(User) repository: Repository<User>) {
    super(repository);
  }
}
  • Change the parameter of the InjectRepository decorator from BaseEntity to User

[ISSUE]: Update failing when primary key is @PrimaryColumn instead of @PrimaryGeneratedColumn

Description:
When attempting to update an entity that has a PrimaryColumn decorator the update fails because it doesnt include the id of the entity in the mutation setting it to null. Tried using an interceptor to force the payload body to have he ID inferred from the path param but that resulted in a failed mutation too because it counted as a new insert that violates unique constraint.

Steps to Reproduce:
Define an entity with a PrimaryColumn primary key
Attempt to update
Expected Behavior:
Update successful and new entity returned.
Actual Behavior:
A 409 http error code exception is thrown that signals that the row's primary key is null

Screenshots:
image

Environment:
Database: Postgres SQL
Library Version: v0.12.0
Node version: v21.5.0

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.