topbit 3.0.5 → 3.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/demo/upserv.js ADDED
@@ -0,0 +1,35 @@
1
+ 'use strict'
2
+
3
+ process.chdir(__dirname)
4
+
5
+ const fs = require('node:fs')
6
+ const Topbit = require('../src/topbit.js')
7
+
8
+ let app = new Topbit({
9
+ debug: true,
10
+ globalLog: true
11
+ })
12
+
13
+ let {ToFile,Timing} = Topbit.extensions
14
+
15
+ app.pre(new Timing({test: true}))
16
+
17
+ app.use(new ToFile, {group: 'upload'})
18
+
19
+ let fsp = fs.promises
20
+
21
+ fsp.access('./tmp').catch(err => {
22
+ fsp.mkdir('tmp')
23
+ })
24
+
25
+ app.post('/file', async ctx => {
26
+
27
+ let f = ctx.getFile('file')
28
+
29
+ if (!f) return ctx.status(400).oo('file not found')
30
+
31
+ ctx.to( await f.toFile('tmp') )
32
+
33
+ }, {group: 'upload'})
34
+
35
+ app.run(1234)
package/docs/README.md ADDED
@@ -0,0 +1,16 @@
1
+ # Extensions Document
2
+
3
+ ## 中文版
4
+
5
+ [TopbitLoader](./topbit-loader.md)
6
+
7
+ [TopbitToken](./topbit-token.md)
8
+
9
+
10
+ ---
11
+
12
+ ## English Document
13
+
14
+ [TopbitLoader](./en/topbit-loader.md)
15
+
16
+ [TopbitToken](./en/topbit-token.md)
@@ -0,0 +1,305 @@
1
+ # 🤖 TopbitLoader Complete User Manual
2
+
3
+ ---
4
+
5
+ ### 1. What is TopbitLoader?
6
+
7
+ TopbitLoader is the official recommended auto-loading extension for the Topbit framework. It completely eliminates the need to manually write `app.get()`, `app.post()`, `app.use()`, etc.
8
+
9
+ It implements a true MCM pattern (Middleware → Controller → Model) — lightweight, ultra-fast, and perfectly aligned with Topbit’s extreme-performance philosophy.
10
+
11
+ **One sentence summary:**
12
+ > Write your project following the conventional directory structure, then just call `new Loader().init(app)` once — all routes, middlewares, and models are automatically loaded.
13
+
14
+ ---
15
+
16
+ ### 2. Recommended Project Structure
17
+
18
+ ```
19
+ project/
20
+ ├── app.js # Entry file (full example below)
21
+ ├── controller/ # Controllers (required)
22
+ │ ├── __mid.js # Global middleware list (optional)
23
+ │ ├── user.js # → /user group
24
+ │ ├── admin/ # Sub-group
25
+ │ │ ├── __mid.js # Middleware only for admin group
26
+ │ │ └── index.js # → /admin
27
+ │ └── api/
28
+ │ ├── __mid.js
29
+ │ └── v1/
30
+ │ └── post.js # → /api/v1/post
31
+ ├── middleware/ # Class-style middlewares (required)
32
+ │ ├── @auth.js # Must start with @
33
+ │ ├── @cors.js
34
+ │ └── rate-limit.js # Plain function middleware (less common)
35
+ └── model/ # Models (optional)
36
+ └── user.js
37
+ ```
38
+
39
+ ---
40
+
41
+ ### 3. 30-Second Quick Start
42
+
43
+ ```js
44
+ // app.js
45
+ 'use strict'
46
+ process.chdir(__dirname)
47
+
48
+ const Topbit = require('topbit')
49
+ const { Loader } = Topbit
50
+
51
+ const app = new Topbit({
52
+ debug: true,
53
+ http2: true,
54
+ allowHTTP1: true,
55
+ cert: './cert/fullchain.pem',
56
+ key: './cert/privkey.pem'
57
+ })
58
+
59
+ if (app.isWorker) {
60
+ // One line only – everything is auto-loaded
61
+ new Loader().init(app)
62
+ }
63
+
64
+ app.autoWorker(16) // Max elastic workers
65
+ app.daemon(443, 4) // 4 base workers
66
+ ```
67
+
68
+ Run `node app.js` → full-featured service is up!
69
+
70
+ ---
71
+
72
+ ### 4. Configuration Options
73
+
74
+ | Option | Type | Default | Description |
75
+ |----------------------|--------------------|---------------|-------------------------------------------------------------------------------------------------|
76
+ | `appPath` | string | `.` | Project root directory |
77
+ | `controllerPath` | string | `./controller`| Controller folder |
78
+ | `midwarePath` | string | `./middleware`| Middleware class folder |
79
+ | `prePath` | string | `''` | Global route prefix (e.g. `/api/v1`) |
80
+ | `subgroup` | string\|Array | `null` | Load only specified subdirectories (e.g. `['admin','api']`) |
81
+ | `fileAsGroup` | boolean | `true` | Highly recommended – each controller file becomes its own route group (precise middleware) |
82
+ | `optionsRoute` | boolean | `true` | Auto-add `OPTIONS /*` routes for CORS preflight |
83
+ | `multi` | boolean | `false` | Allow multiple `init()` calls (keep `false` in production) |
84
+ | `homeFile` | string | `''` | Which file serves the root `/` route (e.g. `'index.js'`) |
85
+ | `initArgs` | any | `app.service` | Arguments passed to every controller’s `init()` method |
86
+ | `beforeController` | function | `null` | Hook executed after controller instantiation, before route registration |
87
+ | `afterController` | function | `null` | Hook executed after route registration |
88
+ | `modelLoader` | async function | `null` | Powerful extension point – custom model loading (recommended with topbit-model) |
89
+
90
+ **Most common production config:**
91
+
92
+ ```js
93
+ new Loader({
94
+ prePath: '/api/v1',
95
+ fileAsGroup: true,
96
+ optionsRoute: true,
97
+ modelLoader: async (service) => {
98
+ const UserModel = require('./model/user')
99
+ service.userModel = new UserModel(service)
100
+ }
101
+ }).init(app)
102
+ ```
103
+
104
+ ---
105
+
106
+ ### 5. Controller Writing Guide
107
+
108
+ #### 5.1 Minimal RESTful Style (Recommended)
109
+
110
+ ```js
111
+ // controller/user.js
112
+ class User {
113
+ async get(c) { // GET /user/:id
114
+ c.to({ id: c.param.id })
115
+ }
116
+ async list(c) { // GET /user
117
+ c.to(['alice', 'bob'])
118
+ }
119
+ async post(c) { // POST /user
120
+ c.to({ saved: true })
121
+ }
122
+ async put(c) { // PUT /user/:id
123
+ c.to({ updated: true })
124
+ }
125
+ async delete(c) { // DELETE /user/:id
126
+ c.to({ deleted: true })
127
+ }
128
+ }
129
+ module.exports = User
130
+ ```
131
+
132
+ #### 5.2 Custom Path Parameters
133
+
134
+ ```js
135
+ class User {
136
+ static param = '/:uid/profile' // overrides default /:id
137
+ static postParam = '/register' // POST /user/register
138
+
139
+ async post(c) {
140
+ c.ok('registered')
141
+ }
142
+ }
143
+ ```
144
+
145
+ #### 5.3 File-Specific Middleware
146
+
147
+ ```js
148
+ class User {
149
+ static __mid() {
150
+ return [
151
+ [require('../middleware/@auth'), { pre: true }],
152
+ require('../middleware/rate-limit')
153
+ ]
154
+ }
155
+ }
156
+ ```
157
+
158
+ #### 5.4 Homepage Controller
159
+
160
+ ```js
161
+ // controller/index.js
162
+ class Index {
163
+ async get(c) {
164
+ c.html('<h1>Welcome to Topbit</h1>')
165
+ }
166
+ }
167
+ module.exports = Index
168
+
169
+ // In Loader config:
170
+ new Loader({ homeFile: 'index.js' }).init(app)
171
+ ```
172
+
173
+ ---
174
+
175
+ ### 6. Middleware Writing Guide
176
+
177
+ #### 6.1 Class-Style Middleware (Recommended – file name starts with `@`)
178
+
179
+ ```js
180
+ // middleware/@auth.js
181
+ class Auth {
182
+ async middleware(c, next) {
183
+ if (!c.headers.token) return c.status(401).to('Token required')
184
+ c.user = { id: 1 }
185
+ await next(c)
186
+ }
187
+ }
188
+ module.exports = Auth
189
+ ```
190
+
191
+ #### 6.2 Global / Group Middleware via `__mid.js`
192
+
193
+ ```js
194
+ // controller/__mid.js (global) or controller/admin/__mid.js (group)
195
+ module.exports = [
196
+ { name: '@auth' }, // class middleware
197
+ { name: 'rate-limit', method: ['GET','POST'] }, // plain function
198
+ { middleware: async (c, next) => { // inline
199
+ console.log('global mid')
200
+ await next(c)
201
+ }, pre: true }
202
+ ]
203
+ ```
204
+
205
+ #### 6.3 File-Level Middleware (Most Precise)
206
+
207
+ ```js
208
+ // Inside any controller file
209
+ static __mid() {
210
+ return [
211
+ { name: '@vip-auth', pre: true },
212
+ { name: 'log', method: 'POST' }
213
+ ]
214
+ }
215
+ ```
216
+
217
+ ---
218
+
219
+ ### 7. Model Loading (modelLoader) Best Practice
220
+
221
+ ```js
222
+ new Loader({
223
+ modelLoader: async (service) => {
224
+ const glob = require('glob')
225
+ const path = require('path')
226
+ const files = glob.sync('model/**/*.js', { cwd: __dirname })
227
+
228
+ for (const f of files) {
229
+ const Model = require(path.resolve(__dirname, f))
230
+ const name = path.basename(f, '.js')
231
+ service[name + 'Model'] = new Model(service)
232
+ }
233
+ }
234
+ }).init(app)
235
+ ```
236
+
237
+ ---
238
+
239
+ ### 8. Naming & Safety Rules
240
+
241
+ - Folder and file names may only contain: `a-z 0-9 _ -` and must start with a letter
242
+ - No spaces, Chinese characters, uppercase letters, or special symbols
243
+ - Files/folders starting with `!` are automatically ignored
244
+ - Violation → red warning + skip loading
245
+
246
+ ---
247
+
248
+ ### 9. Advanced Tips Collection
249
+
250
+ | Need | Solution |
251
+ |---------------------------------|-------------------------------------------------------------------------------------------------------|
252
+ | Multiple API versions coexist | Use different `prePath` and create multiple Loader instances |
253
+ | Canary / gray release | `subgroup: ['v2']` + Nginx traffic split |
254
+ | Plugin system | Each plugin has its own folder → `new Loader({ appPath: './plugins/xxx' }).init(app)` |
255
+ | Hot reload (dev) | Set `multi: true` + watch files with chokidar and re-call `init()` |
256
+
257
+ ---
258
+
259
+ ### 10. Production-Grade Full Entry Example
260
+
261
+ ```js
262
+ // app.js (Ultimate production version)
263
+ 'use strict'
264
+ process.chdir(__dirname)
265
+
266
+ const Topbit = require('topbit')
267
+ const { Loader } = Topbit
268
+
269
+ const app = new Topbit({
270
+ debug: false,
271
+ http2: true,
272
+ allowHTTP1: true,
273
+ cert: '/etc/ssl/certs/fullchain.pem',
274
+ key: '/etc/ssl/private/privkey.pem',
275
+ globalLog: true,
276
+ logType: 'file',
277
+ logFile: '/var/log/topbit/access.log',
278
+ errorLogFile: '/var/log/topbit/error.log'
279
+ })
280
+
281
+ if (app.isWorker) {
282
+ new Loader({
283
+ prePath: '/api',
284
+ fileAsGroup: true,
285
+ optionsRoute: true,
286
+ modelLoader: async (svc) => {
287
+ svc.db = require('./lib/mysql-pool')
288
+ svc.redis = require('./lib/redis-client')
289
+ }
290
+ }).init(app)
291
+ }
292
+
293
+ app.sched('none')
294
+ app.autoWorker(32)
295
+ app.daemon(443, 8)
296
+ ```
297
+
298
+ ---
299
+
300
+ **You have now mastered the complete essence of TopbitLoader!**
301
+
302
+ Start using it today and you’ll find:
303
+ > Topbit + TopbitLoader = possibly the best developer experience + highest performance backend combination in the current Node.js ecosystem.
304
+
305
+ Happy coding and may your services fly!
@@ -0,0 +1,138 @@
1
+ # 🔐 TopbitToken
2
+
3
+ **Ultra-Fast & Secure Token System for Topbit🪙**
4
+
5
+
6
+ ### 1. What is TopbitToken?
7
+
8
+ TopbitToken is a zero-dependency, minimalist, high-security encrypted token system designed specifically for the Topbit framework.
9
+
10
+ Built entirely on Node.js native `crypto`, supports:
11
+
12
+ - AES-256-GCM (default, recommended)
13
+ - AES-192-GCM / AES-128-CBC / AES-256-CBC
14
+ - SM4-CBC (China GM standard)
15
+
16
+ **One-sentence summary:**
17
+ > 3 lines of code = Issue + Verify + Auto-refresh + Instant revocation (hot-swappable keys)
18
+
19
+ ---
20
+
21
+ ### 2. Why Choose TopbitToken?
22
+
23
+ | Feature | Description |
24
+ |--------------------------------|----------------------------------------------------------------------------------|
25
+ | **Zero Dependencies** | Pure native crypto, no jwt/jsonwebtoken |
26
+ | **Lightning Fast** | AES-NI + GCM mode, < 0.05ms per verification |
27
+ | **Refresh Auto Token Refresh** | Automatically issues new token when nearing expiry |
28
+ | **Key Multiple Keys (tokenId)**| Supports multiple key sets, switch master key = instantly invalidate all old tokens |
29
+ | **Shield Tamper-proof** | Built-in timestamp + expiry + tokenId validation |
30
+ | **Lock Instant Revocation** | Remove a tokenId → all related tokens die immediately, no waiting |
31
+ | **Gear SM4 Support** | Full support for China national crypto standard |
32
+
33
+ ---
34
+
35
+ ### 3. 30-Second Quick Start
36
+
37
+ ```js
38
+ // middleware/@token.js
39
+ const TopbitToken = require('topbit-token')
40
+
41
+ const token = new TopbitToken({
42
+ key : 'your-very-strong-32-byte-secret!!',
43
+ expires : 60 * 60 * 24, // 24 hours
44
+ refresh : true // Enable auto refresh
45
+ })
46
+
47
+ module.exports = token
48
+ ```
49
+
50
+ ```js
51
+ // controller/user.js
52
+ async post(c) {
53
+ // After successful login
54
+ const userinfo = { uid: 1, name: 'Alice', role: 'admin' }
55
+ const t = token.make(userinfo)
56
+ c.setHeader('authorization', t)
57
+ c.to({ok: true})
58
+ }
59
+
60
+ // All protected routes automatically use token.mid()
61
+ // Verified user info → c.user
62
+ ```
63
+
64
+ ---
65
+
66
+ ### 4. Full Configuration Options
67
+
68
+ | Option | Type | Default | Description |
69
+ |----------------|----------------|-------------------|----------------------------------------------------------|
70
+ | `key` | string | random 32 bytes | Master encryption key (32 bytes recommended) |
71
+ | `algorithm` | string | `aes-256-gcm` | Supported: `aes-256-gcm`, `sm4-cbc`, etc. |
72
+ | `expires` | number (sec) | 3 hours | Default token lifetime |
73
+ | `refresh` | boolean | `false` | Auto refresh in last 1/5 of lifetime |
74
+ | `encoding` | string | `base64url` | Output encoding |
75
+ | `failedCode` | number | `401` | HTTP status on auth failure |
76
+
77
+ ---
78
+
79
+ ### 5. Advanced: Multi-Key + Instant Revocation
80
+
81
+ ```js
82
+ const token = new TopbitToken({ key: 'current-master-key' })
83
+
84
+ // Add multiple key versions
85
+ token.addTokenId({
86
+ 'v2024' : 'old-key-jan-2024',
87
+ 'mobile': 'mobile-app-key'
88
+ })
89
+
90
+ // Key leaked? Kill instantly:
91
+ token.removeTokenId('v2024') // All tokens issued with v2024 die now
92
+ ```
93
+
94
+ ---
95
+
96
+ ### 6. Auto Token Refresh
97
+
98
+ ```js
99
+ new TopbitToken({
100
+ expires: 24*3600,
101
+ refresh: true
102
+ })
103
+ ```
104
+
105
+ → When remaining time < 20%, server returns:
106
+ `x-refresh-token: new-long-lived-token`
107
+
108
+ Frontend just replaces the old one → seamless “never expire” experience.
109
+
110
+ ---
111
+
112
+ ### 7. Production Recommended Setup
113
+
114
+ ```js
115
+ // middleware/@auth.js
116
+ const TopbitToken = require('topbit-token')
117
+
118
+ const token = new TopbitToken({
119
+ algorithm : 'aes-256-gcm',
120
+ key : process.env.TOKEN_SECRET,
121
+ expires : 30 * 24 * 3600, // 30 days
122
+ refresh : true
123
+ })
124
+
125
+ if (process.env.TOKEN_ID) {
126
+ token.addTokenId(process.env.TOKEN_ID)
127
+ }
128
+
129
+ module.exports = token
130
+ ```
131
+
132
+ ---
133
+
134
+ **TopbitToken is currently the fastest, safest, and most operations-friendly authentication solution in the Topbit ecosystem.**
135
+
136
+ With TopbitLoader, you get a true zero-config, fully automatic, high-performance authentication system.
137
+
138
+ Enjoy secure, blazing-fast services!