Skip to content

Commit bfa5d64

Browse files
committed
feat: v5.1.0
1 parent 1c574ba commit bfa5d64

File tree

124 files changed

+3014
-3789
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

124 files changed

+3014
-3789
lines changed

.prettierrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"tabWidth": 2,
33
"semi": false,
44
"singleQuote": true,
5-
"printWidth": 118,
5+
"printWidth": 116,
66
"endOfLine": "auto",
77
"trailingComma": "none"
88
}

ARCHITECTURE.md

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
## Architecture of NodePress v4.x
1+
## Architecture of NodePress (>= v4.x)
22

33
### API Overview
44

5-
**HTTP Status Codes** [`errors`](/src/errors)
5+
**HTTP Status Codes**
66

77
- `400` — Request rejected due to business logic
88
- `401` — Authentication failed
@@ -18,9 +18,8 @@
1818
- `status`
1919
- `success` — Successful response
2020
- `error` — Error occurred
21-
- `message` — Always present; injected by [`responser.decorator.ts`](/src/decorators/responser.decorator.ts)
22-
- `error` — Required when `status` is `error`, useful for debugging
23-
- `debug` — Stack trace (only in development mode)
21+
- `message` — Always present; injected by [`success-response.decorator.ts`](/src/decorators/success-response.decorator.ts)
22+
- `error` — Required when `status` is `error`, usually a simple description of the error
2423
- `result` — Required when `status` is `success`
2524
- For entity: e.g. `{ title: '', content: '', ... }`
2625
- For list: e.g. `{ pagination: {...}, data: [...] }`
@@ -60,26 +59,25 @@
6059
**Request Lifecycle**
6160

6261
1. `request` — Incoming HTTP request
63-
2. `middleware` — Preprocessing (CORS, origin checks)
62+
2. `middleware` — Preprocessing (empty in this app)
6463
3. `guard` — Authentication guards
6564
4. `interceptor:before` — Input transformation (empty in this app)
66-
5. `pipe` — Data validation and transformation; attaches payload to context
65+
5. `pipe` — Data validation and transformation
6766
6. `controller` — Request handler logic
6867
7. `service` — Business logic
6968
8. `interceptor:after` — Output formatting and error handling
7069
9. `filter` — Captures and handles thrown exceptions
7170

7271
**Authentication Flow**
7372

74-
1. Guard entry point: [`guards`](/src/guards)
75-
2. `canActivate()` — Entry check
76-
3. `JwtStrategy.validate()` — Calls [`jwt.strategy.ts`](/src/modules/auth/jwt.strategy.ts)
77-
4. `handleRequest()` — Accept or reject based on validation result
73+
1. [`main.ts`](/src/main.ts): Uses Fastify’s `onRequest` to perform authentication and inject auth data into the request
74+
2. Uses [`Guards`](/src/guards) to validate and intercept each controller method
75+
3. `handleRequest()` — Accept or reject based on validation result
7876

7977
**Access Control Levels**
8078

8179
- CUD (write) operations require tokens: [`AdminOnlyGuard`](/src/guards/admin-only.guard.ts)
82-
- GET (read) operations auto-detect token presence: [`AdminMaybeGuard`](/src/guards/admin-maybe.guard.ts)
80+
- GET (read) operations auto-detect token presence: [`AdminOptionalGuard`](/src/guards/admin-optional.guard.ts)
8381

8482
**Validation Rules**
8583

@@ -90,41 +88,34 @@
9088

9189
### Core Components
9290

93-
**Exception Filter** [`error.filter.ts`](/src/filters/error.filter.ts)
91+
[**Exception Filter**](/src/filters/exception.filter.ts)
9492

95-
**Interceptors** [`interceptors`](/src/interceptors)
93+
[**Interceptors**](/src/interceptors)
9694

97-
- [Cache](/src/interceptors/cache.interceptor.ts): Adds TTL support
9895
- [Transformer](/src/interceptors/transform.interceptor.ts): Formats successful service responses
99-
- [Error](/src/interceptors/error.interceptor.ts): Catches service-layer exceptions
10096
- [Logging](/src/interceptors/logging.interceptor.ts): Supplements global logging
10197

102-
**Decorators** [`decorators`](/src/decorators)
98+
[**Decorators**](/src/decorators)
10399

104-
- [Cache](/src/decorators/cache.decorator.ts): Configure cache key/TTL
105-
- [Response](/src/decorators/responsor.decorator.ts): Adds `message`, pagination, etc.
106-
- [QueryParams](/src/decorators/queryparams.decorator.ts): Auto-validate and normalize params
107-
- [Guest](/src/decorators/guest.decorator.ts): Extend sub-fields with metadata for `permission.pipe`
100+
- [RequestContext](/src/decorators/request-context.decorator.ts): Auto-validate and normalize params
101+
- [GuestPermission](/src/decorators/guest-permission.decorator.ts): Extend sub-fields with metadata for `permission.pipe`
102+
- [SuccessResponse](/src/decorators/success-response.decorator.ts): Adds `message`, pagination, etc.
103+
- [UploadedFile](/src/decorators/uploaded-file.decorator.ts): Reads the uploaded file from `request.file` and converts it to buffer
108104

109-
**Guards** [`guards`](/src/guards)
105+
[**Guards**](/src/guards)
110106

111107
- Default: All non-GET requests require [`AdminOnlyGuard`](/src/guards/admin-only.guard.ts)
112-
- Multi-role GET requests use [`AdminMaybeGuard`](/src/guards/admin-maybe.guard.ts)
108+
- Multi-role GET requests use [`AdminOptionalGuard`](/src/guards/admin-optional.guard.ts)
113109

114-
**Middlewares** [`middlewares`](/src/middlewares)
115-
116-
- [`CORS`](/src/middlewares/cors.middleware.ts): Handles cross-origin requests
117-
- [`Origin`](/src/middlewares/origin.middleware.ts): Blocks unknown sources
118-
119-
**Pipes** [`pipes`](/src/pipes)
110+
[**Pipes**](/src/pipes)
120111

121112
- `validation.pipe` — Validates DTO schemas
122113
- `permission.pipe` — Checks field-level permissions
123114

124-
**Feature Modules** [`modules`](/src/modules)
115+
[**Feature Modules**](/src/modules)
125116

126117
- `Announcement`, `Article`, `Category`, `Tag`, `Comment`, `Option`
127-
- `Auth`Global token and user auth
118+
- `Admin`Admin profile and authentication
128119
- `Vote` — Reaction logic (like/dislike)
129120
- `Disqus` — Third-party integration
130121
- `Archive` — Caching layer
@@ -133,16 +124,17 @@
133124
- DB Backup (manual and scheduled)
134125
- Miscellaneous third-party services
135126

136-
**Global/Core Modules** [`processors`](/src/processors)
137-
138-
- [`database`](/src/processors/database) — DB connection and error handling
139-
- [`cache`](/src/processors/cache) — Cache APIs and strategies
140-
- [`helper`](/src/processors/helper):
141-
- [SEO Submission](/src/processors/helper/helper.service.seo.ts)
142-
- [Spam Detection](/src/processors/helper/helper.service.akismet.ts)
143-
- [Email Service](/src/processors/helper/helper.service.email.ts)
144-
- [IP Geolocation](/src/processors/helper/helper.service.ip.ts)
145-
- [AWS S3 Upload](/src/processors/helper/helper.service.aws.ts)
127+
[**Global/Core Modules**](/src/core)
128+
129+
- [`database`](/src/core/database) — DB connection and error handling
130+
- [`cache`](/src/core/cache) — Cache APIs and strategies
131+
- [`auth`](/src/core/auth) — Responsible for global JWT authentication logic
132+
- [`helper`](/src/core/helper):
133+
- [SEO Submission](/src/core/helper/helper.service.seo.ts)
134+
- [Spam Detection](/src/core/helper/helper.service.akismet.ts)
135+
- [Email Service](/src/core/helper/helper.service.email.ts)
136+
- [IP Geolocation](/src/core/helper/helper.service.ip.ts)
137+
- [AWS S3 Upload](/src/core/helper/helper.service.aws.ts)
146138
- Google Service Credentials
147139

148140
---

CHANGELOG.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
### 5.1.0 (2025-07-16)
6+
7+
**Feature**
8+
9+
- Replaced Express with Fastify as the HTTP server
10+
- Renamed `AuthModule` to `AdminModule`
11+
- Refactored the global JWT authentication mechanism
12+
- Refactored decorators
13+
- Removed all legacy middleware (CORS)
14+
- Removed the unused Cache decorator
15+
- Removed unnecessary global constants
16+
517
### 5.0.0 (2025-06-16)
618

719
**Feature**
@@ -323,7 +335,6 @@ All notable changes to this project will be documented in this file.
323335
**Chore**
324336

325337
- Upgrade deps
326-
327338
- `Redis` > v4
328339
- `nest` > v8
329340
- `mongoose` > v6

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,8 @@ $ pnpm run start:dev
4545
# test
4646
$ pnpm run lint
4747
$ pnpm run test
48-
$ pnpm run test:e2e
49-
$ pnpm run test:cov
5048
$ pnpm run test:watch
49+
$ pnpm run test:cov
5150

5251
# build
5352
$ pnpm run build

jest.config.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { pathsToModuleNameMapper } from 'ts-jest'
2+
import { compilerOptions } from './tsconfig.json'
3+
import type { Config } from 'jest'
4+
5+
const config: Config = {
6+
preset: 'ts-jest',
7+
testEnvironment: 'node',
8+
moduleFileExtensions: ['js', 'json', 'ts'],
9+
rootDir: '.',
10+
testMatch: ['<rootDir>/src/**/*.spec.ts'],
11+
coverageDirectory: 'coverage',
12+
transform: {
13+
'^.+\\.(t|j)s$': 'ts-jest'
14+
},
15+
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
16+
prefix: '<rootDir>/'
17+
})
18+
}
19+
20+
export default config

package.json

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nodepress",
3-
"version": "5.0.2",
3+
"version": "5.1.0",
44
"description": "RESTful API service for Surmon.me blog",
55
"author": "Surmon",
66
"license": "MIT",
@@ -20,48 +20,41 @@
2020
"start:dev": "cross-env NODE_ENV=development nest start --watch",
2121
"start:debug": "cross-env NODE_ENV=development nest start --debug --watch",
2222
"start:prod": "cross-env NODE_ENV=production node dist/main",
23-
"test": "cross-env NODE_ENV=test jest",
24-
"test:watch": "cross-env NODE_ENV=test jest --watch",
25-
"test:cov": "cross-env NODE_ENV=test jest --coverage",
26-
"test:debug": "cross-env NODE_ENV=test node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
27-
"test:e2e": "cross-env NODE_ENV=test jest --config ./test/jest-e2e.json",
28-
"doc": "compodoc -p tsconfig.json -n 'NodePress documentation' -d documentation --disableCoverage --hideGenerator --customFavicon branding/favicon.ico",
23+
"test": "jest",
24+
"test:watch": "jest --watch",
25+
"test:cov": "jest --coverage",
26+
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
27+
"doc": "compodoc -p tsconfig.compodoc.json -n 'NodePress documentation' -d documentation --disableCoverage --hideGenerator --customFavicon branding/favicon.ico",
2928
"release": ". ./scripts/release-via-github.sh"
3029
},
3130
"dependencies": {
32-
"@aws-sdk/client-s3": "^3.832.0",
31+
"@aws-sdk/client-s3": "^3.846.x",
32+
"@fastify/cookie": "^11.x",
33+
"@fastify/multipart": "^9.x",
3334
"@nestjs/axios": "^4.0.x",
3435
"@nestjs/common": "^11.1.x",
3536
"@nestjs/core": "^11.1.x",
3637
"@nestjs/jwt": "^11.x",
3738
"@nestjs/mapped-types": "^2.1.x",
38-
"@nestjs/passport": "^11.x",
39-
"@nestjs/platform-express": "^11.x",
39+
"@nestjs/platform-fastify": "^11.x",
4040
"@nestjs/throttler": "^6.4.x",
4141
"@redis/client": "^5.x",
4242
"@typegoose/auto-increment": "^4.13.x",
4343
"@typegoose/typegoose": "^12.17.x",
4444
"akismet-api": "^6.x",
4545
"axios": "^1.10.x",
46-
"body-parser": "^2.2.x",
4746
"class-transformer": "^0.5.1",
4847
"class-validator": "^0.14.x",
49-
"compression": "^1.8.x",
50-
"cookie-parser": "^1.4.x",
5148
"cross-env": "^7.x",
5249
"dayjs": "^1.11.x",
53-
"express": "^5.1.x",
5450
"fast-xml-parser": "^5.2.x",
55-
"googleapis": "^150.x",
56-
"helmet": "^8.x",
51+
"googleapis": "^153.x",
5752
"js-base64": "^3.7.x",
5853
"jsonwebtoken": "^9.0.x",
59-
"lodash": "^4.17.x",
54+
"lodash": "^4.x",
6055
"mongoose": "~8.16.0",
6156
"node-schedule": "^2.1.x",
6257
"nodemailer": "^7.x",
63-
"passport": "~0.7.0",
64-
"passport-jwt": "^4.0.1",
6558
"picocolors": "^1.x",
6659
"reflect-metadata": "^0.2.2",
6760
"rimraf": "^6.x",
@@ -76,27 +69,22 @@
7669
"@nestjs/cli": "^11.0.x",
7770
"@nestjs/schematics": "^11.x",
7871
"@nestjs/testing": "^11.x",
79-
"@types/body-parser": "^1.19.x",
80-
"@types/cookie-parser": "^1.4.x",
81-
"@types/express": "^5.x",
8272
"@types/jest": "30.x",
83-
"@types/jsonwebtoken": "^9.0.x",
73+
"@types/jsonwebtoken": "^9.x",
8474
"@types/lodash": "^4.17.x",
85-
"@types/multer": "^1.4.x",
8675
"@types/node": "^22.x",
8776
"@types/node-schedule": "^2.x",
8877
"@types/nodemailer": "^6.x",
89-
"@types/passport": "~1.0.17",
90-
"@types/passport-jwt": "^4.0.1",
9178
"@types/shelljs": "^0.8.x",
9279
"@types/supertest": "^6.x",
9380
"@types/validator": "^13.15.x",
9481
"eslint": "^9.x",
9582
"eslint-config-prettier": "^10.x",
9683
"eslint-plugin-prettier": "^5.x",
84+
"fastify": "5.4.0",
9785
"globals": "^16.x",
9886
"jest": "^30.x",
99-
"prettier": "^3.5.x",
87+
"prettier": "^3.6.x",
10088
"supertest": "^7.x",
10189
"ts-jest": "^29.x",
10290
"ts-loader": "^9.5.x",
@@ -107,19 +95,5 @@
10795
},
10896
"engines": {
10997
"node": ">=22"
110-
},
111-
"jest": {
112-
"moduleFileExtensions": [
113-
"js",
114-
"json",
115-
"ts"
116-
],
117-
"rootDir": "src",
118-
"testRegex": ".spec.ts$",
119-
"transform": {
120-
"^.+\\.(t|j)s$": "ts-jest"
121-
},
122-
"coverageDirectory": "../coverage",
123-
"testEnvironment": "node"
12498
}
12599
}

0 commit comments

Comments
 (0)