{"id":21147603,"url":"https://github.com/drinkjs/ngulf","last_synced_at":"2026-04-18T13:33:52.387Z","repository":{"id":54469951,"uuid":"486571123","full_name":"drinkjs/ngulf","owner":"drinkjs","description":"Based on the Fastify webframework. Integrate typeorm, ioredis, and zod","archived":false,"fork":false,"pushed_at":"2024-03-14T14:15:06.000Z","size":824,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-15T20:58:50.942Z","etag":null,"topics":["class-validator","fastify","ioredis","mongoose","typegoose","typeorm","webframework","zod"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/drinkjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-28T11:45:39.000Z","updated_at":"2023-09-11T03:01:43.000Z","dependencies_parsed_at":"2023-10-11T18:00:59.643Z","dependency_job_id":"be6cd4df-1526-4be0-9cc1-7dd4ccada5e5","html_url":"https://github.com/drinkjs/ngulf","commit_stats":{"total_commits":37,"total_committers":3,"mean_commits":"12.333333333333334","dds":0.2702702702702703,"last_synced_commit":"856fac95cae366c05bc429ecd16d6308fc42038c"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/drinkjs/ngulf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drinkjs%2Fngulf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drinkjs%2Fngulf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drinkjs%2Fngulf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drinkjs%2Fngulf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/drinkjs","download_url":"https://codeload.github.com/drinkjs/ngulf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drinkjs%2Fngulf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31971488,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"online","status_checked_at":"2026-04-18T02:00:07.018Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["class-validator","fastify","ioredis","mongoose","typegoose","typeorm","webframework","zod"],"created_at":"2024-11-20T09:17:34.992Z","updated_at":"2026-04-18T13:33:52.362Z","avatar_url":"https://github.com/drinkjs.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ngulf\nBased on the Fastify webframework. Integrate typeorm, ioredis, and class-validator\n\n## Quick Start\n\n```js\nnpx ngulf init\n```\n\n## Controller\n\n``` js\n// src/controller/DemoController.ts\nimport {Controller} from \"ngulf\";\n\n@Controller(\"/demo\")\nexport default class DemoController {\n\n  @Get(\"/hello\")\n  async hello() {\n    return \"hello ngulf\";\n  }\n}\n```\n## Listen\n``` js\n// src/app.ts\nimport Ngulf from \"ngulf\";\nimport * as path from \"path\"\n\nconst app = Ngulf.create({\n  routePrefix: \"/api\",\n  controllers: path.join(__dirname, \"controller\"),\n});\napp.listen({ port: 3737 }).then(() =\u003e {\n  console.log(\"Ngulf listen on 3737\");\n});\n```\n \n``` Request http://localhost:3737/api/demo/hello ```\n\n## Params\n``` js\n// src/controller/DemoController.ts\nimport {Controller} from \"ngulf\";\n\n@Controller(\"/demo\")\nexport default class DemoController {\n\n  @Get(\"/hello\")\n  async hello() {\n    return \"hello ngulf\";\n  }\n\n  @Get(\"/query\")\n  async query(@Query(\"name\") name: string) {\n    return `hello ${name}`;\n  }\n\n  @Post(\"/body\")\n  async body(@Body() data:any) {\n    console.log(data)\n    return data\n  }\n\n  @Post(\"/header\")\n  async header(@Headers(\"user-agent\") userAgent?:string) {\n    return userAgent\n  }\n}\n```\n\n## Zod\n```js\nimport { z } from \"zod\";\n\nexport const ZodUser = z.object({\n  username: z.string(),\n  password: z\n    .string({ required_error: \"password is Required\" })\n    .nonempty(\"password is empty\"),\n  email: z.string().email().nullish(),\n});\n\nexport type AddZodUser = z.infer\u003ctypeof ZodUser\u003e;\n\n```\nController\n```js\n@Post(\"/api\")\n  async testZod(@Body(ZodUser) data: AddZodUser) {\n    console.log(data);\n    return data;\n  }\n```\n\n## Validator\n\n``` js\n// src/dto/UserDto.ts\nimport { IsNotEmpty } from \"ngulf/class-validator\";\n\nexport default class UserDto {\n  id?:string\n\n  @IsNotEmpty({ groups: [\"login\", \"add\"] })\n  name!: string;\n\n  @IsNotEmpty({ groups: [\"login\"] })\n  password!: string;\n}\n\n```\nController\n``` js\n// src/controller/DemoController.ts\nimport {Controller} from \"ngulf\";\n\n@Controller(\"/demo\")\nexport default class DemoController {\n\n  @Post(\"/login\")\n  async login(@Body(new Validation({ groups: [\"login\"] })) dto: UserDto){\n    if(dto.name === \"admin\" \u0026\u0026 dto.password === \"123456\"){\n      return true;\n    }\n    return false\n  }\n\n  @Post(\"/add\")\n  async add(@Body(new Validation({ groups: [\"add\"] })) dto: UserDto){\n    // add user...\n    return true\n  }\n}\n```\n\n## ORM\nAdd configuration\n``` js\n// src/app.ts\nimport Ngulf from \"ngulf\";\nimport * as path from \"path\"\n\nconst app = Ngulf.create({\n  routePrefix: \"/api\",\n  controllers: path.join(__dirname, \"controller\"),\n  orm: {\n      type: \"mysql\",\n      port: 3306,\n      host: \"localhost\",\n      username: \"root\",\n      password: \"\",\n      database: \"test\",\n      entityPrefix: \"ng_\",\n      entities: [path.join(__dirname, \"entity/*{.ts,.js}\")],\n      // The production environment must be false, otherwise data may be lost\n      synchronize: true, \n    },\n});\napp.listen({ port: 3737 }).then(() =\u003e {\n  console.log(\"Ngulf listen on 3737\");\n});\n```\nCreate entity\n``` js\n// src/entity/UserEntity.ts\nimport {\n  Entity,\n  Column,\n  PrimaryGeneratedColumn,\n} from \"ngulf/typeorm\";\n\n@Entity({ name: \"user\" })\nexport default class UserEntity {\n  @PrimaryGeneratedColumn(\"uuid\")\n  id!: string;\n\n  @Column()\n  name!: string;\n\n  @Column()\n  password!: string;\n}\n```\nCreate servcie\n``` js\n// src/service/UserService.ts\nimport { Injectable, OrmModel, OrmModelType } from \"ngulf\";\nimport UserEntity from \"../entity/UserEntity\";\n\n@Injectable()\nexport default class UserService {\n  @OrmModel(UserEntity)\n  private model!: OrmModelType\u003cUserEntity\u003e;\n\n  async login(name: string, password:string) {\n    return await this.model.findOneBy({ name, password });\n  }\n\n  async add(name: string, password?:string) {\n    const data = this.model.create();\n    data.name = name;\n    data.password = password || \"123456\";\n    return await this.model.save(data);\n  }\n}\n```\nUse servcie\n\n```js\n// src/controller/DemoController.ts\nimport {Controller} from \"ngulf\";\n\n@Controller(\"/demo\")\nexport default class DemoController {\n\n  constructor(private readonly service: UserService){}\n\n  @Post(\"/login\")\n  async login(@Body(new Validation({ groups: [\"login\"] })) dto: UserDto){\n    const rel = await this.service.login(dto.name, dto.password!)\n    return rel ? \"Login success\" : \"Login fail\"\n  }\n\n  @Post(\"/add\")\n  async add(@Body(new Validation({ groups: [\"add\"] })) dto: UserDto){\n    return this.service.add(dto.name, dto.password)\n  }\n}\n```\n\n## Demo\n\n[https://github.com/drinkjs/ngulf-demo](https://github.com/drinkjs/ngulf-demo)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrinkjs%2Fngulf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrinkjs%2Fngulf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrinkjs%2Fngulf/lists"}