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

@codegenerator/node-gen

v3.0.4

Published

NodeJS code generator from database.

Downloads

27

Readme

Node.js Project Generator

Este repositório contém um conjunto de geradores TypeScript para criar a estrutura de um projeto NestJS completo, incluindo módulos, controladores, serviços, entidades TypeORM, DTOs e arquivos de configuração.

Instalação

O node-gen é um pacote Node.js que pode ser instalado globalmente via npm. O registro estaá disponível em @codegenerator/node-gen, então você pode instalar o pacote diretamente a partir do NPM.

Para instalar todas as dependências necessárias, execute o comando:

npm install -g @codegenerator/node-gen

Uso

Este repositório contém vários geradores para criar diferentes partes de um projeto NestJS. Aqui está uma breve descrição de cada gerador:

  • db.reader.postgres.ts: Lê a estrutura do banco de dados PostgreSQL e gera um arquivo JSON com a definição do esquema.
  • typeorm-entity-generator.ts: Gera entidades TypeORM com base na definição do esquema.
  • service-generator.ts: Gera serviços NestJS com base nas entidades geradas.
  • interface-generator.ts: Gera interfaces para as entidades e serviços.
  • controller-generator.ts: Gera controladores NestJS com base nos serviços gerados.
  • dto-generator.ts: Gera DTOs (Data Transfer Objects) com base nas entidades geradas.
  • module-generator.ts: Gera módulos NestJS com base nos controladores e serviços gerados.
  • app-module-generator.ts: Gera o módulo principal do aplicativo NestJS.
  • main-generator.ts: Gera o arquivo de entrada principal do aplicativo NestJS.
  • env-generator.ts: Gera arquivos de configuração de ambiente.
  • package-json-generator.ts: Gera o arquivo package.json para o projeto.
  • readme-generator.ts: Gera o arquivo README.md para o projeto gerado.

Executando o Gerador

Para executar o gerador e criar toda a estrutura do projeto, use o script db.reader.postgres.sh:

./db.reader.postgres.sh

Este script executará todos os geradores na ordem correta e copiará os arquivos estáticos para o diretório ./build.

Estrutura do Projeto Gerado

Após a execução do script, a estrutura do projeto gerado será semelhante a esta:

./build
├── LICENSE
├── README.md
├── app.module.ts
├── controller
│   ├── example.controller.ts
├── dto
│   ├── create-example.dto.ts
│   ├── update-example.dto.ts
├── entity
│   ├── example.entity.ts
├── interface
│   ├── example.interface.ts
├── main.ts
├── module
│   ├── example.module.ts
├── service
│   ├── example.service.ts
├── static
│   ├── add-header.js
│   ├── bitbucket-pipelines.yml
│   ├── config
│   │   ├── app.readiness.service.ts
│   │   ├── datasource.service.ts
│   │   ├── environment.module.ts
│   │   ├── environment.service.ts
│   │   └── httpsource.service.ts
│   ├── docker-compose.yaml
│   ├── docker-start.sh
│   ├── health
│   │   ├── health.controller.ts
│   │   ├── health.database.indicator.ts
│   │   ├── health.module.ts
│   │   └── health.service.ts
│   ├── jest.config.ts
│   ├── middleware
│   │   ├── jwt-auth.guard.module.ts
│   │   └── jwt-auth.guard.ts
│   ├── tsconfig.build.json
│   ├── tsconfig.json
│   ├── validators
│   │   └── constraint.isRecentDate.ts
│   └── version
│       ├── version.controller.ts
│       └── version.module.ts

Executando o Projeto Gerado

Para executar o projeto gerado, use os seguintes comandos:

  1. Navegue até o diretório ./build:

    cd build
  2. Instale as dependências do projeto gerado:

    npm install
  3. Inicie o projeto:

    npm start

Isso iniciará o servidor NestJS usando as configurações geradas.


Licença

Este projeto é licenciado sob a licença MIT - veja o arquivo LICENSE para mais detalhes.

Para adicionar o gerador de README ao script db.reader.postgres.sh, basta incluir a chamada ao readme-generator.ts no final do script:

rm -rf ./build

npx ts-node db.reader.postgres.ts
npx ts-node typeorm-entity-generator.ts
npx ts-node service-generator.ts
npx ts-node interface-generator.ts
npx ts-node controller-generator.ts
npx ts-node dto-generator.ts
npx ts-node module-generator.ts
npx ts-node app-module-generator.ts
npx ts-node main-generator.ts
npx ts-node env-generator.ts
npx ts-node package-json-generator.ts
npx ts-node readme-generator.ts

cp -r ./static/* ./build/

publicação

Para atualizar no NPM, execute um dos os comandos:

npm run publish:patch

ou

npm run publish:minor

ou

npm run publish:major

Pre-requisitos

Crie seu modelo relacional no PostgreSQL e em seguida execute o script abaixo para criar as funções e triggers necessários para garantir a integridade dos dados.

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
SELECT uuid_generate_v4();

CREATE FUNCTION public.prevent_created_at_update() RETURNS trigger
    LANGUAGE plpgsql
    AS $$
BEGIN
    IF OLD IS NOT NULL AND NEW.created_at <> OLD.created_at THEN
        RAISE EXCEPTION 'Não é possível atualizar o campo created_at após a criação do registro.';
    END IF;
    RETURN NEW;
END;
$$;

CREATE FUNCTION public.prevent_deleted_at_update() RETURNS trigger
    LANGUAGE plpgsql
    AS $$
BEGIN
    IF OLD IS NOT NULL AND OLD.created_at IS NOT null THEN
        RAISE EXCEPTION 'Não é possível atualizar o campo deleted_at.';
    END IF;
    RETURN NEW;
END;
$$;

CREATE FUNCTION public.prevent_delete() RETURNS trigger
    LANGUAGE plpgsql
    AS $$
BEGIN
    RAISE EXCEPTION 'Não é possível excluir o registro. Operação não permitida.';
    RETURN NEW;
END;
$$;

CREATE FUNCTION public.prevent_update() RETURNS trigger
    LANGUAGE plpgsql
    AS $$
BEGIN
    RAISE EXCEPTION 'Não é possível atualizar o registro. Operação não permitida.';
    RETURN NEW;
END;
$$;

DO $$
DECLARE
    tbl RECORD;
    col_exists BOOLEAN;
    trg_update_name TEXT;
    trg_delete_name TEXT;
    trg_update_deleted_at_name TEXT;
    index_name TEXT;
BEGIN
    -- Lista todas as tabelas no esquema public com prefixo 'tb_'
    FOR tbl IN 
        SELECT tablename
        FROM pg_tables
        WHERE schemaname = 'public' AND tablename LIKE 'tb_%'
    LOOP
        -- Verifica se a coluna 'created_at' já existe na tabela
        SELECT EXISTS (
            SELECT 1 
            FROM information_schema.columns 
            WHERE table_schema = 'public' 
              AND table_name = tbl.tablename 
              AND column_name = 'created_at'
        ) INTO col_exists;

        -- Se a coluna não existir, adiciona a coluna 'created_at'
        IF NOT col_exists THEN
            EXECUTE format('ALTER TABLE %I ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP', tbl.tablename);
        END IF;

        -- Adiciona ou atualiza o comentário na coluna 'created_at'
        EXECUTE format('COMMENT ON COLUMN %I.created_at IS ''Data de criação do registro.''', tbl.tablename);

        -- Verifica se a coluna 'updated_at' já existe na tabela
        SELECT EXISTS (
            SELECT 1 
            FROM information_schema.columns 
            WHERE table_schema = 'public' 
              AND table_name = tbl.tablename 
              AND column_name = 'updated_at'
        ) INTO col_exists;

        -- Se a coluna não existir, adiciona a coluna 'updated_at'
        IF NOT col_exists THEN
            EXECUTE format('ALTER TABLE %I ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP', tbl.tablename);
        END IF;

        -- Adiciona ou atualiza o comentário na coluna 'updated_at'
        EXECUTE format('COMMENT ON COLUMN %I.updated_at IS ''Data de atualização do registro.''', tbl.tablename);

        -- Verifica se a coluna 'deleted_at' já existe na tabela
        SELECT EXISTS (
            SELECT 1 
            FROM information_schema.columns 
            WHERE table_schema = 'public' 
              AND table_name = tbl.tablename 
              AND column_name = 'deleted_at'
        ) INTO col_exists;

        -- Se a coluna não existir, adiciona a coluna 'deleted_at'
        IF NOT col_exists THEN
            EXECUTE format('ALTER TABLE %I ADD COLUMN deleted_at TIMESTAMP', tbl.tablename);
        END IF;

        -- Adiciona ou atualiza o comentário na coluna 'deleted_at'
        EXECUTE format('COMMENT ON COLUMN %I.deleted_at IS ''Data da exclusão lógica do registro.''', tbl.tablename);

        -- Verifica se a coluna 'external_id' já existe na tabela
        SELECT EXISTS (
            SELECT 1 
            FROM information_schema.columns 
            WHERE table_schema = 'public' 
              AND table_name = tbl.tablename 
              AND column_name = 'external_id'
        ) INTO col_exists;

        -- Se a coluna não existir, adiciona a coluna 'external_id'
        IF NOT col_exists THEN
            EXECUTE format('ALTER TABLE %I ADD COLUMN external_id UUID DEFAULT uuid_generate_v4() NOT NULL', tbl.tablename);
        END IF;

        -- Adiciona ou atualiza o comentário na coluna 'external_id'
        EXECUTE format('COMMENT ON COLUMN %I.external_id IS ''Identificador único externo de registros desta tabela. Este campo é obrigatório.''', tbl.tablename);

        -- Nome do índice único na coluna 'external_id'
        index_name := tbl.tablename || '_external_id_idx';

        -- Cria o índice único na coluna 'external_id' se não existir
        IF NOT EXISTS (
            SELECT 1 
            FROM pg_indexes 
            WHERE tablename = tbl.tablename
              AND indexname = index_name
        ) THEN
            EXECUTE format('CREATE UNIQUE INDEX %I ON %I (external_id)', index_name, tbl.tablename);
        END IF;
        
        -- Nome das triggers baseado no nome da tabela
        trg_update_name := tbl.tablename || '_fire_update_rules';
        trg_delete_name := tbl.tablename || '_fire_delete_rules';
        trg_update_deleted_at_name := tbl.tablename || '_fire_update_deleted_at_rules';
        
        -- Verifica se a trigger de update já existe e a remove se necessário
        IF EXISTS (
            SELECT 1 
            FROM pg_trigger 
            WHERE tgname = trg_update_name 
              AND tgrelid = tbl.tablename::regclass
        ) THEN
            EXECUTE format('DROP TRIGGER %I ON %I', trg_update_name, tbl.tablename);
        END IF;

        -- Cria a trigger de update
        EXECUTE format('
            CREATE TRIGGER %I 
            BEFORE UPDATE ON %I 
            FOR EACH ROW 
            EXECUTE FUNCTION public.prevent_created_at_update();
        ', trg_update_name, tbl.tablename);

        -- Verifica se a trigger de delete já existe e a remove se necessário
        IF EXISTS (
            SELECT 1 
            FROM pg_trigger 
            WHERE tgname = trg_delete_name 
              AND tgrelid = tbl.tablename::regclass
        ) THEN
            EXECUTE format('DROP TRIGGER %I ON %I', trg_delete_name, tbl.tablename);
        END IF;

        -- Cria a trigger de delete
        EXECUTE format('
            CREATE TRIGGER %I 
            BEFORE DELETE ON %I 
            FOR EACH ROW 
            EXECUTE FUNCTION public.prevent_delete();
        ', trg_delete_name, tbl.tablename);

        -- Verifica se a trigger de update em 'deleted_at' já existe e a remove se necessário
        IF EXISTS (
            SELECT 1 
            FROM pg_trigger 
            WHERE tgname = trg_update_deleted_at_name 
              AND tgrelid = tbl.tablename::regclass
        ) THEN
            EXECUTE format('DROP TRIGGER %I ON %I', trg_update_deleted_at_name, tbl.tablename);
        END IF;

        -- Cria a trigger de update em 'deleted_at'
        EXECUTE format('
            CREATE TRIGGER %I 
            BEFORE UPDATE ON %I 
            FOR EACH ROW 
            EXECUTE FUNCTION public.prevent_deleted_at_update();
        ', trg_update_deleted_at_name, tbl.tablename);

    END LOOP;
END $$;