Skip to content
/ eicrud Public

A CRUD/Authorization framework based on NestJS. Get your CRUD app up and running in no time! ⚙️🔒

License

Notifications You must be signed in to change notification settings

eicrud/eicrud

Repository files navigation

@eicrud/eicrud logo

Static Badge npm package Static Badge X (formerly Twitter) Follow

Eicrud is CRUD/Authorization framework extending NestJS.
It's a tool for building scalable, secure Node.js server applications in record time.

Philosophy

Most of the time, a web app has some CRUD functionality as its base. Eicrud attempts to abstract this into a simple and easy-to-use API, so you don't have to re-write boilerplate code (controllers, validations, db queries...) every time you need a new service. By centering everything around CRUD entities, Eicrud provides a framework for writing complex applications that are easy to read, test and maintain. Eicrud also emphasizes "default security" for its components, where everything is forbidden until allowed.

Features

How it works

Under the hood, Eicrud uses MikroOrm entities guarded with CASL and class-validator.

Here's a quick example

You first define your entity with validations and transforms (what the data can be).

@Entity()
export class Profile {
  @PrimaryKey()
  @IsString()
  @IsOptional()
  id: string;

  @OneToOne(() => MyUser, (user) => user.profile)
  @IsString()
  owner: MyUser | string;

  @Property()
  @$Transform((val) => val.toLowerCase())
  @MaxLength(30)
  userName: string;
}

Then define your security (who can access the data).

const security: CrudSecurity = {
  user: {
    async defineCRUDAbility(can, cannot, ctx) {
      const id = ctx.userId;
      // users can crud their own profile
      can('crud', 'profile', { owner: id });
    },
  },
  guest: {
    async defineCRUDAbility(can, cannot, ctx) {
      // guests can read all profiles
      can('read', 'profile');
    },
  },
};

And finally, register your service.

@Injectable()
export class ProfileService extends CrudService<Profile> {
  constructor(protected moduleRef: ModuleRef) {
    super(moduleRef, Profile, security);
  }
}

That's it, profile is now a fully operational CRUD service that you can query with the client.

const client = new CrudClient({ serviceName: 'profile' });

const res = await client.findOne({ userName: 'jon doe' });

You can extend it using commands (for non-CRUD operations).

Monolithic/Microservices duality

Eicrud lets you group your CRUD services into "microservices" with a simple configuration. You can start developing a monolith and easily switch to microservices later on.

msOptions.microServices = {
  "entry": {
    services: [],
    openBackDoor: false, openController: true,
    url: "http://localhost:3004",
  },
  "users": {
    services: [User, Profile],
    openBackDoor: true, openController: false,
    url: "http://localhost:3005",
  },
  "orders": {
    services: [Order],
    openBackDoor: true, openController: false,
    url: "http://localhost:3006",
  },
}

Powerful typed client (remote procedure call)

Eicrud lets you generate a powerful super-client that holds all your DTOs and commands. Allowing auto-completion and type safety directly in your front-end.

// in your profile service
async $say_hello(dto: SayHelloDto, ctx: CrudContext) {
    return `Hello ${dto.arg}!`
}

// in your frontend
const sp = new SuperClient({url: 'http://localhost:3004'});
sp.profile.say_hello({myArg: 'world'}).then(console.log);

Start building

Eicrud is made for code simplicity, you can build your applications in record time using the CLI that will do the heavy work for you.

Check out the documentation to get started.

Support

Eicrud is in active development and issues are taken seriously. Don't hesitate to create a ticket or join the Discord if you need help.