Skip to content
linecodesxxPublic

About

Backend-as-Code generator

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

ForgerAPI

Декларативный язык схем → NestJS кодогенератор

ForgerAPI превращает описание API на DSL schema.forger в готовый NestJS код: Prisma схему, DTO, CRUD-сервисы, контроллеры, guards и модули. Без рантайма — только компиляция.

model User {
  id: uuid @id @default(uuid)
  email: string @unique
  name: string
  role: Role
  posts: Post[]
}

module Auth {
  route: "/auth"
  models: User
  guards: AuthGuard

  action Login {
    route: "/login"
    method: POST
    input: [email: string, password: string]
    steps: validateUser signToken
  }
}

Содержание


Как это работает

Пайплайн

schema.forger файл
    │
    ▼
┌─────────────┐
│   Lexer     │  ← разбивает текст на токены
└──────┬──────┘
       │
       ▼
┌─────────────┐
│   Parser    │  ← строит AST (ForgerSchema)
└──────┬──────┘
       │
       ▼
┌──────────────────┐
│ Semantic Analyzer│  ← проверяет типы, связи, дубликаты
└──────┬───────────┘
       │
       ▼
┌─────────────┐
│   Codegen   │  ← генерирует файлы в src/ и prisma/
└─────────────┘

1. Lexer (@forgerapi/parser)

Принимает сырой текст schema.forger, возвращает массив Token[].

Токен Пример Описание
keyword model, enum, action, module, guard Ключевые слова языка
type string, uuid, boolean Примитивные типы
identifier User, email, Role Имена сущностей и полей
symbol {, }, :, (, ), [, ] Символы пунктуации
annotation @id, @unique, @default(uuid) Аннотации полей
string "/auth", "@nestjs/passport" Строковые литералы
eof — Конец файла

2. Parser (@forgerapi/parser)

Рекурсивный спуск. Принимает Token[], возвращает ForgerSchema.

Функция Описание
parseSchema() Корневая — парсит enums → models → guards → actions → modules
parseEnum() enum Name { VAL1 VAL2 }
parseModel() model Name { fields }
parseField() name: type @constraints
parseFieldType() Определяет тип поля + связь
parseConstraints() Парсит @id, @unique, @default(value)
parseRelationField() Парсит @relation(fieldName)
parseAction() action Name { route/method/input/steps/emits }
parseGuard() guard Name { import: "..." }
parseModule() module Name { route/models/guards/actions }

3. Semantic Analyzer (@forgerapi/parser)

Проходит по AST после парсинга. Проверяет:

Проверка Ошибка
Дубликаты имён моделей Duplicate model name: User
Дубликаты имён enum Duplicate enum name: Role
Дубликаты значений enum Duplicate value ADMIN in enum Role
Пустой enum Enum Role has no values
Relation target не найден Model Post: relation target 'User' not found
Relation field не найден Model Post: relation field 'authorId' not found
@id не на uuid поле @id field 'id' must be uuid type
Guard без import Guard X has no import
Модель в module не найдена Module X: model 'Y' not found

4. Codegen (@forgerapi/codegen)

Принимает ForgerSchema + ForgerConfig, создаёт файлы на диске.

Генератор Создаёт
prisma.ts schema.prisma целиком
dto.ts Create/Update/Response DTO с @ApiProperty
service.ts CRUD-сервис
controller.ts REST контроллер + Swagger
module.ts NestJS Module
enum.ts TS enum

5. CLI (@forgerapi/cli)

forger generate    # парсит schema.forger → генерирует NestJS код
forger watch       # вотчер с авто-генерацией
forger help        # справка

Установка

npm install -g @forgerapi/cli

Из монорепозитория:

npm run build
npx forger generate

Язык Forger DSL

Конструкции

Enum

enum Role {
  USER
  ADMIN
  MODERATOR
}

Model

model User {
  id: uuid @id @default(uuid)
  email: string @unique
  name: string
  role: Role
  posts: Post[]
}

Field

<name>: <type> [@constraints] [@relation(field)]
Тип TS Prisma
string string String
number number Int
boolean boolean Boolean
uuid string String + @default(uuid())
datetime Date DateTime

Аннотации:

  • @id — первичный ключ (только на uuid)
  • @unique — уникальный индекс
  • @default(uuid | now | true | false) — значение по умолчанию

Связи:

  • Role — ссылка на enum/model
  • Post[] — hasMany связь
  • author: User @relation(authorId) — belongsTo с явным FK

Action

action CreatePost {
  route: "/posts"
  method: POST
  input: [title: string, content: string, authorId: uuid]
  guards: AuthGuard
  steps: validateInput saveToDb
  emits: PostCreated
}
Ключ Описание
route HTTP путь
method GET / POST / PUT / PATCH / DELETE
input Типизированные параметры [name: type, ...]
guards Список guards
steps Имена шагов-методов
emits События, которые порождает action

Guard

guard AuthGuard { import: "@nestjs/passport" }

Module

Группирует модели, guards и actions под общим HTTP префиксом.

module Blog {
  route: "/blog"
  models: User Post
  guards: AuthGuard

  action ListPosts {
    route: "/"
    method: GET
    steps: queryPosts
  }

  action CreatePost {
    route: "/"
    method: POST
    input: [title: string, content: string]
    steps: validate save
  }
}

Конфигурация

forger.config.json:

{
  "outDir": "./src",
  "prismaSchema": "./prisma/schema.prisma",
  "prisma": true,
  "swagger": true,
  "deleteOrphans": true
}
Поле По умолчанию Описание
outDir ./src Куда генерировать NestJS код
prismaSchema ./prisma/schema.prisma Путь к Prisma схеме
prisma true Генерировать Prisma schema, PrismaModule/Service и Prisma-реализации
swagger true Добавлять @ApiTags, @ApiOperation, @ApiProperty
deleteOrphans true Удалять папки模型, которых нет в schema.forger

Если forger.config.json нет — используются значения по умолчанию.

Например, чтобы сгенерировать проект без Prisma и Swagger:

{
  "prisma": false,
  "swagger": false
}

При prisma: false вместо Prisma-реализаций создаются одноразовые заглушки с NotImplementedException, которые можно заменить своей реализацией хранилища.


Что генерируется

Для каждой модели (model Post)

src/{model}/
  dto/
    create-{model}.dto.ts
    update-{model}.dto.ts
    {model}-response.dto.ts
  {model}.service.ts         ← abstract CRUD service
  {model}.controller.ts      ← CRUD controller + Swagger
  {model}.module.ts          ← NestJS Module
  impl/
    {model}.impl.ts          ← Prisma implementation (создаётся 1 раз)

Для каждого standalone action (action Login)

src/{action}/
  {action}.action-dto.ts
  {action}.action-service.ts    ← abstract service с execute()
  {action}.action-controller.ts ← POST endpoint
  {action}.action-module.ts
  {action}.action-event.ts      ← на каждый emits (создаётся 1 раз)
  impl/
    {action}.action-impl.ts     ← stub шагов (создаётся 1 раз)

Для каждого module с вложенными actions

src/{module}/
  {module}.module.ts
  actions/{action}/
    {action}.action-dto.ts
    {action}.action-service.ts
    {action}.action-controller.ts
  impl/{action}.action-impl.ts
  events/{action}.action-event.ts

Общие файлы

src/common/
  enums/{name}.enum.ts          ← TS enum
  prisma/prisma.service.ts      ← PrismaClient wrapper
  prisma/prisma.module.ts       ← Global Prisma module
  guards/{name}.guard.ts        ← guard stub (только если нет import)
src/forger-modules.module.ts    ← агрегатор всех модулей
prisma/schema.prisma            ← полная Prisma схема

Пакеты

packages/
  ast/          @forgerapi/ast      — AST типы (интерфейсы)
  parser/       @forgerapi/parser   — лексер + парсер + анализатор
  codegen/      @forgerapi/codegen  — генераторы NestJS-кода
  cli/          @forgerapi/cli      — CLI точка входа
Пакет npm
@forgerapi/ast npm
@forgerapi/parser npm
@forgerapi/codegen npm
@forgerapi/cli npm

Roadmap

v0.1:

  • DSL парсер (model, enum, field)
  • AST генерация

v0.2:

  • Constraints (@id, @unique, @default)
  • Relations
  • Semantic analyzer
  • NestJS codegen (DTO, Service, Controller, Module, Enum, Prisma)
  • Swagger декораторы
  • Guard declaration
  • Module declaration with nested actions

v0.3 (planned):

  • Action codegen (endpoints из action-деклараций)
  • Watch mode
  • Плагины (кастомные генераторы)
  • CLI polish

v1.0 (goal):

  • Language Server Protocol
  • VS Code extension
  • Full schema validation

Философия

Forger описывает только что есть данные и какие операции над ними. Всё остальное — бизнес-логика, guards, pipes, middleware — остаётся в TypeScript.

Никакого рантайма. ForgerAPI — это компилятор. Он прочитал schema.forger, сгенерировал код, закончил работу. В продакшне никаких зависимостей от ForgerAPI.

Разработчик описывает API  →  Система генерирует код
   (schema.forger файл)          (NestJS + Prisma)

About

Backend-as-Code generator

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages