@fecommunity/reactpress-server 1.0.0-beta.1

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.
Files changed (235) hide show
  1. package/README.md +395 -0
  2. package/bin/reactpress-server.js +302 -0
  3. package/dist/app.module.d.ts +2 -0
  4. package/dist/app.module.js +80 -0
  5. package/dist/app.module.js.map +1 -0
  6. package/dist/bootstrap.d.ts +10 -0
  7. package/dist/bootstrap.js +57 -0
  8. package/dist/bootstrap.js.map +1 -0
  9. package/dist/filters/http-exception.filter.d.ts +4 -0
  10. package/dist/filters/http-exception.filter.js +36 -0
  11. package/dist/filters/http-exception.filter.js.map +1 -0
  12. package/dist/interceptors/transform.interceptor.d.ts +9 -0
  13. package/dist/interceptors/transform.interceptor.js +36 -0
  14. package/dist/interceptors/transform.interceptor.js.map +1 -0
  15. package/dist/logger/index.d.ts +4 -0
  16. package/dist/logger/index.js +33 -0
  17. package/dist/logger/index.js.map +1 -0
  18. package/dist/main.d.ts +1 -0
  19. package/dist/main.js +44 -0
  20. package/dist/main.js.map +1 -0
  21. package/dist/modules/article/article.controller.d.ts +27 -0
  22. package/dist/modules/article/article.controller.js +198 -0
  23. package/dist/modules/article/article.controller.js.map +1 -0
  24. package/dist/modules/article/article.entity.d.ts +23 -0
  25. package/dist/modules/article/article.entity.js +128 -0
  26. package/dist/modules/article/article.entity.js.map +1 -0
  27. package/dist/modules/article/article.module.d.ts +2 -0
  28. package/dist/modules/article/article.module.js +30 -0
  29. package/dist/modules/article/article.module.js.map +1 -0
  30. package/dist/modules/article/article.service.d.ts +30 -0
  31. package/dist/modules/article/article.service.js +303 -0
  32. package/dist/modules/article/article.service.js.map +1 -0
  33. package/dist/modules/article/article.util.d.ts +1 -0
  34. package/dist/modules/article/article.util.js +9 -0
  35. package/dist/modules/article/article.util.js.map +1 -0
  36. package/dist/modules/auth/auth.controller.d.ts +12 -0
  37. package/dist/modules/auth/auth.controller.js +66 -0
  38. package/dist/modules/auth/auth.controller.js.map +1 -0
  39. package/dist/modules/auth/auth.module.d.ts +2 -0
  40. package/dist/modules/auth/auth.module.js +41 -0
  41. package/dist/modules/auth/auth.module.js.map +1 -0
  42. package/dist/modules/auth/auth.service.d.ts +26 -0
  43. package/dist/modules/auth/auth.service.js +127 -0
  44. package/dist/modules/auth/auth.service.js.map +1 -0
  45. package/dist/modules/auth/jwt-auth.guard.d.ts +7 -0
  46. package/dist/modules/auth/jwt-auth.guard.js +29 -0
  47. package/dist/modules/auth/jwt-auth.guard.js.map +1 -0
  48. package/dist/modules/auth/jwt.strategy.d.ts +9 -0
  49. package/dist/modules/auth/jwt.strategy.js +38 -0
  50. package/dist/modules/auth/jwt.strategy.js.map +1 -0
  51. package/dist/modules/auth/roles.guard.d.ts +10 -0
  52. package/dist/modules/auth/roles.guard.js +46 -0
  53. package/dist/modules/auth/roles.guard.js.map +1 -0
  54. package/dist/modules/category/category.controller.d.ts +11 -0
  55. package/dist/modules/category/category.controller.js +91 -0
  56. package/dist/modules/category/category.controller.js.map +1 -0
  57. package/dist/modules/category/category.entity.d.ts +9 -0
  58. package/dist/modules/category/category.entity.js +60 -0
  59. package/dist/modules/category/category.entity.js.map +1 -0
  60. package/dist/modules/category/category.module.d.ts +2 -0
  61. package/dist/modules/category/category.module.js +27 -0
  62. package/dist/modules/category/category.module.js.map +1 -0
  63. package/dist/modules/category/category.service.d.ts +12 -0
  64. package/dist/modules/category/category.service.js +89 -0
  65. package/dist/modules/category/category.service.js.map +1 -0
  66. package/dist/modules/comment/comment.controller.d.ts +12 -0
  67. package/dist/modules/comment/comment.controller.js +100 -0
  68. package/dist/modules/comment/comment.controller.js.map +1 -0
  69. package/dist/modules/comment/comment.entity.d.ts +17 -0
  70. package/dist/modules/comment/comment.entity.js +104 -0
  71. package/dist/modules/comment/comment.entity.js.map +1 -0
  72. package/dist/modules/comment/comment.module.d.ts +2 -0
  73. package/dist/modules/comment/comment.module.js +30 -0
  74. package/dist/modules/comment/comment.module.js.map +1 -0
  75. package/dist/modules/comment/comment.service.d.ts +24 -0
  76. package/dist/modules/comment/comment.service.js +172 -0
  77. package/dist/modules/comment/comment.service.js.map +1 -0
  78. package/dist/modules/comment/html.d.ts +15 -0
  79. package/dist/modules/comment/html.js +632 -0
  80. package/dist/modules/comment/html.js.map +1 -0
  81. package/dist/modules/file/file.controller.d.ts +10 -0
  82. package/dist/modules/file/file.controller.js +84 -0
  83. package/dist/modules/file/file.controller.js.map +1 -0
  84. package/dist/modules/file/file.entity.d.ts +9 -0
  85. package/dist/modules/file/file.entity.js +60 -0
  86. package/dist/modules/file/file.entity.js.map +1 -0
  87. package/dist/modules/file/file.module.d.ts +2 -0
  88. package/dist/modules/file/file.module.js +27 -0
  89. package/dist/modules/file/file.module.js.map +1 -0
  90. package/dist/modules/file/file.service.d.ts +17 -0
  91. package/dist/modules/file/file.service.js +111 -0
  92. package/dist/modules/file/file.service.js.map +1 -0
  93. package/dist/modules/install/install.controller.d.ts +11 -0
  94. package/dist/modules/install/install.controller.js +49 -0
  95. package/dist/modules/install/install.controller.js.map +1 -0
  96. package/dist/modules/install/install.module.d.ts +2 -0
  97. package/dist/modules/install/install.module.js +26 -0
  98. package/dist/modules/install/install.module.js.map +1 -0
  99. package/dist/modules/install/install.service.d.ts +12 -0
  100. package/dist/modules/install/install.service.js +63 -0
  101. package/dist/modules/install/install.service.js.map +1 -0
  102. package/dist/modules/knowledge/knowledge.controller.d.ts +14 -0
  103. package/dist/modules/knowledge/knowledge.controller.js +128 -0
  104. package/dist/modules/knowledge/knowledge.controller.js.map +1 -0
  105. package/dist/modules/knowledge/knowledge.entity.d.ts +18 -0
  106. package/dist/modules/knowledge/knowledge.entity.js +109 -0
  107. package/dist/modules/knowledge/knowledge.entity.js.map +1 -0
  108. package/dist/modules/knowledge/knowledge.module.d.ts +2 -0
  109. package/dist/modules/knowledge/knowledge.module.js +27 -0
  110. package/dist/modules/knowledge/knowledge.module.js.map +1 -0
  111. package/dist/modules/knowledge/knowledge.service.d.ts +14 -0
  112. package/dist/modules/knowledge/knowledge.service.js +143 -0
  113. package/dist/modules/knowledge/knowledge.service.js.map +1 -0
  114. package/dist/modules/page/page.controller.d.ts +12 -0
  115. package/dist/modules/page/page.controller.js +102 -0
  116. package/dist/modules/page/page.controller.js.map +1 -0
  117. package/dist/modules/page/page.entity.d.ts +15 -0
  118. package/dist/modules/page/page.entity.js +94 -0
  119. package/dist/modules/page/page.entity.js.map +1 -0
  120. package/dist/modules/page/page.module.d.ts +2 -0
  121. package/dist/modules/page/page.module.js +27 -0
  122. package/dist/modules/page/page.module.js.map +1 -0
  123. package/dist/modules/page/page.service.d.ts +12 -0
  124. package/dist/modules/page/page.service.js +97 -0
  125. package/dist/modules/page/page.service.js.map +1 -0
  126. package/dist/modules/search/search.controller.d.ts +8 -0
  127. package/dist/modules/search/search.controller.js +67 -0
  128. package/dist/modules/search/search.controller.js.map +1 -0
  129. package/dist/modules/search/search.entity.d.ts +8 -0
  130. package/dist/modules/search/search.entity.js +59 -0
  131. package/dist/modules/search/search.entity.js.map +1 -0
  132. package/dist/modules/search/search.module.d.ts +2 -0
  133. package/dist/modules/search/search.module.js +27 -0
  134. package/dist/modules/search/search.module.js.map +1 -0
  135. package/dist/modules/search/search.service.d.ts +12 -0
  136. package/dist/modules/search/search.service.js +84 -0
  137. package/dist/modules/search/search.service.js.map +1 -0
  138. package/dist/modules/setting/setting.constant.d.ts +4 -0
  139. package/dist/modules/setting/setting.constant.js +24 -0
  140. package/dist/modules/setting/setting.constant.js.map +1 -0
  141. package/dist/modules/setting/setting.controller.d.ts +12 -0
  142. package/dist/modules/setting/setting.controller.js +77 -0
  143. package/dist/modules/setting/setting.controller.js.map +1 -0
  144. package/dist/modules/setting/setting.entity.d.ts +26 -0
  145. package/dist/modules/setting/setting.entity.js +149 -0
  146. package/dist/modules/setting/setting.entity.js.map +1 -0
  147. package/dist/modules/setting/setting.module.d.ts +2 -0
  148. package/dist/modules/setting/setting.module.js +28 -0
  149. package/dist/modules/setting/setting.module.js.map +1 -0
  150. package/dist/modules/setting/setting.service.d.ts +10 -0
  151. package/dist/modules/setting/setting.service.js +83 -0
  152. package/dist/modules/setting/setting.service.js.map +1 -0
  153. package/dist/modules/smtp/mail.util.d.ts +6 -0
  154. package/dist/modules/smtp/mail.util.js +33 -0
  155. package/dist/modules/smtp/mail.util.js.map +1 -0
  156. package/dist/modules/smtp/smtp.controller.d.ts +9 -0
  157. package/dist/modules/smtp/smtp.controller.js +69 -0
  158. package/dist/modules/smtp/smtp.controller.js.map +1 -0
  159. package/dist/modules/smtp/smtp.entity.d.ts +9 -0
  160. package/dist/modules/smtp/smtp.entity.js +60 -0
  161. package/dist/modules/smtp/smtp.entity.js.map +1 -0
  162. package/dist/modules/smtp/smtp.module.d.ts +2 -0
  163. package/dist/modules/smtp/smtp.module.js +28 -0
  164. package/dist/modules/smtp/smtp.module.js.map +1 -0
  165. package/dist/modules/smtp/smtp.service.d.ts +11 -0
  166. package/dist/modules/smtp/smtp.service.js +82 -0
  167. package/dist/modules/smtp/smtp.service.js.map +1 -0
  168. package/dist/modules/tag/tag.controller.d.ts +12 -0
  169. package/dist/modules/tag/tag.controller.js +101 -0
  170. package/dist/modules/tag/tag.controller.js.map +1 -0
  171. package/dist/modules/tag/tag.entity.d.ts +9 -0
  172. package/dist/modules/tag/tag.entity.js +59 -0
  173. package/dist/modules/tag/tag.entity.js.map +1 -0
  174. package/dist/modules/tag/tag.module.d.ts +2 -0
  175. package/dist/modules/tag/tag.module.js +27 -0
  176. package/dist/modules/tag/tag.module.js.map +1 -0
  177. package/dist/modules/tag/tag.service.d.ts +13 -0
  178. package/dist/modules/tag/tag.service.js +103 -0
  179. package/dist/modules/tag/tag.service.js.map +1 -0
  180. package/dist/modules/user/user.controller.d.ts +13 -0
  181. package/dist/modules/user/user.controller.js +114 -0
  182. package/dist/modules/user/user.controller.js.map +1 -0
  183. package/dist/modules/user/user.entity.d.ts +15 -0
  184. package/dist/modules/user/user.entity.js +96 -0
  185. package/dist/modules/user/user.entity.js.map +1 -0
  186. package/dist/modules/user/user.module.d.ts +2 -0
  187. package/dist/modules/user/user.module.js +28 -0
  188. package/dist/modules/user/user.module.js.map +1 -0
  189. package/dist/modules/user/user.service.d.ts +16 -0
  190. package/dist/modules/user/user.service.js +151 -0
  191. package/dist/modules/user/user.service.js.map +1 -0
  192. package/dist/modules/view/view.controller.d.ts +11 -0
  193. package/dist/modules/view/view.controller.js +92 -0
  194. package/dist/modules/view/view.controller.js.map +1 -0
  195. package/dist/modules/view/view.entity.d.ts +14 -0
  196. package/dist/modules/view/view.entity.js +88 -0
  197. package/dist/modules/view/view.entity.js.map +1 -0
  198. package/dist/modules/view/view.module.d.ts +2 -0
  199. package/dist/modules/view/view.module.js +27 -0
  200. package/dist/modules/view/view.module.js.map +1 -0
  201. package/dist/modules/view/view.service.d.ts +11 -0
  202. package/dist/modules/view/view.service.js +89 -0
  203. package/dist/modules/view/view.service.js.map +1 -0
  204. package/dist/tsconfig.build.tsbuildinfo +15722 -0
  205. package/dist/utils/date.util.d.ts +1 -0
  206. package/dist/utils/date.util.js +13 -0
  207. package/dist/utils/date.util.js.map +1 -0
  208. package/dist/utils/ip.util.d.ts +2 -0
  209. package/dist/utils/ip.util.js +27 -0
  210. package/dist/utils/ip.util.js.map +1 -0
  211. package/dist/utils/markdown.util.d.ts +4 -0
  212. package/dist/utils/markdown.util.js +42 -0
  213. package/dist/utils/markdown.util.js.map +1 -0
  214. package/dist/utils/oss/aliyun-oss-client.d.ts +6 -0
  215. package/dist/utils/oss/aliyun-oss-client.js +28 -0
  216. package/dist/utils/oss/aliyun-oss-client.js.map +1 -0
  217. package/dist/utils/oss/oss-client.d.ts +6 -0
  218. package/dist/utils/oss/oss-client.js +10 -0
  219. package/dist/utils/oss/oss-client.js.map +1 -0
  220. package/dist/utils/oss.util.d.ts +13 -0
  221. package/dist/utils/oss.util.js +48 -0
  222. package/dist/utils/oss.util.js.map +1 -0
  223. package/dist/utils/ua.util.d.ts +9 -0
  224. package/dist/utils/ua.util.js +36 -0
  225. package/dist/utils/ua.util.js.map +1 -0
  226. package/dist/utils/uniqueid.util.d.ts +1 -0
  227. package/dist/utils/uniqueid.util.js +9 -0
  228. package/dist/utils/uniqueid.util.js.map +1 -0
  229. package/dist/utils/upload.util.d.ts +5 -0
  230. package/dist/utils/upload.util.js +34 -0
  231. package/dist/utils/upload.util.js.map +1 -0
  232. package/dist/utils/user.util.d.ts +1 -0
  233. package/dist/utils/user.util.js +18 -0
  234. package/dist/utils/user.util.js.map +1 -0
  235. package/package.json +140 -0
package/README.md ADDED
@@ -0,0 +1,395 @@
1
+ # @fecommunity/reactpress-server
2
+
3
+ NestJS-based backend API server for ReactPress - A modern React-based CMS platform.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # For new projects
9
+ npm install @fecommunity/reactpress-server@1.0.0-beta.1 @fecommunity/reactpress-config@1.0.0-beta.1
10
+
11
+ # Using yarn
12
+ yarn add @fecommunity/reactpress-server@1.0.0-beta.1 @fecommunity/reactpress-config@1.0.0-beta.1
13
+
14
+ # Using pnpm in workspace root (add -w flag)
15
+ pnpm add -w @fecommunity/reactpress-server@1.0.0-beta.1 @fecommunity/reactpress-config@1.0.0-beta.1
16
+
17
+ # Using pnpm in standalone project
18
+ pnpm add @fecommunity/reactpress-server@1.0.0-beta.1 @fecommunity/reactpress-config@1.0.0-beta.1
19
+ ```
20
+
21
+ ## Features
22
+
23
+ - 🚀 **NestJS Framework** - Built on modern, scalable Node.js framework
24
+ - 🔐 **Authentication & Authorization** - JWT-based auth with role management
25
+ - 📝 **Content Management** - Full CRUD for articles, categories, tags, and comments
26
+ - 🗃️ **Database Integration** - MySQL support with TypeORM
27
+ - 📁 **File Upload** - Local and cloud storage support (Ali OSS)
28
+ - 🌍 **Internationalization** - Multi-language support
29
+ - 📚 **API Documentation** - Auto-generated Swagger docs
30
+ - 🔒 **Security** - Rate limiting, CORS, Helmet integration
31
+
32
+ ## Quick Start
33
+
34
+ ### 1. Initialize Server
35
+
36
+ ```bash
37
+ # Using npx (recommended for first-time use)
38
+ npx @fecommunity/reactpress-server init
39
+
40
+ # Or if installed globally
41
+ reactpress-server init
42
+ ```
43
+
44
+ This will create configuration files and set up your environment.
45
+
46
+ ### 2. Start Development Server
47
+
48
+ ```bash
49
+ # Using npx
50
+ npx @fecommunity/reactpress-server dev
51
+
52
+ # Or if installed globally
53
+ reactpress-server dev
54
+ ```
55
+
56
+ The server will start on `http://localhost:3002` with API documentation at `http://localhost:3002/api`.
57
+
58
+ ### 3. Start Production Server
59
+
60
+ ```bash
61
+ # Using npx
62
+ npx @fecommunity/reactpress-server start
63
+
64
+ # Or if installed globally
65
+ reactpress-server start
66
+ ```
67
+
68
+ ## CLI Commands
69
+
70
+ The package includes a powerful CLI for server management:
71
+
72
+ ### Initialize Project
73
+ ```bash
74
+ # Using npx (recommended)
75
+ npx @fecommunity/reactpress-server init [options]
76
+
77
+ # Or if installed globally
78
+ reactpress-server init [options]
79
+
80
+ Options:
81
+ -p, --port <port> Server port (default: 3002)
82
+ --api-prefix <prefix> API prefix (default: /api)
83
+ --db-host <host> Database host (default: localhost)
84
+ --db-port <port> Database port (default: 3306)
85
+ --db-name <name> Database name (default: reactpress)
86
+ ```
87
+
88
+ ### Development Mode
89
+ ```bash
90
+ # Using npx
91
+ npx @fecommunity/reactpress-server dev [options]
92
+
93
+ # Or if installed globally
94
+ reactpress-server dev [options]
95
+
96
+ Options:
97
+ -p, --port <port> Server port (default: 3002)
98
+ --no-open Don't open browser automatically
99
+ ```
100
+
101
+ ### Production Mode
102
+ ```bash
103
+ # Using npx
104
+ npx @fecommunity/reactpress-server start [options]
105
+
106
+ # Or if installed globally
107
+ reactpress-server start [options]
108
+
109
+ Options:
110
+ -p, --port <port> Server port (default: 3002)
111
+ ```
112
+
113
+ ### Build Project
114
+ ```bash
115
+ # Using npx
116
+ npx @fecommunity/reactpress-server build
117
+
118
+ # Or if installed globally
119
+ reactpress-server build
120
+ ```
121
+
122
+ ## Environment Configuration
123
+
124
+ Create a `.env` file in your project root:
125
+
126
+ ```env
127
+ # Server Configuration
128
+ SERVER_PORT=3002
129
+ SERVER_API_PREFIX=/api
130
+ NODE_ENV=development
131
+
132
+ # Database Configuration
133
+ DB_HOST=localhost
134
+ DB_PORT=3306
135
+ DB_USERNAME=root
136
+ DB_PASSWORD=your_password
137
+ DB_DATABASE=reactpress
138
+
139
+ # JWT Configuration
140
+ JWT_SECRET=your_jwt_secret_key
141
+ JWT_EXPIRES_IN=7d
142
+
143
+ # File Upload (Optional - Ali OSS)
144
+ OSS_ACCESS_KEY_ID=your_access_key_id
145
+ OSS_ACCESS_KEY_SECRET=your_access_key_secret
146
+ OSS_BUCKET=your_bucket_name
147
+ OSS_REGION=your_region
148
+
149
+ # Email Configuration (Optional)
150
+ EMAIL_HOST=smtp.gmail.com
151
+ EMAIL_PORT=587
152
+ EMAIL_USER=your_email@gmail.com
153
+ EMAIL_PASS=your_app_password
154
+ ```
155
+
156
+ ## Programmatic Usage
157
+
158
+ You can also use the server programmatically in your Node.js applications:
159
+
160
+ ```typescript
161
+ import { bootstrap } from '@fecommunity/reactpress-server';
162
+
163
+ async function startServer() {
164
+ const app = await bootstrap({
165
+ port: 3002,
166
+ apiPrefix: '/api',
167
+ cors: true
168
+ });
169
+
170
+ console.log('ReactPress server started successfully!');
171
+ }
172
+
173
+ startServer();
174
+ ```
175
+
176
+ ## API Endpoints
177
+
178
+ The server provides comprehensive REST APIs:
179
+
180
+ ### Authentication
181
+ - `POST /api/auth/login` - User login
182
+ - `POST /api/auth/register` - User registration
183
+ - `GET /api/auth/profile` - Get user profile
184
+
185
+ ### Articles
186
+ - `GET /api/articles` - Get articles (with pagination)
187
+ - `POST /api/articles` - Create article
188
+ - `GET /api/articles/:id` - Get article by ID
189
+ - `PUT /api/articles/:id` - Update article
190
+ - `DELETE /api/articles/:id` - Delete article
191
+
192
+ ### Categories
193
+ - `GET /api/categories` - Get all categories
194
+ - `POST /api/categories` - Create category
195
+ - `PUT /api/categories/:id` - Update category
196
+ - `DELETE /api/categories/:id` - Delete category
197
+
198
+ ### Tags
199
+ - `GET /api/tags` - Get all tags
200
+ - `POST /api/tags` - Create tag
201
+ - `PUT /api/tags/:id` - Update tag
202
+ - `DELETE /api/tags/:id` - Delete tag
203
+
204
+ ### Comments
205
+ - `GET /api/comments` - Get comments
206
+ - `POST /api/comments` - Create comment
207
+ - `PUT /api/comments/:id` - Update comment
208
+ - `DELETE /api/comments/:id` - Delete comment
209
+
210
+ ### File Upload
211
+ - `POST /api/upload/image` - Upload image
212
+ - `POST /api/upload/file` - Upload file
213
+
214
+ ## Database Setup
215
+
216
+ ### MySQL Installation
217
+
218
+ **Ubuntu/Debian:**
219
+ ```bash
220
+ sudo apt update
221
+ sudo apt install mysql-server
222
+ sudo mysql_secure_installation
223
+ ```
224
+
225
+ **macOS:**
226
+ ```bash
227
+ brew install mysql
228
+ brew services start mysql
229
+ ```
230
+
231
+ **Windows:**
232
+ Download and install from [MySQL Official Website](https://dev.mysql.com/downloads/mysql/)
233
+
234
+ ### Database Creation
235
+
236
+ ```sql
237
+ CREATE DATABASE reactpress;
238
+ CREATE USER 'reactpress'@'localhost' IDENTIFIED BY 'your_password';
239
+ GRANT ALL PRIVILEGES ON reactpress.* TO 'reactpress'@'localhost';
240
+ FLUSH PRIVILEGES;
241
+ ```
242
+
243
+ ## Advanced Usage
244
+
245
+ ### Custom Configuration
246
+
247
+ ```typescript
248
+ import { NestFactory } from '@nestjs/core';
249
+ import { AppModule } from '@fecommunity/reactpress-server';
250
+
251
+ async function bootstrap() {
252
+ const app = await NestFactory.create(AppModule);
253
+
254
+ // Custom middleware
255
+ app.use('/custom', customMiddleware);
256
+
257
+ // Custom global filters
258
+ app.useGlobalFilters(new CustomExceptionFilter());
259
+
260
+ await app.listen(3002);
261
+ }
262
+
263
+ bootstrap();
264
+ ```
265
+
266
+ ### Plugin Development
267
+
268
+ ```typescript
269
+ import { Module } from '@nestjs/common';
270
+ import { PluginInterface } from '@fecommunity/reactpress-server';
271
+
272
+ @Module({
273
+ // Your plugin implementation
274
+ })
275
+ export class CustomPlugin implements PluginInterface {
276
+ install() {
277
+ // Plugin installation logic
278
+ }
279
+ }
280
+ ```
281
+
282
+ ## Deployment
283
+
284
+ ### PM2 (Recommended)
285
+
286
+ ```bash
287
+ # Install PM2
288
+ npm install -g pm2
289
+
290
+ # Start with PM2
291
+ npm run pm2
292
+
293
+ # Monitor
294
+ pm2 monitor
295
+ ```
296
+
297
+ ### Docker
298
+
299
+ ```dockerfile
300
+ FROM node:18-alpine
301
+ WORKDIR /app
302
+ COPY package*.json ./
303
+ RUN npm install
304
+ COPY . .
305
+ RUN npm run build
306
+ EXPOSE 3002
307
+ CMD ["npm", "start"]
308
+ ```
309
+
310
+ ### Docker Compose
311
+
312
+ ```yaml
313
+ version: '3.8'
314
+ services:
315
+ reactpress-server:
316
+ build: .
317
+ ports:
318
+ - "3002:3002"
319
+ environment:
320
+ - DB_HOST=mysql
321
+ - DB_USERNAME=root
322
+ - DB_PASSWORD=password
323
+ - DB_DATABASE=reactpress
324
+ depends_on:
325
+ - mysql
326
+
327
+ mysql:
328
+ image: mysql:5.7
329
+ environment:
330
+ - MYSQL_ROOT_PASSWORD=password
331
+ - MYSQL_DATABASE=reactpress
332
+ ports:
333
+ - "3306:3306"
334
+ ```
335
+
336
+ ## Integration with Frontend
337
+
338
+ Use with ReactPress client:
339
+
340
+ ```bash
341
+ # Install both server and client
342
+ npm install @fecommunity/reactpress-server @fecommunity/reactpress-client @fecommunity/reactpress-config
343
+
344
+ # Start server
345
+ npx reactpress-server dev
346
+
347
+ # In another terminal, start client
348
+ npx reactpress-client dev
349
+ ```
350
+
351
+ ## Troubleshooting
352
+
353
+ ### Common Issues
354
+
355
+ 1. **Database Connection Error**
356
+ ```
357
+ Error: connect ECONNREFUSED 127.0.0.1:3306
358
+ ```
359
+ - Ensure MySQL is running
360
+ - Check database credentials in `.env`
361
+
362
+ 2. **Port Already in Use**
363
+ ```
364
+ Error: listen EADDRINUSE :::3002
365
+ ```
366
+ - Change port in `.env` file or use `-p` option
367
+
368
+ 3. **JWT Secret Missing**
369
+ ```
370
+ Error: JWT_SECRET is not defined
371
+ ```
372
+ - Add `JWT_SECRET=your_secret_key` to `.env`
373
+
374
+ ### Debug Mode
375
+
376
+ Start server with debug information:
377
+
378
+ ```bash
379
+ DEBUG=* npx reactpress-server dev
380
+ ```
381
+
382
+ ## Contributing
383
+
384
+ Contributions are welcome! Please feel free to submit a Pull Request.
385
+
386
+ ## License
387
+
388
+ MIT
389
+
390
+ ## Links
391
+
392
+ - [GitHub Repository](https://github.com/fecommunity/reactpress)
393
+ - [Documentation](https://reactpress.surge.sh)
394
+ - [npm Package](https://www.npmjs.com/package/@fecommunity/reactpress-server)
395
+ - [API Documentation](http://localhost:3002/api) (when server is running)
@@ -0,0 +1,302 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { program } = require('commander');
4
+ const { execSync } = require('child_process');
5
+ const path = require('path');
6
+ const fs = require('fs');
7
+ const chalk = require('chalk');
8
+ const inquirer = require('inquirer');
9
+
10
+ program
11
+ .name('@reactpress/server')
12
+ .description('ReactPress Server CLI')
13
+ .version('1.0.0');
14
+
15
+ // Init command - 初始化服务器配置
16
+ program
17
+ .command('init')
18
+ .description('Initialize ReactPress server configuration')
19
+ .option('-d, --database <type>', 'Database type (mysql|postgres)', 'mysql')
20
+ .option('-p, --port <port>', 'Server port', '3002')
21
+ .option('--skip-db-setup', 'Skip database setup')
22
+ .action(async (options) => {
23
+ console.log(chalk.blue('🚀 Initializing ReactPress Server...\n'));
24
+
25
+ const cwd = process.cwd();
26
+ const envPath = path.join(cwd, '.env');
27
+
28
+ // 检查.env文件是否已存在
29
+ if (fs.existsSync(envPath)) {
30
+ const { overwrite } = await inquirer.prompt([
31
+ {
32
+ type: 'confirm',
33
+ name: 'overwrite',
34
+ message: 'Configuration file (.env) already exists. Overwrite?',
35
+ default: false
36
+ }
37
+ ]);
38
+
39
+ if (!overwrite) {
40
+ console.log(chalk.yellow('⚠️ Initialization cancelled.'));
41
+ process.exit(0);
42
+ }
43
+ }
44
+
45
+ // 收集配置信息
46
+ console.log(chalk.cyan('📋 Please provide the following configuration:\n'));
47
+
48
+ const config = await inquirer.prompt([
49
+ {
50
+ type: 'input',
51
+ name: 'DB_HOST',
52
+ message: 'Database host:',
53
+ default: 'localhost'
54
+ },
55
+ {
56
+ type: 'input',
57
+ name: 'DB_PORT',
58
+ message: 'Database port:',
59
+ default: options.database === 'postgres' ? '5432' : '3306'
60
+ },
61
+ {
62
+ type: 'input',
63
+ name: 'DB_USERNAME',
64
+ message: 'Database username:',
65
+ default: 'root'
66
+ },
67
+ {
68
+ type: 'password',
69
+ name: 'DB_PASSWORD',
70
+ message: 'Database password:',
71
+ mask: '*'
72
+ },
73
+ {
74
+ type: 'input',
75
+ name: 'DB_DATABASE',
76
+ message: 'Database name:',
77
+ default: 'reactpress'
78
+ },
79
+ {
80
+ type: 'input',
81
+ name: 'SERVER_PORT',
82
+ message: 'Server port:',
83
+ default: options.port
84
+ },
85
+ {
86
+ type: 'input',
87
+ name: 'JWT_SECRET',
88
+ message: 'JWT secret (leave empty to generate):',
89
+ default: ''
90
+ },
91
+ {
92
+ type: 'input',
93
+ name: 'ADMIN_USER',
94
+ message: 'Admin username:',
95
+ default: 'admin'
96
+ },
97
+ {
98
+ type: 'password',
99
+ name: 'ADMIN_PASSWD',
100
+ message: 'Admin password:',
101
+ default: 'admin',
102
+ mask: '*'
103
+ }
104
+ ]);
105
+
106
+ // 如果没有提供JWT密钥则生成一个
107
+ if (!config.JWT_SECRET) {
108
+ config.JWT_SECRET = require('crypto').randomBytes(32).toString('hex');
109
+ console.log(chalk.green('🔐 Generated JWT secret'));
110
+ }
111
+
112
+ // 创建.env文件
113
+ const envContent = `# ReactPress Server Configuration
114
+ # Generated on ${new Date().toISOString()}
115
+
116
+ # Database Configuration
117
+ DB_TYPE=${options.database}
118
+ DB_HOST=${config.DB_HOST}
119
+ DB_PORT=${config.DB_PORT}
120
+ DB_USERNAME=${config.DB_USERNAME}
121
+ DB_PASSWORD=${config.DB_PASSWORD}
122
+ DB_DATABASE=${config.DB_DATABASE}
123
+
124
+ # Server Configuration
125
+ SERVER_PORT=${config.SERVER_PORT}
126
+ SERVER_API_PREFIX=/api
127
+
128
+ # Security
129
+ JWT_SECRET=${config.JWT_SECRET}
130
+ ADMIN_USER=${config.ADMIN_USER}
131
+ ADMIN_PASSWD=${config.ADMIN_PASSWD}
132
+
133
+ # Environment
134
+ NODE_ENV=development
135
+ `;
136
+
137
+ fs.writeFileSync(envPath, envContent);
138
+ console.log(chalk.green('✅ Configuration saved to .env file'));
139
+
140
+ if (!options.skipDbSetup) {
141
+ console.log(chalk.yellow('\n🗄️ Setting up database...'));
142
+ console.log(chalk.gray(`Please ensure your ${options.database} server is running and create the database:`));
143
+ console.log(chalk.cyan(`CREATE DATABASE ${config.DB_DATABASE};`));
144
+ console.log(chalk.gray('Then run: npx @reactpress/server start'));
145
+ }
146
+
147
+ console.log(chalk.green('\n🎉 ReactPress Server initialized successfully!'));
148
+ console.log(chalk.cyan('\nNext steps:'));
149
+ console.log(chalk.gray('1. Start the server: npx @reactpress/server start'));
150
+ console.log(chalk.gray('2. Visit API: http://localhost:' + config.SERVER_PORT + '/api'));
151
+ console.log(chalk.gray('3. API docs: http://localhost:' + config.SERVER_PORT + '/api (Swagger UI)'));
152
+ });
153
+
154
+ // Start command - 启动服务器
155
+ program
156
+ .command('start')
157
+ .description('Start ReactPress server')
158
+ .option('-p, --port <port>', 'Server port')
159
+ .option('-d, --dev', 'Start in development mode')
160
+ .option('--watch', 'Watch for file changes (dev mode)')
161
+ .action(async (options) => {
162
+ console.log(chalk.blue('🚀 Starting ReactPress Server...\n'));
163
+
164
+ const cwd = process.cwd();
165
+ const envPath = path.join(cwd, '.env');
166
+
167
+ // 检查.env文件是否存在
168
+ if (!fs.existsSync(envPath)) {
169
+ console.log(chalk.red('❌ Configuration file (.env) not found!'));
170
+ console.log(chalk.yellow('Please run: npx @reactpress/server init'));
171
+ process.exit(1);
172
+ }
173
+
174
+ // 检查是否在项目根目录(有server目录)
175
+ const serverPath = path.join(cwd, 'server');
176
+ const hasServerDir = fs.existsSync(serverPath);
177
+
178
+ let serverMainPath;
179
+ if (hasServerDir) {
180
+ // 在项目根目录,使用相对路径
181
+ serverMainPath = path.join(serverPath, 'dist', 'main.js');
182
+ const packageDir = serverPath;
183
+
184
+ // 检查构建文件是否存在
185
+ if (!fs.existsSync(serverMainPath)) {
186
+ console.log(chalk.yellow('⚠️ Built server not found, building...'));
187
+ try {
188
+ execSync('pnpm run build:server', { cwd: cwd, stdio: 'inherit' });
189
+ } catch (error) {
190
+ console.log(chalk.red('❌ Build failed'));
191
+ process.exit(1);
192
+ }
193
+ }
194
+ } else {
195
+ // 可能在独立安装的@reactpress/server包中
196
+ try {
197
+ const serverPackagePath = require.resolve('@reactpress/server/package.json');
198
+ const serverPackageDir = path.dirname(serverPackagePath);
199
+ serverMainPath = path.join(serverPackageDir, 'dist', 'main.js');
200
+ } catch (error) {
201
+ console.log(chalk.red('❌ ReactPress server package not found!'));
202
+ console.log(chalk.yellow('Please install: npm install @reactpress/server'));
203
+ process.exit(1);
204
+ }
205
+ }
206
+
207
+ // 设置环境变量
208
+ const env = {
209
+ ...process.env,
210
+ NODE_ENV: options.dev ? 'development' : 'production'
211
+ };
212
+
213
+ if (options.port) {
214
+ env.SERVER_PORT = options.port;
215
+ }
216
+
217
+ try {
218
+ if (options.dev || options.watch) {
219
+ console.log(chalk.yellow('🔄 Starting in development mode...'));
220
+ if (hasServerDir) {
221
+ execSync('pnpm run dev:server', {
222
+ cwd: cwd,
223
+ stdio: 'inherit',
224
+ env
225
+ });
226
+ } else {
227
+ console.log(chalk.yellow('⚠️ Development mode requires server source code'));
228
+ console.log(chalk.cyan('Starting in production mode instead...'));
229
+ execSync(`node ${serverMainPath}`, {
230
+ cwd: process.cwd(),
231
+ stdio: 'inherit',
232
+ env
233
+ });
234
+ }
235
+ } else {
236
+ console.log(chalk.green('🌟 Starting in production mode...'));
237
+ execSync(`node ${serverMainPath}`, {
238
+ cwd: process.cwd(),
239
+ stdio: 'inherit',
240
+ env
241
+ });
242
+ }
243
+ } catch (error) {
244
+ console.log(chalk.red('❌ Failed to start server'));
245
+ process.exit(1);
246
+ }
247
+ });
248
+
249
+ // Build command - 构建服务器
250
+ program
251
+ .command('build')
252
+ .description('Build ReactPress server')
253
+ .action(() => {
254
+ console.log(chalk.blue('🔨 Building ReactPress Server...\n'));
255
+
256
+ const cwd = process.cwd();
257
+ const serverPath = path.join(cwd, 'server');
258
+
259
+ if (!fs.existsSync(serverPath)) {
260
+ console.log(chalk.red('❌ Server directory not found!'));
261
+ console.log(chalk.yellow('This command should be run from the project root directory.'));
262
+ process.exit(1);
263
+ }
264
+
265
+ try {
266
+ execSync('pnpm run build:server', {
267
+ cwd: cwd,
268
+ stdio: 'inherit'
269
+ });
270
+ console.log(chalk.green('✅ Build completed successfully!'));
271
+ } catch (error) {
272
+ console.log(chalk.red('❌ Build failed'));
273
+ process.exit(1);
274
+ }
275
+ });
276
+
277
+ // Dev command - 开发模式启动
278
+ program
279
+ .command('dev')
280
+ .description('Start server in development mode')
281
+ .option('-p, --port <port>', 'Server port')
282
+ .action((options) => {
283
+ console.log(chalk.blue('🔄 Starting ReactPress Server in development mode...\n'));
284
+
285
+ // 调用start命令的dev模式
286
+ const args = ['start', '--dev'];
287
+ if (options.port) {
288
+ args.push('--port', options.port);
289
+ }
290
+
291
+ // 重新调用当前脚本
292
+ const child = require('child_process').spawn('node', [__filename, ...args], {
293
+ stdio: 'inherit',
294
+ env: process.env
295
+ });
296
+
297
+ child.on('exit', (code) => {
298
+ process.exit(code);
299
+ });
300
+ });
301
+
302
+ program.parse();
@@ -0,0 +1,2 @@
1
+ export declare class AppModule {
2
+ }