Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 0 additions & 24 deletions .eslintrc.js

This file was deleted.

42 changes: 42 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: CI

on:
push:
branches: [master]
pull_request:
branches: [master]

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
verify:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [20, 22]

steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: pnpm

- run: pnpm install --frozen-lockfile

- name: Lint
run: pnpm run lint

- name: Type-check
run: pnpm run typecheck

# Unit tests only: the e2e suite needs a reachable PostgreSQL instance.
- name: Test
run: pnpm run test

- name: Build
run: pnpm run build
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ lerna-debug.log*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/extensions.json
/coverage
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dist
node_modules
coverage
pnpm-lock.yaml
6 changes: 6 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"printWidth": 100,
"singleQuote": true,
"trailingComma": "all",
"arrowParens": "always"
}
47 changes: 47 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Changelog

## Unreleased

### Fixed

- **None of the npm scripts ran.** Every one of them starts with `cross-env`,
which was never in `devDependencies`.
- **Three more dependencies were used but never declared**: `lodash` (15 call
sites), `body-parser` and `jsonwebtoken`. They resolved through hoisting under
npm/yarn and fail under pnpm. `lodash` is now declared; `body-parser` is
replaced by Express's own `json()` / `urlencoded()`; the `jsonwebtoken` import
only provided a type and is gone.
- **`CatsService` swallowed errors and returned them as data.** Both methods
ended in `catch (err) { return err; }`, so a failed query reached the client
as a 200 with an `Error` object in the body. Errors now propagate, and there
are tests for it.
- **`CatEntity` was missing the columns the API accepts.** The endpoint takes
`age` and `breed`, but the entity declared only `id` and `name`, so TypeORM
silently dropped both on write.
- The e2e spec used `import * as request from 'supertest'`, which is not
callable with `esModuleInterop` on.

### Changed

- **Nest 7 → 12**, and with it: `HttpModule` / `HttpService` moved from
`@nestjs/common` to `@nestjs/axios`.
- **TypeORM 0.2 → 0.3**: `createConnection` → `DataSource`, `ConnectionOptions`
→ `DataSourceOptions`, and `findOne()` now requires explicit `where` options.
- Remaining dependencies to current: pg 8.23, helmet 4 → 8, express-rate-limit
5 → 8, class-validator 0.13 → 0.15, nodemailer 6 → 10, TypeScript 4.2 → 5.9.
- **Jest → Vitest.** `@nestjs/testing` 12 is ESM-only, and Jest 30 cannot
`require()` ESM before Node 24.9. Vitest runs the suite through SWC, which —
unlike esbuild — implements `emitDecoratorMetadata`, so Nest's DI works.
- `@nestjs/cli` is pinned to 11: the 12 line pulls in an ESM-only `ora` through
`@angular-devkit/schematics`, which crashes on Node 22 with
`ERR_REQUIRE_CYCLE_MODULE`.
- The project uses pnpm.

### Added

- ESLint 9 flat config with typescript-eslint, replacing ESLint 7. 0 errors.
- Real tests for the Cats module: 9 tests covering both the service and the
controller with the repository mocked, where the previous specs were Nest CLI
stubs that could not resolve their own dependencies.
- `README_EN.md`, `CONTRIBUTING.md` and this changelog.
- `ci.yml`: lint, typecheck, test and build on Node 20 and 22.
178 changes: 178 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# Contributing · 贡献指南

English | [中文](#中文)

Thanks for taking the time to contribute. Issues and pull requests are both welcome.

## "I don't have permission to push"

You don't need it, and you shouldn't ask for it. **Nobody outside the project can push a branch to
this repository** — that is how GitHub works for every public repo, not a restriction set up here.
The way to contribute a change is to push to _your own_ fork and open a pull request from it:

```bash
# 1. Fork the repo on GitHub (the "Fork" button, top right)

# 2. Clone YOUR fork, not this one
git clone https://github.com/<your-username>/Nest-Postgre-API.git
cd Nest-Postgre-API

# 3. Point "upstream" at this repo so you can stay in sync
git remote add upstream https://github.com/ludejun/Nest-Postgre-API.git

# 4. Branch, commit, push to your fork
git checkout -b fix/some-bug
git commit -am "fix: describe what changed"
git push origin fix/some-bug

# 5. Open the pull request from your fork's branch against ludejun/master
```

Or do the whole thing with the [GitHub CLI](https://cli.github.com/):

```bash
gh repo fork ludejun/Nest-Postgre-API --clone
cd Nest-Postgre-API
git checkout -b fix/some-bug
# ...edit, commit...
gh pr create --repo ludejun/Nest-Postgre-API
```

A couple of things that can look like a permission problem but aren't:

- **The checks on your PR sit there greyed out.** For a first-time contributor, GitHub Actions waits
for a maintainer to click "Approve and run". Nothing is wrong; it just needs a maintainer to look.
- **`git push` to `ludejun/…` returns 403.** Expected — see above. Push to your fork's remote.

## Development setup

This project uses [pnpm](https://pnpm.io/) and needs Node >= 20. The e2e suite also needs a
reachable PostgreSQL instance; the unit tests do not.

```bash
pnpm install
pnpm start:dev # development, watch mode
```

## Before you open the pull request

Please make sure all four pass — CI runs exactly these:

```bash
pnpm lint # eslint, must report 0 errors
pnpm typecheck # tsc --noEmit
pnpm test # vitest
pnpm build # compile to dist/
```

If you changed behaviour, add or update a test in `tests/`. If you fixed a bug, a test that fails
without your fix is the most useful thing you can include.

Run `pnpm format` before committing so Prettier settles the formatting; CI does not reformat for you.

## A few conventions

- **Commit messages** follow [Conventional Commits](https://www.conventionalcommits.org/):
`fix:`, `feat:`, `docs:`, `chore:`, `refactor:`, `test:`.
- **Both READMEs.** If a change affects the documented API, update `README.md` _and_ `README_EN.md`.
- **Declare what you import.** Four packages were imported without ever appearing in
`package.json`; they only resolved through hoisting. pnpm's layout catches this, so do not work
around a missing module by reaching for a hoisted copy.
- **Do not swallow errors.** `catch (err) { return err }` sends an `Error` object to the client as a
200 response. Let errors reach the filters, which turn them into the documented shape.
- **Keep entities and DTOs in step.** A column missing from the entity is silently dropped on write.

## Reporting a bug

Open an [issue](https://github.com/ludejun/Nest-Postgre-API/issues) with:

- the Node and PostgreSQL versions,
- the endpoint and the request you sent,
- what you expected and what happened instead,
- the response you got, and the server log if there is one.

---

<a id="中文"></a>

# 中文

感谢你愿意花时间参与。Issue 和 Pull Request 都非常欢迎。

## “我没有权限提交代码”

你不需要这个权限,也不用来要。**项目之外的任何人都无法直接往本仓库推送分支** —— 这是 GitHub 对所有公开仓库的默认行为,不是本项目做了什么限制。正确的做法是推到**你自己的 fork**,再从 fork 发起 Pull Request:

```bash
# 1. 在 GitHub 页面右上角点 "Fork"

# 2. clone 你自己的 fork,不是这个仓库
git clone https://github.com/<你的用户名>/Nest-Postgre-API.git
cd Nest-Postgre-API

# 3. 把 upstream 指向本仓库,方便后续同步
git remote add upstream https://github.com/ludejun/Nest-Postgre-API.git

# 4. 建分支、提交、推到你自己的 fork
git checkout -b fix/some-bug
git commit -am "fix: 描述你改了什么"
git push origin fix/some-bug

# 5. 从你 fork 的这个分支,向 ludejun/master 发起 Pull Request
```

也可以用 [GitHub CLI](https://cli.github.com/) 一条龙:

```bash
gh repo fork ludejun/Nest-Postgre-API --clone
cd Nest-Postgre-API
git checkout -b fix/some-bug
# ...改代码、提交...
gh pr create --repo ludejun/Nest-Postgre-API
```

有两种情况看着像“没权限”,其实不是:

- **PR 上的 CI 检查一直灰着不跑。** 首次贡献者的 workflow 需要维护者点一下 “Approve and run”,这是 GitHub 的默认策略,等一下即可。
- **`git push` 到 `ludejun/…` 返回 403。** 这是预期行为,推到你自己 fork 的 remote 就好。

## 本地开发

本项目使用 [pnpm](https://pnpm.io/),需要 Node >= 20。e2e 测试还需要一个可连接的 PostgreSQL;单元测试不需要。

```bash
pnpm install
pnpm start:dev # 开发环境,watch 模式
```

## 提 PR 之前

请确认这四条全部通过 —— CI 跑的就是这四条:

```bash
pnpm lint # eslint,必须 0 error
pnpm typecheck # tsc --noEmit
pnpm test # vitest
pnpm build # 编译到 dist/
```

如果你改了行为,请在 `tests/` 下补充或更新测试。如果你修的是 bug,**一个不打补丁就会失败的测试**是最有价值的东西。

提交前跑一下 `pnpm format` 让 Prettier 统一格式,CI 不会替你格式化。

## 一些约定

- **提交信息**遵循 [Conventional Commits](https://www.conventionalcommits.org/):`fix:`、`feat:`、`docs:`、`chore:`、`refactor:`、`test:`。
- **两份 README。** 如果改动影响了对外 API,请同时更新 `README.md` 和 `README_EN.md`。
- **用了什么就声明什么。** 之前有四个包被 import 却从没出现在 `package.json` 里,靠依赖提升侥幸能跑。pnpm 的严格目录结构能抓到这类问题,请不要绕过去用提升出来的副本。
- **不要吞掉错误。** `catch (err) { return err }` 会把 `Error` 对象当成 200 响应发给客户端。让错误抛到 filter,由它转成文档里定义的结构。
- **entity 要和 DTO 保持一致。** entity 上缺的列,写入时会被静默丢弃。

## 反馈 Bug

到 [Issues](https://github.com/ludejun/Nest-Postgre-API/issues) 提一条,请带上:

- Node 和 PostgreSQL 版本,
- 请求的是哪个接口、发了什么,
- 你期望的行为,以及实际发生了什么,
- 拿到的响应,以及服务端日志(如果有)。
66 changes: 59 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,58 @@
## Nest-Postgre-API
<h1 align="center">Nest-Postgre-API</h1>

*Nest + Postgre + JWT + TypeORM* 基于Nest和传统数据库Postgre的Node Restful API脚手架,适用于基础生产项目
<p align="center">
面向生产的 Node REST API 脚手架:Nest + PostgreSQL + TypeORM + JWT。
</p>

参考https://github.com/surmon-china/nodepress
<p align="center">
<img src="https://img.shields.io/badge/nest-12-e0234e?logo=nestjs&logoColor=white" alt="nest 12" />
<img src="https://img.shields.io/badge/typeorm-0.3-fe0902" alt="typeorm 0.3" />
<img src="https://img.shields.io/badge/postgres-8-4169e1?logo=postgresql&logoColor=white" alt="postgres" />
<img src="https://img.shields.io/badge/typescript-5.9-3178c6?logo=typescript&logoColor=white" alt="typescript 5.9" />
<img src="https://img.shields.io/badge/pnpm-10-f69220?logo=pnpm&logoColor=white" alt="pnpm 10" />
<br />
<a href="https://github.com/ludejun/Nest-Postgre-API/actions/workflows/ci.yml"><img src="https://github.com/ludejun/Nest-Postgre-API/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
<a href="https://github.com/ludejun/Nest-Postgre-API/blob/master/CONTRIBUTING.md"><img src="https://img.shields.io/badge/PR-欢迎提交-brightgreen.svg" alt="欢迎 PR" /></a>
</p>

刚开始不习惯TypeORM,想使用传统sql来请求数据库,后面使用TypeORM也还习惯,原生兼容Nest、代码entity可以和数据库打通、API也还简单
查询参考:https://typeorm.biunav.com/zh/find-options.html#%E5%9F%BA%E7%A1%80%E9%80%89%E9%A1%B9
<p align="center">
<a href="./CHANGELOG.md">更新日志</a>
·
<a href="./CONTRIBUTING.md">贡献指南</a>
·
<a href="./README_EN.md">English</a>
</p>

服务器端口及数据库配置、Auth配置等详见ap.config.ts
### 接口概述
---

_Nest + PostgreSQL + JWT + TypeORM_ —— 基于 Nest 和传统数据库 PostgreSQL 的 Node RESTful API 脚手架,适用于基础生产项目。

参考 https://github.com/surmon-china/nodepress

刚开始不习惯 TypeORM,想使用传统 SQL 来请求数据库,后面使用 TypeORM 也还习惯:原生兼容 Nest、entity 可以和数据库打通、API 也还简单。查询参考 https://typeorm.biunav.com/zh/find-options.html

服务器端口及数据库配置、Auth 配置等详见 `src/app.config.ts`。

## 环境要求

Node >= 20,PostgreSQL,以及 [pnpm](https://pnpm.io/)。

## 命令

```shell
pnpm install
pnpm start:dev # 开发环境,watch 模式
pnpm build # 编译到 dist/
pnpm start:prod # 运行编译产物

pnpm lint # eslint
pnpm typecheck # tsc --noEmit
pnpm test # vitest(单元测试)
pnpm test:e2e # vitest(e2e,需要可用的数据库)
pnpm format # prettier --write
```

## 接口概述

- HTTP 状态码(详见 [errors] )

Expand Down Expand Up @@ -171,3 +215,11 @@ $ yarn update-geo-db
```

打开http://localhost:8000 即可看到数据返回

## 参与贡献

见 [CONTRIBUTING.md](./CONTRIBUTING.md)。

## 开源协议

[MIT](./LICENSE)
Loading
Loading