npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

genese

v1.2.2

Published

Documentation about @genese framework

Downloads

8

Readme

@genese

@genese is a tool suite composed by different modules which will improve your development velocity and increase your code quality. Some of these tools are accessible by command lines thanks to @genese/cli module, like @genese/complexity, and may be installed globally. Other tools are available as classic node-modules, like @genese/mapper, @genese/angular or @genese/api.

Table of Contents

Installation

Each Genese module may be installed separately :

@genese/complexity

@genese/complexity is a module which analyzes the code quality of a given project by analyzing its cyclomatic and cognitive complexities. This module creates an HTML report displaying an overview of the complexities index of each folder, file or method of your project. Moreover, you will find for each method the elements increasing complexity index, which will help you to refactor easier your code.

Dashboard Genese Complexity

More information on @genese/complexity official documentation.

Top

@genese/mapper

@genese/mapper maps objects of unknown type into the required type.

Basic usage

With @genese/mapper, you can transform untyped javascript objects into safe typed objects.

@genese/mapper exposes only one method, the create() method.

  • Example 1 : creation of a typed object
export class Person {

    name: string;

    hello(): void {
        console.log(`Hello ${this.name} !`);
    }
}

const data = {name: 'John'};
const person: Person = create(Person, data);    // person is a Person object
person.hello();                                 // log : 'Hello John !'

This is equivalent to :

const person: Person = new Person();
person.name = data.name;
  • Example 2 : creation of a more complex object

Now, assume that Person is a little more complex :

export class Person {

    age: number;
    cat: Cat;
    firstname: string;
    lastname: string;

    hello(): void {
        console.log(`Hello ${this.name} !`);
    }
}

export class Cat {
    name: string;

    meaow(): void {
        console.log(`Meaow !`);
    }
}

const data = {
    age: 20,
    cat: {
        name: 'Molly'
    },
    firstname: 'John',
    lastname: 'Doe',
};

In this case, it would be sufficiently long to create manually the Person object :

const cat: Cat = new Cat();
cat.name = data.cat.name;

const person: Person = new Person();
person.age = data.age;
person.firstname = data.firstname;
person.lastname = data.lastname;

person.hello(); // => logs 'Hello John !'
person.cat.meaow(); // => logs 'Meaow !'

With @genese/mapper, you can do it in one line :

const person: Person = create(Person, data);    // Person object which contains a Cat object

person.hello();                                 // log: 'Hello John !'
person.cat.meaow();                             // log: 'Meaow !'

The data object may be as complex as you want, you will still need only one line to create a real object, including nested objects if necessary.

  • Example 3 : validation of the data shape

The above usage simplifies the creation of known objects, the real power of @genese/mapper is to create safe typed objects even when you don't know the data value or even its shape.

Assume that you receive some data with unknown value or shape, like on http requests. You need to check the data shape and verify if its value respects your DTO contract :

interface PersonDto {
    name: string;
    skills: string[];
}

Without @genese/mapper, your controller in the backend could be written like this (example with NestJs) :

@Post()
addPerson(@Body() data: PersonDto) {
    if (isValid(data)) {
        addNewPersonToDataBase(data); // do some stuff
    }
}

isValid(data: any): data is PersonDto {
    return data
        && typeof data.name === 'string'
        && Array.isArray(data.skills)
        && data.skills.every(d => typeof d === 'string');
}

With @genese/mapper, you could simply do that :

@Post()
addPerson(@Body() data: PersonDto) {
    if (create('PersonDto', data)) { // create('PersonDto', data) is a PersonDto object if data is correct, undefined if not
        addNewPersonToDataBase(data);
    }
}

The create() method checks everything for you. If data value respects the contract of the interface PersonDto the create() method will return the data value. If data is incorrect, it will return undefined.

This method can be used with primitives, arrays, tuples, classes, interfaces, enums and types.

More information on @genese/mapper official documentation.

Top

@genese/angular

@genese/angular is an Angular library which replaces all the data-services of Angular applications. Thanks to @genese/mapper, it maps every data received from your http requests into the safe typed object that you'll need to use in your components.

Basic usage

@genese/angular replaces the http requests located in your services, and replaces the mappers used to format data coming from the backend into typed objects.

Returning typed objects from your data-services to your components is fundamental : if you do not, your component could receive incorrect data from the backend, and your application could crash. However, even if the mappers are important, they are also long and fastidious to write. Moreover, if you write mappers, you'll need to write unit tests for them, and add some mock values to be able to do these tests...

So, what would you say if @genese/angular could do all of that for you ? Yes, that's right : @genese/angular calls the http requests for you, and uses @genese/mapper which will send you back objects automatically typed !

In the below example, that means that you can simply put the file book-data.service.ts in the garbage, with its associated test file book-data.service.spec.ts.

  • Example

Actually, you probably have Angular data-services like this :

book.model.ts

export class Book = {
    id?: string;
    isAvailable?: boolean;
    name?: string;
    public editors?: [{
        name?: string,
        country.: string
    }];

    constructor() {}
}

book-data.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';

@Injectable({
    providedIn: 'root'
})
export class BookDataService {

    constructor(private http: HttpClient) {}

    mapToBook(data: any): Book {
        let book = new Book();
        if (data && data.id) {
            book.id = data.id;
            book.isAvailable : data.isAvailable ? data.isAvailable : false;
            book.name : data.name ? data.name : '';
            book.editors = [];
            if (Array.isArray(data.editors)) {
                for (let editor of data.editors) {
                    let newEditor = {};
                    newEditor.name = editor.name ? editor.name : '';
                    newEditor.country = editor.country ? editor.country : '';
                    book.editors.push(newEditor);
                }
            }
        }
        return book;
    }

    getOne(id: string): Observable<Book> {
        this.http.get('http://localhost:3000/' + id)
            .pipe(
                map((data: any) => {
                    return this.mapToBook(data);
                }
            )
    }

    getAll(): Observable<Book[]> {
        this.http.get('http://localhost:3000/')
            .pipe(
                map((data: any) => {
                    let books = [];
                    if (Array.isArray(data)) {
                        for (let element of data) {
                            books.push(this.mapToBook(element));
                        }
                    }
                    return books;
                }
            )
    }

    delete(id: string) {
        // call DELETE request and do some stuff
    }

    update(id: string) {
        // call PUT request and do some stuff
    }

    // other CRUD methods
}

With @genese/angular, you simply need to call GeneseService inside your components, like this :

Supposing that in your environment.ts, genese.api = http://localhost:3000 .

books.component.ts

export class BooksComponent {

    public booksGenese: Genese<Book>;

    constructor(private geneseService: GeneseService) {
        this.booksGenese = geneseService.getGeneseInstance(Book);
    }

    this.booksGenese.getOne('/books', '1').subscribe((book: Book) => {
         // book is the data returned by 
         // the request http://localhost:3000/books/1
         // and formatted with type Book
    });
}

With the getOne() method, you are sure to receive your data correctly formatted with Book's type. No data-services to write, and no unit tests to do.

More information on @genese/angular official documentation.

Top

@genese/api

@genese/api is a code generator for Angular and React apps which generates all your DTOs and data-services from your OpenApi (Swagger) file.

You simply need to create you OpenApi file and launch @genese/api : all your DTOs and data-services will be automatically generated. Moreover, with the help of @genese/mapper, all these data-services will use and return typed objects corresponding to the schemas included in your OpenApi file.

@genese/api may be used in combination with @genese/angular to remove both the necessity to create DTOs, data-services and calls to http requests.

More information on @genese/api official documentation.

Top

@genese/cli

@genese/cli is a command line interface to ease the use of some @genese packages, like @genese/complexity or @genese/api.

More information on @genese/cli official documentation.

Top

@genese/core

@genese/core is a set of tools used by some @genese packages.

It should not be installed separately.

Github repository : @genese/core.