@fecommunity/reactpress 3.7.0 → 4.0.0-beta.0

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 (406) hide show
  1. package/bin/reactpress-cli-shim.js +2 -6
  2. package/bin/reactpress-theme-client.js +2 -0
  3. package/bin/reactpress.js +1 -380
  4. package/out/.source-fingerprint-cli +1 -0
  5. package/out/bin/reactpress-cli-shim.d.ts +3 -0
  6. package/out/bin/reactpress-cli-shim.d.ts.map +1 -0
  7. package/out/bin/reactpress-cli-shim.js +28 -0
  8. package/out/bin/reactpress-cli-shim.js.map +1 -0
  9. package/out/bin/reactpress-theme-client.d.ts +3 -0
  10. package/out/bin/reactpress-theme-client.d.ts.map +1 -0
  11. package/out/bin/reactpress-theme-client.js +113 -0
  12. package/out/bin/reactpress-theme-client.js.map +1 -0
  13. package/out/bin/reactpress.d.ts +3 -0
  14. package/out/bin/reactpress.d.ts.map +1 -0
  15. package/out/bin/reactpress.js +534 -0
  16. package/out/bin/reactpress.js.map +1 -0
  17. package/out/core/services/config.d.ts +12 -0
  18. package/out/core/services/config.d.ts.map +1 -0
  19. package/out/core/services/config.js +137 -0
  20. package/out/core/services/config.js.map +1 -0
  21. package/out/core/services/database/index.d.ts +17 -0
  22. package/out/core/services/database/index.d.ts.map +1 -0
  23. package/out/core/services/database/index.js +242 -0
  24. package/out/core/services/database/index.js.map +1 -0
  25. package/out/core/services/database/mysql.d.ts +14 -0
  26. package/out/core/services/database/mysql.d.ts.map +1 -0
  27. package/out/core/services/database/mysql.js +82 -0
  28. package/out/core/services/database/mysql.js.map +1 -0
  29. package/out/core/services/database/profile.d.ts +6 -0
  30. package/out/core/services/database/profile.d.ts.map +1 -0
  31. package/out/core/services/database/profile.js +60 -0
  32. package/out/core/services/database/profile.js.map +1 -0
  33. package/out/core/services/database/sqlite.d.ts +10 -0
  34. package/out/core/services/database/sqlite.d.ts.map +1 -0
  35. package/out/core/services/database/sqlite.js +73 -0
  36. package/out/core/services/database/sqlite.js.map +1 -0
  37. package/out/core/services/exec.d.ts +21 -0
  38. package/out/core/services/exec.d.ts.map +1 -0
  39. package/out/core/services/exec.js +56 -0
  40. package/out/core/services/exec.js.map +1 -0
  41. package/out/core/services/init.d.ts +11 -0
  42. package/out/core/services/init.d.ts.map +1 -0
  43. package/out/core/services/init.js +60 -0
  44. package/out/core/services/init.js.map +1 -0
  45. package/out/core/services/local-site.d.ts +24 -0
  46. package/out/core/services/local-site.d.ts.map +1 -0
  47. package/out/core/services/local-site.js +144 -0
  48. package/out/core/services/local-site.js.map +1 -0
  49. package/out/core/utils/cli-context.d.ts +3 -0
  50. package/out/core/utils/cli-context.d.ts.map +1 -0
  51. package/out/core/utils/cli-context.js +12 -0
  52. package/out/core/utils/cli-context.js.map +1 -0
  53. package/out/core/utils/paths.d.ts +20 -0
  54. package/out/core/utils/paths.d.ts.map +1 -0
  55. package/out/core/utils/paths.js +34 -0
  56. package/out/core/utils/paths.js.map +1 -0
  57. package/out/core/utils/platform.d.ts +7 -0
  58. package/out/core/utils/platform.d.ts.map +1 -0
  59. package/out/core/utils/platform.js +28 -0
  60. package/out/core/utils/platform.js.map +1 -0
  61. package/out/core/utils/port.d.ts +4 -0
  62. package/out/core/utils/port.d.ts.map +1 -0
  63. package/out/core/utils/port.js +32 -0
  64. package/out/core/utils/port.js.map +1 -0
  65. package/out/lib/api-dev-runner.d.ts +3 -0
  66. package/out/lib/api-dev-runner.d.ts.map +1 -0
  67. package/{lib → out/lib}/api-dev-runner.js +4 -1
  68. package/out/lib/api-dev-runner.js.map +1 -0
  69. package/out/lib/api-dev.d.ts +2 -0
  70. package/out/lib/api-dev.d.ts.map +1 -0
  71. package/out/lib/api-dev.js +101 -0
  72. package/out/lib/api-dev.js.map +1 -0
  73. package/out/lib/bootstrap.d.ts +18 -0
  74. package/out/lib/bootstrap.d.ts.map +1 -0
  75. package/out/lib/bootstrap.js +93 -0
  76. package/out/lib/bootstrap.js.map +1 -0
  77. package/out/lib/build.d.ts +2 -0
  78. package/out/lib/build.d.ts.map +1 -0
  79. package/out/lib/build.js +191 -0
  80. package/out/lib/build.js.map +1 -0
  81. package/out/lib/db-backup.d.ts +2 -0
  82. package/out/lib/db-backup.d.ts.map +1 -0
  83. package/out/lib/db-backup.js +68 -0
  84. package/out/lib/db-backup.js.map +1 -0
  85. package/out/lib/dev-banner.d.ts +2 -0
  86. package/out/lib/dev-banner.d.ts.map +1 -0
  87. package/out/lib/dev-banner.js +102 -0
  88. package/out/lib/dev-banner.js.map +1 -0
  89. package/out/lib/dev-child-io.d.ts +2 -0
  90. package/out/lib/dev-child-io.d.ts.map +1 -0
  91. package/out/lib/dev-child-io.js +80 -0
  92. package/out/lib/dev-child-io.js.map +1 -0
  93. package/out/lib/dev-log.d.ts +2 -0
  94. package/out/lib/dev-log.d.ts.map +1 -0
  95. package/out/lib/dev-log.js +64 -0
  96. package/out/lib/dev-log.js.map +1 -0
  97. package/out/lib/dev-session.d.ts +2 -0
  98. package/out/lib/dev-session.d.ts.map +1 -0
  99. package/out/lib/dev-session.js +95 -0
  100. package/out/lib/dev-session.js.map +1 -0
  101. package/out/lib/dev.d.ts +2 -0
  102. package/out/lib/dev.d.ts.map +1 -0
  103. package/out/lib/dev.js +906 -0
  104. package/out/lib/dev.js.map +1 -0
  105. package/out/lib/docker.d.ts +2 -0
  106. package/out/lib/docker.d.ts.map +1 -0
  107. package/out/lib/docker.js +398 -0
  108. package/out/lib/docker.js.map +1 -0
  109. package/out/lib/doctor.d.ts +2 -0
  110. package/out/lib/doctor.d.ts.map +1 -0
  111. package/out/lib/doctor.js +260 -0
  112. package/out/lib/doctor.js.map +1 -0
  113. package/out/lib/health-parse.d.ts +5 -0
  114. package/out/lib/health-parse.d.ts.map +1 -0
  115. package/out/lib/health-parse.js +36 -0
  116. package/out/lib/health-parse.js.map +1 -0
  117. package/out/lib/health-parse.test.d.ts +2 -0
  118. package/out/lib/health-parse.test.d.ts.map +1 -0
  119. package/out/lib/health-parse.test.js +19 -0
  120. package/out/lib/health-parse.test.js.map +1 -0
  121. package/out/lib/http.d.ts +2 -0
  122. package/out/lib/http.d.ts.map +1 -0
  123. package/out/lib/http.js +234 -0
  124. package/out/lib/http.js.map +1 -0
  125. package/out/lib/i18n/index.d.ts +2 -0
  126. package/out/lib/i18n/index.d.ts.map +1 -0
  127. package/out/lib/i18n/index.js +29 -0
  128. package/out/lib/i18n/index.js.map +1 -0
  129. package/out/lib/i18n/strings.d.ts +2 -0
  130. package/out/lib/i18n/strings.d.ts.map +1 -0
  131. package/out/lib/i18n/strings.js +1140 -0
  132. package/out/lib/i18n/strings.js.map +1 -0
  133. package/out/lib/lifecycle.d.ts +2 -0
  134. package/out/lib/lifecycle.d.ts.map +1 -0
  135. package/out/lib/lifecycle.js +169 -0
  136. package/out/lib/lifecycle.js.map +1 -0
  137. package/out/lib/nginx.d.ts +2 -0
  138. package/out/lib/nginx.d.ts.map +1 -0
  139. package/out/lib/nginx.js +618 -0
  140. package/out/lib/nginx.js.map +1 -0
  141. package/out/lib/paths.d.ts +2 -0
  142. package/out/lib/paths.d.ts.map +1 -0
  143. package/out/lib/paths.js +106 -0
  144. package/out/lib/paths.js.map +1 -0
  145. package/out/lib/plugin-build.d.ts +2 -0
  146. package/out/lib/plugin-build.d.ts.map +1 -0
  147. package/out/lib/plugin-build.js +104 -0
  148. package/out/lib/plugin-build.js.map +1 -0
  149. package/out/lib/plugin-cli.d.ts +2 -0
  150. package/out/lib/plugin-cli.d.ts.map +1 -0
  151. package/out/lib/plugin-cli.js +142 -0
  152. package/out/lib/plugin-cli.js.map +1 -0
  153. package/out/lib/pm2.d.ts +2 -0
  154. package/out/lib/pm2.d.ts.map +1 -0
  155. package/out/lib/pm2.js +32 -0
  156. package/out/lib/pm2.js.map +1 -0
  157. package/out/lib/ports.d.ts +2 -0
  158. package/out/lib/ports.d.ts.map +1 -0
  159. package/out/lib/ports.js +394 -0
  160. package/out/lib/ports.js.map +1 -0
  161. package/out/lib/process.d.ts +2 -0
  162. package/out/lib/process.d.ts.map +1 -0
  163. package/out/lib/process.js +47 -0
  164. package/out/lib/process.js.map +1 -0
  165. package/out/lib/prod-memory.d.ts +6 -0
  166. package/out/lib/prod-memory.d.ts.map +1 -0
  167. package/out/lib/prod-memory.js +57 -0
  168. package/out/lib/prod-memory.js.map +1 -0
  169. package/out/lib/project-type.d.ts +2 -0
  170. package/out/lib/project-type.d.ts.map +1 -0
  171. package/out/lib/project-type.js +77 -0
  172. package/out/lib/project-type.js.map +1 -0
  173. package/out/lib/publish.d.ts +3 -0
  174. package/out/lib/publish.d.ts.map +1 -0
  175. package/out/lib/publish.js +388 -0
  176. package/out/lib/publish.js.map +1 -0
  177. package/out/lib/remote-dev.d.ts +2 -0
  178. package/out/lib/remote-dev.d.ts.map +1 -0
  179. package/out/lib/remote-dev.js +158 -0
  180. package/out/lib/remote-dev.js.map +1 -0
  181. package/out/lib/root.d.ts +2 -0
  182. package/out/lib/root.d.ts.map +1 -0
  183. package/out/lib/root.js +85 -0
  184. package/out/lib/root.js.map +1 -0
  185. package/out/lib/spawn.d.ts +2 -0
  186. package/out/lib/spawn.d.ts.map +1 -0
  187. package/out/lib/spawn.js +96 -0
  188. package/out/lib/spawn.js.map +1 -0
  189. package/out/lib/status.d.ts +2 -0
  190. package/out/lib/status.d.ts.map +1 -0
  191. package/out/lib/status.js +78 -0
  192. package/out/lib/status.js.map +1 -0
  193. package/out/lib/theme-catalog.d.ts +2 -0
  194. package/out/lib/theme-catalog.d.ts.map +1 -0
  195. package/out/lib/theme-catalog.js +6 -0
  196. package/out/lib/theme-catalog.js.map +1 -0
  197. package/out/lib/theme-cli.d.ts +2 -0
  198. package/out/lib/theme-cli.d.ts.map +1 -0
  199. package/out/lib/theme-cli.js +50 -0
  200. package/out/lib/theme-cli.js.map +1 -0
  201. package/out/lib/theme-dev.d.ts +2 -0
  202. package/out/lib/theme-dev.d.ts.map +1 -0
  203. package/out/lib/theme-dev.js +759 -0
  204. package/out/lib/theme-dev.js.map +1 -0
  205. package/out/lib/theme-env.d.ts +2 -0
  206. package/out/lib/theme-env.d.ts.map +1 -0
  207. package/out/lib/theme-env.js +101 -0
  208. package/out/lib/theme-env.js.map +1 -0
  209. package/out/lib/theme-install.d.ts +2 -0
  210. package/out/lib/theme-install.d.ts.map +1 -0
  211. package/out/lib/theme-install.js +363 -0
  212. package/out/lib/theme-install.js.map +1 -0
  213. package/out/lib/theme-lock.d.ts +2 -0
  214. package/out/lib/theme-lock.d.ts.map +1 -0
  215. package/out/lib/theme-lock.js +70 -0
  216. package/out/lib/theme-lock.js.map +1 -0
  217. package/out/lib/theme-paths.d.ts +2 -0
  218. package/out/lib/theme-paths.d.ts.map +1 -0
  219. package/out/lib/theme-paths.js +73 -0
  220. package/out/lib/theme-paths.js.map +1 -0
  221. package/out/lib/theme-placeholder-cover.d.ts +13 -0
  222. package/out/lib/theme-placeholder-cover.d.ts.map +1 -0
  223. package/out/lib/theme-placeholder-cover.js +95 -0
  224. package/out/lib/theme-placeholder-cover.js.map +1 -0
  225. package/out/lib/theme-preview-frame.d.ts +2 -0
  226. package/out/lib/theme-preview-frame.d.ts.map +1 -0
  227. package/out/lib/theme-preview-frame.js +107 -0
  228. package/out/lib/theme-preview-frame.js.map +1 -0
  229. package/out/lib/theme-preview-pool.d.ts +2 -0
  230. package/out/lib/theme-preview-pool.d.ts.map +1 -0
  231. package/out/lib/theme-preview-pool.js +484 -0
  232. package/out/lib/theme-preview-pool.js.map +1 -0
  233. package/out/lib/theme-preview-proxy.d.ts +2 -0
  234. package/out/lib/theme-preview-proxy.d.ts.map +1 -0
  235. package/out/lib/theme-preview-proxy.js +101 -0
  236. package/out/lib/theme-preview-proxy.js.map +1 -0
  237. package/out/lib/theme-prod.d.ts +2 -0
  238. package/out/lib/theme-prod.d.ts.map +1 -0
  239. package/out/lib/theme-prod.js +400 -0
  240. package/out/lib/theme-prod.js.map +1 -0
  241. package/out/lib/theme-registry.d.ts +2 -0
  242. package/out/lib/theme-registry.d.ts.map +1 -0
  243. package/out/lib/theme-registry.js +135 -0
  244. package/out/lib/theme-registry.js.map +1 -0
  245. package/out/lib/theme-runtime.d.ts +2 -0
  246. package/out/lib/theme-runtime.d.ts.map +1 -0
  247. package/out/lib/theme-runtime.js +344 -0
  248. package/out/lib/theme-runtime.js.map +1 -0
  249. package/out/lib/theme-sources.d.ts +2 -0
  250. package/out/lib/theme-sources.d.ts.map +1 -0
  251. package/out/lib/theme-sources.js +347 -0
  252. package/out/lib/theme-sources.js.map +1 -0
  253. package/out/lib/theme-warmup.d.ts +2 -0
  254. package/out/lib/theme-warmup.d.ts.map +1 -0
  255. package/out/lib/theme-warmup.js +167 -0
  256. package/out/lib/theme-warmup.js.map +1 -0
  257. package/out/lib/toolkit-build.d.ts +2 -0
  258. package/out/lib/toolkit-build.d.ts.map +1 -0
  259. package/out/lib/toolkit-build.js +57 -0
  260. package/out/lib/toolkit-build.js.map +1 -0
  261. package/out/types/config.d.ts +57 -0
  262. package/out/types/config.d.ts.map +1 -0
  263. package/out/types/config.js +3 -0
  264. package/out/types/config.js.map +1 -0
  265. package/out/ui/banner.d.ts +2 -0
  266. package/out/ui/banner.d.ts.map +1 -0
  267. package/out/ui/banner.js +358 -0
  268. package/out/ui/banner.js.map +1 -0
  269. package/out/ui/interactive.d.ts +2 -0
  270. package/out/ui/interactive.d.ts.map +1 -0
  271. package/out/ui/interactive.js +328 -0
  272. package/out/ui/interactive.js.map +1 -0
  273. package/out/ui/theme.d.ts +2 -0
  274. package/out/ui/theme.d.ts.map +1 -0
  275. package/out/ui/theme.js +250 -0
  276. package/out/ui/theme.js.map +1 -0
  277. package/package.json +13 -7
  278. package/server/dist/common/api-messages.d.ts +9 -0
  279. package/server/dist/common/api-messages.js +9 -0
  280. package/server/dist/common/api-messages.js.map +1 -1
  281. package/server/dist/database/typeorm-options.d.ts +3 -0
  282. package/server/dist/database/typeorm-options.js +60 -0
  283. package/server/dist/database/typeorm-options.js.map +1 -0
  284. package/server/dist/modules/api-key/api-key.controller.js.map +1 -1
  285. package/server/dist/modules/api-key/api-key.entity.js.map +1 -1
  286. package/server/dist/modules/api-key/api-key.guard.js +2 -3
  287. package/server/dist/modules/api-key/api-key.guard.js.map +1 -1
  288. package/server/dist/modules/api-key/api-key.module.js.map +1 -1
  289. package/server/dist/modules/api-key/api-key.service.js +1 -1
  290. package/server/dist/modules/api-key/api-key.service.js.map +1 -1
  291. package/server/dist/modules/article/article-revision.entity.js +3 -3
  292. package/server/dist/modules/article/article-revision.entity.js.map +1 -1
  293. package/server/dist/modules/article/article-slug.util.d.ts +2 -0
  294. package/server/dist/modules/article/article-slug.util.js +19 -0
  295. package/server/dist/modules/article/article-slug.util.js.map +1 -0
  296. package/server/dist/modules/article/scheduled-publish.service.js.map +1 -1
  297. package/server/dist/modules/bootstrap/bootstrap.constants.d.ts +20 -0
  298. package/server/dist/modules/bootstrap/bootstrap.constants.js +171 -0
  299. package/server/dist/modules/bootstrap/bootstrap.constants.js.map +1 -0
  300. package/server/dist/modules/bootstrap/bootstrap.service.d.ts +22 -0
  301. package/server/dist/modules/bootstrap/bootstrap.service.js +183 -0
  302. package/server/dist/modules/bootstrap/bootstrap.service.js.map +1 -0
  303. package/server/dist/modules/bootstrap/install-locale.d.ts +2 -0
  304. package/server/dist/modules/bootstrap/install-locale.js +11 -0
  305. package/server/dist/modules/bootstrap/install-locale.js.map +1 -0
  306. package/server/dist/modules/extension/extension.module.d.ts +9 -0
  307. package/server/dist/modules/extension/extension.module.js +50 -0
  308. package/server/dist/modules/extension/extension.module.js.map +1 -0
  309. package/server/dist/modules/extension/plugin-loader.service.d.ts +12 -0
  310. package/server/dist/modules/extension/plugin-loader.service.js +96 -0
  311. package/server/dist/modules/extension/plugin-loader.service.js.map +1 -0
  312. package/server/dist/modules/extension/plugin-registry.bridge.d.ts +3 -0
  313. package/server/dist/modules/extension/plugin-registry.bridge.js +44 -0
  314. package/server/dist/modules/extension/plugin-registry.bridge.js.map +1 -0
  315. package/server/dist/modules/extension/plugin.controller.d.ts +22 -0
  316. package/server/dist/modules/extension/plugin.controller.js +155 -0
  317. package/server/dist/modules/extension/plugin.controller.js.map +1 -0
  318. package/server/dist/modules/extension/plugin.service.d.ts +52 -0
  319. package/server/dist/modules/extension/plugin.service.js +391 -0
  320. package/server/dist/modules/extension/plugin.service.js.map +1 -0
  321. package/server/dist/modules/extension/preview-draft.store.d.ts +13 -0
  322. package/server/dist/modules/extension/preview-draft.store.js +41 -0
  323. package/server/dist/modules/extension/preview-draft.store.js.map +1 -0
  324. package/server/dist/modules/extension/theme-registry.bridge.d.ts +56 -0
  325. package/server/dist/modules/extension/theme-registry.bridge.js +46 -0
  326. package/server/dist/modules/extension/theme-registry.bridge.js.map +1 -0
  327. package/server/dist/modules/extension/theme.controller.d.ts +66 -0
  328. package/server/dist/modules/extension/theme.controller.js +301 -0
  329. package/server/dist/modules/extension/theme.controller.js.map +1 -0
  330. package/server/dist/modules/extension/theme.service.d.ts +140 -0
  331. package/server/dist/modules/extension/theme.service.js +1039 -0
  332. package/server/dist/modules/extension/theme.service.js.map +1 -0
  333. package/server/dist/modules/file/file-optimization.controller.d.ts +12 -0
  334. package/server/dist/modules/file/file-optimization.controller.js +79 -0
  335. package/server/dist/modules/file/file-optimization.controller.js.map +1 -0
  336. package/server/dist/modules/file/file-optimization.service.d.ts +36 -0
  337. package/server/dist/modules/file/file-optimization.service.js +385 -0
  338. package/server/dist/modules/file/file-optimization.service.js.map +1 -0
  339. package/server/dist/modules/file/file-optimization.types.d.ts +66 -0
  340. package/server/dist/modules/file/file-optimization.types.js +5 -0
  341. package/server/dist/modules/file/file-optimization.types.js.map +1 -0
  342. package/server/dist/modules/file/image-optimizer-plugin.guard.d.ts +7 -0
  343. package/server/dist/modules/file/image-optimizer-plugin.guard.js +33 -0
  344. package/server/dist/modules/file/image-optimizer-plugin.guard.js.map +1 -0
  345. package/server/dist/modules/health/health.controller.js +2 -4
  346. package/server/dist/modules/health/health.controller.js.map +1 -1
  347. package/server/dist/modules/health/health.module.js.map +1 -1
  348. package/server/dist/modules/hook/hook.module.d.ts +2 -0
  349. package/server/dist/modules/hook/hook.module.js +22 -0
  350. package/server/dist/modules/hook/hook.module.js.map +1 -0
  351. package/server/dist/modules/hook/hook.service.d.ts +26 -0
  352. package/server/dist/modules/hook/hook.service.js +105 -0
  353. package/server/dist/modules/hook/hook.service.js.map +1 -0
  354. package/server/dist/modules/webhook/webhook.controller.js.map +1 -1
  355. package/server/dist/modules/webhook/webhook.entity.js.map +1 -1
  356. package/server/dist/modules/webhook/webhook.module.js.map +1 -1
  357. package/server/dist/modules/webhook/webhook.service.d.ts +1 -1
  358. package/server/dist/modules/webhook/webhook.service.js +5 -2
  359. package/server/dist/modules/webhook/webhook.service.js.map +1 -1
  360. package/server/dist/public/uploads/2026-05-30/QR3X4UZQ93ZTUPGXCFA9II..png +0 -0
  361. package/server/dist/public/uploads/2026-05-31/BXQV3NX9ZVWHGNOSX9AXD8.webp +0 -0
  362. package/server/dist/public/uploads/2026-05-31/BXQV3NX9ZVWHGNOSX9AXD8_medium.webp +0 -0
  363. package/server/dist/public/uploads/2026-05-31/BXQV3NX9ZVWHGNOSX9AXD8_thumb.webp +0 -0
  364. package/server/dist/public/uploads/2026-05-31/I2SZC0ONA7CF31UM46MN56..jpg +0 -0
  365. package/server/dist/tsconfig.tsbuildinfo +1 -0
  366. package/server/dist/utils/image-processor.util.d.ts +23 -0
  367. package/server/dist/utils/image-processor.util.js +88 -0
  368. package/server/dist/utils/image-processor.util.js.map +1 -0
  369. package/server/dist/utils/local-api-quiet.util.d.ts +1 -0
  370. package/server/dist/utils/local-api-quiet.util.js +8 -0
  371. package/server/dist/utils/local-api-quiet.util.js.map +1 -0
  372. package/server/dist/utils/project-root.util.d.ts +2 -0
  373. package/server/dist/utils/project-root.util.js +42 -0
  374. package/server/dist/utils/project-root.util.js.map +1 -0
  375. package/server/public/uploads/2026-05-30/QR3X4UZQ93ZTUPGXCFA9II..png +0 -0
  376. package/server/public/uploads/2026-05-31/BXQV3NX9ZVWHGNOSX9AXD8.webp +0 -0
  377. package/server/public/uploads/2026-05-31/BXQV3NX9ZVWHGNOSX9AXD8_medium.webp +0 -0
  378. package/server/public/uploads/2026-05-31/BXQV3NX9ZVWHGNOSX9AXD8_thumb.webp +0 -0
  379. package/server/public/uploads/2026-05-31/I2SZC0ONA7CF31UM46MN56..jpg +0 -0
  380. package/templates/config.local.json +13 -0
  381. package/templates/env.local.default +10 -0
  382. package/templates/theme-catalog.json +27 -0
  383. package/lib/api-dev.js +0 -89
  384. package/lib/bootstrap.js +0 -114
  385. package/lib/build.js +0 -162
  386. package/lib/db-backup.js +0 -67
  387. package/lib/dev-banner.js +0 -72
  388. package/lib/dev.js +0 -141
  389. package/lib/docker.js +0 -275
  390. package/lib/doctor.js +0 -266
  391. package/lib/http.js +0 -182
  392. package/lib/i18n/index.js +0 -32
  393. package/lib/i18n/strings.js +0 -846
  394. package/lib/lifecycle.js +0 -190
  395. package/lib/nginx.js +0 -342
  396. package/lib/paths.js +0 -108
  397. package/lib/pm2.js +0 -32
  398. package/lib/process.js +0 -45
  399. package/lib/project-type.js +0 -72
  400. package/lib/publish.js +0 -968
  401. package/lib/root.js +0 -88
  402. package/lib/spawn.js +0 -92
  403. package/lib/status.js +0 -132
  404. package/ui/banner.js +0 -441
  405. package/ui/interactive.js +0 -380
  406. package/ui/theme.js +0 -265
package/out/lib/dev.js ADDED
@@ -0,0 +1,906 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // @ts-nocheck
4
+ const { spawn, spawnSync } = require('child_process');
5
+ const { spawnDevChild } = require('./dev-child-io');
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+ const ora = require('ora');
9
+ const { runBuild } = require('./build');
10
+ const { ensureProjectEnvironment } = require('./bootstrap');
11
+ const { loadWebAdminUrl, loadClientSiteUrl, loadServerSiteUrl, getHealthUrl, checkHealth, waitForHttp, } = require('./http');
12
+ const { printDevReadyBanner } = require('./dev-banner');
13
+ const { startDevNginx, stopDevNginx, nginxEntryUrl } = require('./nginx');
14
+ const { ensureOriginalCwd, isMonorepoCheckout } = require('./root');
15
+ const { detectProjectType, hasWeb, hasToolkit } = require('./project-type');
16
+ const { hasResolvableActiveTheme, hasThemePackages, readActiveThemeManifest, resolveThemeDirectory, } = require('./theme-runtime');
17
+ const { shouldBuildToolkit } = require('./toolkit-build');
18
+ const { buildLocalPlugins } = require('./plugin-build');
19
+ const { startThemeSiteWithWatch, stopThemeSite } = require('./theme-dev');
20
+ const { scheduleBackgroundThemeBuilds } = require('./theme-prod');
21
+ const { shouldBlockOnThemeWarmup, warmupThemeDevRoutes, warmupThemeDevRoutesInBackground, } = require('./theme-warmup');
22
+ const { DEV_PORTS, ensureApiPortFree, ensurePortFree, readEnvPort, isPortListening } = require('./ports');
23
+ const { ensureDevDatabase, probeMysqlHost } = require('./docker');
24
+ const { acquireDevSession, releaseDevSession } = require('./dev-session');
25
+ const { checkNodeVersion, checkDocker } = require('./doctor');
26
+ const { startDevTimer, markDevPhase, isDevVerbose, logDevLine, logDevDetail, logDevStatus, logDevTimingSummary, } = require('./dev-log');
27
+ const { t } = require('./i18n');
28
+ const { resolveRemoteThemeApiBase, readDevClientApiOrigin, normalizeRemoteOrigin, } = require('./remote-dev');
29
+ const CLIENT_READY_TIMEOUT_MS = 120_000;
30
+ const API_READY_TIMEOUT_MS = 180_000;
31
+ const DEV_POLL_MS = 250;
32
+ const DEV_POLL_FAST_MS = 150;
33
+ function shouldWaitForThemeInForeground() {
34
+ if (process.env.REACTPRESS_DESKTOP_LOCAL === '1')
35
+ return true;
36
+ return process.env.REACTPRESS_DEV_WAIT_THEME === '1';
37
+ }
38
+ function logDevPhase(step, total, messageKey, vars = {}) {
39
+ console.log('');
40
+ console.log(`[reactpress] [${step}/${total}] ${t(messageKey, vars)}`);
41
+ }
42
+ function isDesktopLocalMode() {
43
+ return process.env.REACTPRESS_DESKTOP_LOCAL === '1';
44
+ }
45
+ function isLocalSqliteMode() {
46
+ return process.env.REACTPRESS_LOCAL_MODE === '1' || isDesktopLocalMode();
47
+ }
48
+ function desktopPhaseKey(defaultKey) {
49
+ if (!isDesktopLocalMode())
50
+ return defaultKey;
51
+ const map = {
52
+ 'dev.phasePrerequisites': 'dev.phasePrerequisitesDesktop',
53
+ 'dev.phaseInfra': 'dev.phaseInfraDesktop',
54
+ 'dev.phaseServices': 'dev.phaseServicesDesktop',
55
+ };
56
+ return map[defaultKey] || defaultKey;
57
+ }
58
+ function formatDevFailureHint() {
59
+ return [
60
+ t('dev.nextSteps'),
61
+ t('dev.nextDoctor'),
62
+ t('dev.nextDocker'),
63
+ t('dev.nextEnv'),
64
+ ].join('\n');
65
+ }
66
+ let apiChild;
67
+ let webChild;
68
+ let desktopChild;
69
+ let shuttingDown = false;
70
+ let nginxEnabled = false;
71
+ /** When false, admin/API child exit during startup must not tear down the stack. */
72
+ let devServicesReady = false;
73
+ function shutdown(signal = 'SIGINT') {
74
+ if (shuttingDown)
75
+ return;
76
+ shuttingDown = true;
77
+ stopThemeSite();
78
+ if (nginxEnabled)
79
+ stopDevNginx(ensureOriginalCwd());
80
+ const stopEmbeddedApi = signal === 'SIGINT' || devServicesReady || !isDesktopLocalMode();
81
+ if (stopEmbeddedApi) {
82
+ try {
83
+ const { stopLocalServer } = require(path.join(ensureOriginalCwd(), 'desktop/out/main/local-server.js'));
84
+ stopLocalServer();
85
+ }
86
+ catch {
87
+ // desktop local API not running
88
+ }
89
+ }
90
+ if (desktopChild && !desktopChild.killed)
91
+ desktopChild.kill(signal);
92
+ if (webChild && !webChild.killed)
93
+ webChild.kill(signal);
94
+ if (apiChild && !apiChild.killed)
95
+ apiChild.kill(signal);
96
+ try {
97
+ releaseDevSession(ensureOriginalCwd());
98
+ }
99
+ catch {
100
+ // ignore
101
+ }
102
+ }
103
+ async function buildToolkit(projectRoot) {
104
+ if (!hasToolkit(projectRoot))
105
+ return;
106
+ if (!shouldBuildToolkit(projectRoot)) {
107
+ logDevDetail('dev.toolkitUpToDate');
108
+ }
109
+ else {
110
+ await runBuild('toolkit', projectRoot);
111
+ }
112
+ try {
113
+ buildLocalPlugins(projectRoot);
114
+ }
115
+ catch (err) {
116
+ console.error(`[reactpress] ${err.message || err}`);
117
+ throw err;
118
+ }
119
+ }
120
+ async function spawnApi(projectRoot) {
121
+ const { reused, port: apiPort } = await ensureApiPortFree(projectRoot, { allowReuse: true });
122
+ if (reused) {
123
+ logDevStatus('dev.apiReusing', { port: apiPort });
124
+ return { reused: true, port: apiPort };
125
+ }
126
+ const apiDevRunner = path.join(__dirname, 'api-dev-runner.js');
127
+ logDevStatus('dev.startingApi');
128
+ apiChild = spawn(process.execPath, [apiDevRunner], {
129
+ stdio: 'inherit',
130
+ cwd: projectRoot,
131
+ env: {
132
+ ...process.env,
133
+ REACTPRESS_ORIGINAL_CWD: projectRoot,
134
+ REACTPRESS_DEV_SESSION_PID: String(process.pid),
135
+ REACTPRESS_DEV_DB_READY: '1',
136
+ REACTPRESS_DEV_PORTS_READY: '1',
137
+ },
138
+ });
139
+ apiChild.on('close', (code) => {
140
+ if (shuttingDown) {
141
+ process.exit(code ?? 0);
142
+ return;
143
+ }
144
+ if (webChild && !webChild.killed)
145
+ webChild.kill('SIGINT');
146
+ process.exit(code ?? 1);
147
+ });
148
+ return { reused: false, port: apiPort };
149
+ }
150
+ async function waitForApiReady(projectRoot, { readyMessageKey = 'dev.apiReady', alreadyHealthy = false } = {}) {
151
+ const healthUrl = getHealthUrl(projectRoot);
152
+ const apiPort = readEnvPort(projectRoot, 'SERVER_PORT', DEV_PORTS.API);
153
+ if (alreadyHealthy) {
154
+ const health = await checkHealth(healthUrl, 2000);
155
+ if (health.ok) {
156
+ logDevStatus(readyMessageKey);
157
+ return;
158
+ }
159
+ }
160
+ const useSpinner = isDevVerbose() && process.stdout.isTTY;
161
+ const spinner = useSpinner
162
+ ? ora({
163
+ text: t('dev.waitingApi', { url: healthUrl }),
164
+ color: 'magenta',
165
+ spinner: 'dots',
166
+ }).start()
167
+ : null;
168
+ if (!useSpinner)
169
+ logDevStatus('dev.waitingApiQuiet');
170
+ const deadline = Date.now() + API_READY_TIMEOUT_MS;
171
+ let lastHint = '';
172
+ while (Date.now() < deadline) {
173
+ if (!isPortListening(apiPort)) {
174
+ lastHint = t('dev.waitingApiCompile', { port: apiPort });
175
+ if (spinner) {
176
+ spinner.text = `${t('dev.waitingApi', { url: healthUrl })} — ${lastHint}`;
177
+ }
178
+ await new Promise((r) => setTimeout(r, DEV_POLL_MS));
179
+ continue;
180
+ }
181
+ const health = await checkHealth(healthUrl, 2500);
182
+ if (health.ok) {
183
+ if (spinner)
184
+ spinner.succeed(t(readyMessageKey));
185
+ else
186
+ logDevStatus(readyMessageKey);
187
+ return;
188
+ }
189
+ if (health.data?.database === 'down') {
190
+ lastHint = t('dev.healthDbDown');
191
+ }
192
+ else if (health.statusCode === 200 && health.data?.status === 'degraded') {
193
+ lastHint = t('dev.healthDegraded');
194
+ }
195
+ else if (health.statusCode === 0) {
196
+ lastHint = t('dev.waitingApiStarting');
197
+ }
198
+ else if (health.statusCode > 0) {
199
+ lastHint = `HTTP ${health.statusCode}`;
200
+ }
201
+ if (spinner && lastHint) {
202
+ spinner.text = `${t('dev.waitingApi', { url: healthUrl })} — ${lastHint}`;
203
+ }
204
+ await new Promise((r) => setTimeout(r, DEV_POLL_FAST_MS));
205
+ }
206
+ if (spinner)
207
+ spinner.fail(t('dev.apiTimeout', { seconds: API_READY_TIMEOUT_MS / 1000 }));
208
+ else
209
+ console.error(t('dev.apiTimeout', { seconds: API_READY_TIMEOUT_MS / 1000 }));
210
+ shutdown('SIGINT');
211
+ process.exit(1);
212
+ }
213
+ function handlePrimaryDevChildClose(code, label = 'dev', projectRoot = ensureOriginalCwd()) {
214
+ if (!devServicesReady) {
215
+ console.warn(`[reactpress] ${label} process exited during startup (code ${code ?? 'unknown'}) — waiting for services…`);
216
+ return;
217
+ }
218
+ const adminPort = readEnvPort(projectRoot, 'WEB_ADMIN_PORT', DEV_PORTS.ADMIN_WEB);
219
+ if (isDesktopLocalMode() && label === 'Admin dev') {
220
+ return;
221
+ }
222
+ if (label === 'Admin dev' && isPortListening(adminPort)) {
223
+ return;
224
+ }
225
+ if (!shuttingDown)
226
+ shutdown('SIGINT');
227
+ process.exit(code ?? 0);
228
+ }
229
+ async function spawnAdminWeb(projectRoot, { behindNginx = false, integratedStack = false, adminApiOrigin = null, waitForReady = true, } = {}) {
230
+ const adminPort = readEnvPort(projectRoot, 'WEB_ADMIN_PORT', DEV_PORTS.ADMIN_WEB);
231
+ await ensurePortFree(adminPort, { label: 'admin' });
232
+ logDevDetail('dev.startingAdmin', { url: loadWebAdminUrl(projectRoot) });
233
+ const adminEnv = {
234
+ ...process.env,
235
+ REACTPRESS_ORIGINAL_CWD: projectRoot,
236
+ WEB_ADMIN_PORT: String(adminPort),
237
+ };
238
+ if (nginxEnabled && process.env.REACTPRESS_NGINX_ENTRY_URL) {
239
+ adminEnv.REACTPRESS_NGINX_ENTRY_URL = process.env.REACTPRESS_NGINX_ENTRY_URL;
240
+ }
241
+ else {
242
+ adminEnv.REACTPRESS_SKIP_DEV_PORT_REDIRECT = '1';
243
+ }
244
+ if (behindNginx) {
245
+ adminEnv.VITE_ADMIN_BASE = '/admin/';
246
+ process.env.REACTPRESS_BEHIND_NGINX = '1';
247
+ }
248
+ // Full stack (API + theme site): theme install/activate must hit Nest, not MSW.
249
+ if (integratedStack || adminApiOrigin) {
250
+ adminEnv.VITE_ENABLE_MOCK = 'false';
251
+ adminEnv.VITE_AUTH_MODE = 'server';
252
+ if (adminApiOrigin) {
253
+ // Vite proxies `/api` → `${target}/api/...`; target is host-only origin.
254
+ adminEnv.VITE_DEV_API_PROXY_TARGET = normalizeRemoteOrigin(adminApiOrigin) || adminApiOrigin;
255
+ }
256
+ else if (isDesktopLocalMode() && process.env.REACTPRESS_DESKTOP_LOCAL_API) {
257
+ // Desktop dev embeds SQLite API on a dedicated port (default :13102), not :3002.
258
+ adminEnv.VITE_DEV_API_PROXY_TARGET = process.env.REACTPRESS_DESKTOP_LOCAL_API.replace(/\/api\/?$/, '');
259
+ }
260
+ else {
261
+ adminEnv.VITE_DEV_API_PROXY_TARGET = loadServerSiteUrl(projectRoot).replace(/\/$/, '');
262
+ }
263
+ }
264
+ webChild = isDesktopLocalMode()
265
+ ? spawn(process.platform === 'win32' ? 'pnpm.cmd' : 'pnpm', ['exec', 'vp', 'dev'], {
266
+ cwd: path.join(projectRoot, 'web'),
267
+ env: adminEnv,
268
+ stdio: 'inherit',
269
+ shell: process.platform === 'win32',
270
+ })
271
+ : spawnDevChild('pnpm', ['run', '--dir', './web', 'dev'], {
272
+ shell: true,
273
+ cwd: projectRoot,
274
+ env: adminEnv,
275
+ });
276
+ webChild.on('close', (code) => {
277
+ handlePrimaryDevChildClose(code, 'Admin dev', projectRoot);
278
+ });
279
+ if (!waitForReady)
280
+ return Promise.resolve(true);
281
+ const readyUrl = loadWebAdminUrl(projectRoot);
282
+ return waitForHttp(readyUrl, CLIENT_READY_TIMEOUT_MS, DEV_POLL_MS).then((ready) => {
283
+ if (!ready) {
284
+ console.warn(t('dev.adminSlow', {
285
+ seconds: CLIENT_READY_TIMEOUT_MS / 1000,
286
+ url: readyUrl,
287
+ }));
288
+ }
289
+ return ready;
290
+ });
291
+ }
292
+ function assertDevPrerequisites() {
293
+ const node = checkNodeVersion();
294
+ if (!node.ok) {
295
+ console.error(`[reactpress] ${node.message}`);
296
+ if (node.fix)
297
+ console.error(` → ${node.fix}`);
298
+ console.error(formatDevFailureHint());
299
+ process.exit(1);
300
+ }
301
+ if (!isLocalSqliteMode()) {
302
+ const docker = checkDocker();
303
+ if (!docker.ok) {
304
+ console.error(`[reactpress] ${docker.message}`);
305
+ if (docker.fix)
306
+ console.error(` → ${docker.fix}`);
307
+ console.error(formatDevFailureHint());
308
+ process.exit(1);
309
+ }
310
+ }
311
+ logDevStatus(isDesktopLocalMode() ? 'dev.prerequisitesOkDesktop' : 'dev.prerequisitesOk', { version: process.version });
312
+ }
313
+ async function prepareDevInfrastructure(projectRoot, { needsLocalApi = true } = {}) {
314
+ await acquireDevSession(projectRoot);
315
+ if (isLocalSqliteMode()) {
316
+ if (process.env.REACTPRESS_LOCAL_MODE === '1') {
317
+ const { ensureLocalSite } = require('../core/services/local-site');
318
+ const { ensureSqliteDatabase } = require('../core/services/database/sqlite');
319
+ const { getMonorepoRoot } = require('./root');
320
+ const port = readEnvPort(projectRoot, 'SERVER_PORT', DEV_PORTS.API);
321
+ ensureLocalSite(projectRoot, port, { monorepoRoot: getMonorepoRoot() });
322
+ const sqliteResult = await ensureSqliteDatabase(projectRoot);
323
+ if (!sqliteResult.ok) {
324
+ throw new Error(sqliteResult.message || 'SQLite 数据库未就绪');
325
+ }
326
+ }
327
+ nginxEnabled = false;
328
+ delete process.env.REACTPRESS_NGINX_ENTRY_URL;
329
+ process.env.REACTPRESS_SKIP_DEV_PORT_REDIRECT = '1';
330
+ return;
331
+ }
332
+ const planNginx = process.env.REACTPRESS_SKIP_NGINX !== '1';
333
+ const clientApiOrigin = readDevClientApiOrigin(projectRoot);
334
+ const [, nginxResult] = await Promise.all([
335
+ needsLocalApi ? ensureDevDatabase(projectRoot, { quiet: true }) : Promise.resolve(true),
336
+ planNginx ? startDevNginx(projectRoot) : Promise.resolve(false),
337
+ ]);
338
+ nginxEnabled = nginxResult;
339
+ if (nginxEnabled) {
340
+ process.env.REACTPRESS_NGINX_ENTRY_URL = nginxEntryUrl(projectRoot);
341
+ delete process.env.REACTPRESS_SKIP_DEV_PORT_REDIRECT;
342
+ if (clientApiOrigin) {
343
+ logDevStatus('dev.nginxReadyRemote', {
344
+ url: nginxEntryUrl(projectRoot),
345
+ api: clientApiOrigin,
346
+ });
347
+ }
348
+ else {
349
+ logDevStatus('dev.nginxReady', { url: nginxEntryUrl(projectRoot) });
350
+ }
351
+ }
352
+ else {
353
+ delete process.env.REACTPRESS_NGINX_ENTRY_URL;
354
+ process.env.REACTPRESS_SKIP_DEV_PORT_REDIRECT = '1';
355
+ }
356
+ }
357
+ async function startDevStack(projectRoot, { webOnly = false, themeOnly = false, desktopMode = false, localWebMode = false, infraDone = false, apiOrigins = { admin: null, client: null, needsLocalApi: true }, } = {}) {
358
+ const { admin: adminApiOrigin, client: clientApiOrigin, needsLocalApi } = apiOrigins;
359
+ if (!infraDone) {
360
+ logDevPhase(1, 3, desktopPhaseKey('dev.phasePrerequisites'));
361
+ assertDevPrerequisites();
362
+ logDevPhase(2, 3, desktopPhaseKey('dev.phaseInfra'));
363
+ try {
364
+ await prepareDevInfrastructure(projectRoot, { needsLocalApi });
365
+ }
366
+ catch (err) {
367
+ console.error(t('dev.dbEnsureFailed', { message: err.message || err }));
368
+ console.error(formatDevFailureHint());
369
+ process.exit(1);
370
+ }
371
+ }
372
+ else if (needsLocalApi && !(await probeMysqlHost(projectRoot))) {
373
+ console.error(t('dev.dbEnsureFailed', {
374
+ message: t('docker.devStartBlocked', {
375
+ port: readEnvPort(projectRoot, 'DB_PORT', DEV_PORTS.MYSQL),
376
+ }),
377
+ }));
378
+ console.error(formatDevFailureHint());
379
+ process.exit(1);
380
+ }
381
+ const includeAdmin = webOnly && hasWeb(projectRoot);
382
+ // Always run theme watchers when packages exist — admin activate/preview writes manifests
383
+ // and relies on fs.watch even if the current active theme is not yet resolvable.
384
+ const includeThemeSite = themeOnly ||
385
+ (desktopMode && hasThemePackages(projectRoot)) ||
386
+ (!webOnly && hasThemePackages(projectRoot));
387
+ if (!webOnly && !themeOnly && includeThemeSite && !hasResolvableActiveTheme(projectRoot)) {
388
+ const { activeTheme } = readActiveThemeManifest(projectRoot);
389
+ console.warn(`[reactpress] ${t('themeDev.notFound', { id: activeTheme })} — ${t('dev.themeSiteSkipped')}`);
390
+ }
391
+ if (includeThemeSite) {
392
+ const { validateBundledThemes, validateCatalogThemes } = require('./theme-registry');
393
+ const bundled = validateBundledThemes(projectRoot);
394
+ if (bundled.missing.length) {
395
+ console.warn(`[reactpress] themes/package.json lists bundled theme(s) without theme.json: ${bundled.missing.join(', ')}`);
396
+ }
397
+ const catalog = validateCatalogThemes(projectRoot);
398
+ if (catalog.missing.length) {
399
+ console.warn(`[reactpress] themes/package.json lists catalog dir(s) without reactpress.theme in package.json: ${catalog.missing.join(', ')}`);
400
+ }
401
+ }
402
+ const planNginx = process.env.REACTPRESS_SKIP_NGINX !== '1';
403
+ const includeWebInStack = hasWeb(projectRoot) && !webOnly && !themeOnly;
404
+ if (infraDone) {
405
+ logDevPhase(3, 3, localWebMode ? 'dev.phaseServicesLocalWeb' : desktopPhaseKey('dev.phaseServices'));
406
+ }
407
+ markDevPhase('services');
408
+ const readinessWaits = [];
409
+ let apiSpawn = null;
410
+ const prewarmPreviewBuilds = includeThemeSite &&
411
+ isDesktopLocalMode() &&
412
+ process.env.REACTPRESS_SKIP_PREVIEW_BUILD !== '1';
413
+ if (prewarmPreviewBuilds) {
414
+ const { warmupAllPreviewThemeBuilds } = require('./theme-prod');
415
+ logDevStatus('dev.previewPrewarmStarting');
416
+ readinessWaits.push(warmupAllPreviewThemeBuilds(projectRoot));
417
+ }
418
+ if (adminApiOrigin || clientApiOrigin) {
419
+ if (adminApiOrigin) {
420
+ logDevStatus('dev.adminApiRemote', { url: adminApiOrigin });
421
+ }
422
+ if (clientApiOrigin) {
423
+ logDevStatus('dev.clientApiRemote', { url: clientApiOrigin });
424
+ }
425
+ }
426
+ if (needsLocalApi) {
427
+ logDevStatus('dev.phaseApi');
428
+ apiSpawn = await spawnApi(projectRoot);
429
+ const readyMessageKey = webOnly || hasWeb(projectRoot) ? 'dev.apiReadyAdmin' : 'dev.apiReady';
430
+ readinessWaits.push(waitForApiReady(projectRoot, {
431
+ readyMessageKey,
432
+ alreadyHealthy: Boolean(apiSpawn?.reused),
433
+ }));
434
+ }
435
+ if (!includeAdmin && !includeThemeSite && !includeWebInStack) {
436
+ await Promise.all(readinessWaits);
437
+ printDevReadyBanner(projectRoot, { apiOnly: true, nginx: nginxEnabled });
438
+ console.log(t('dev.standaloneHint'));
439
+ return;
440
+ }
441
+ const waitThemeInForeground = includeThemeSite && shouldWaitForThemeInForeground();
442
+ let themeSiteStarted = false;
443
+ if (includeWebInStack) {
444
+ logDevDetail('dev.phaseAdmin');
445
+ if (planNginx)
446
+ process.env.REACTPRESS_BEHIND_NGINX = '1';
447
+ logDevDetail('dev.startingAdmin', { url: loadWebAdminUrl(projectRoot) });
448
+ spawnAdminWeb(projectRoot, {
449
+ behindNginx: planNginx,
450
+ integratedStack: true,
451
+ adminApiOrigin,
452
+ waitForReady: false,
453
+ });
454
+ const adminBase = loadWebAdminUrl(projectRoot).replace(/\/$/, '');
455
+ const adminProbe = planNginx ? `${adminBase}/admin/` : `${adminBase}/`;
456
+ readinessWaits.push(waitForHttp(adminProbe, 120_000, DEV_POLL_MS));
457
+ }
458
+ else if (includeAdmin) {
459
+ logDevDetail('dev.phaseAdmin');
460
+ spawnAdminWeb(projectRoot, {
461
+ behindNginx: desktopMode || localWebMode ? false : planNginx,
462
+ integratedStack: desktopMode || localWebMode || isLocalSqliteMode(),
463
+ adminApiOrigin,
464
+ waitForReady: false,
465
+ });
466
+ const adminBase = loadWebAdminUrl(projectRoot).replace(/\/$/, '');
467
+ const adminProbe = planNginx ? `${adminBase}/admin/` : `${adminBase}/`;
468
+ readinessWaits.push(waitForHttp(adminProbe, 120_000, DEV_POLL_MS));
469
+ }
470
+ if (includeThemeSite) {
471
+ const { activeTheme } = readActiveThemeManifest(projectRoot);
472
+ logDevStatus('dev.themeStarting', {
473
+ id: activeTheme,
474
+ port: readEnvPort(projectRoot, 'CLIENT_PORT', DEV_PORTS.VISITOR),
475
+ });
476
+ if (planNginx)
477
+ process.env.REACTPRESS_BEHIND_NGINX = '1';
478
+ if (clientApiOrigin) {
479
+ delete process.env.REACTPRESS_DEV_FORCE_LOCAL_THEME_API;
480
+ const themeApiBase = resolveRemoteThemeApiBase(clientApiOrigin);
481
+ process.env.REACTPRESS_THEME_API_URL = themeApiBase;
482
+ process.env.REACTPRESS_THEME_PUBLIC_API_URL = planNginx
483
+ ? `${nginxEntryUrl(projectRoot).replace(/\/$/, '')}/api`
484
+ : themeApiBase;
485
+ const themeDir = resolveThemeDirectory(projectRoot, activeTheme);
486
+ if (themeDir) {
487
+ const nextCache = path.join(themeDir, '.next');
488
+ if (fs.existsSync(nextCache)) {
489
+ fs.rmSync(nextCache, { recursive: true, force: true });
490
+ logDevDetail('dev.themeCacheClearedForRemote');
491
+ }
492
+ }
493
+ }
494
+ else {
495
+ process.env.REACTPRESS_DEV_FORCE_LOCAL_THEME_API = '1';
496
+ }
497
+ const themeBoot = startThemeSiteWithWatch(projectRoot);
498
+ const themeWait = themeBoot.then(async (started) => {
499
+ themeSiteStarted = started;
500
+ if (!started)
501
+ return false;
502
+ const clientUrl = loadClientSiteUrl(projectRoot);
503
+ const port = readEnvPort(projectRoot, 'CLIENT_PORT', DEV_PORTS.VISITOR);
504
+ const portOpen = await (async () => {
505
+ const deadline = Date.now() + 120_000;
506
+ while (Date.now() < deadline) {
507
+ if (isPortListening(port))
508
+ return true;
509
+ await new Promise((r) => setTimeout(r, DEV_POLL_MS));
510
+ }
511
+ return false;
512
+ })();
513
+ if (portOpen) {
514
+ if (isDesktopLocalMode()) {
515
+ const { warmupThemeHomepage } = require('./theme-warmup');
516
+ await warmupThemeHomepage(projectRoot, clientUrl);
517
+ }
518
+ else if (shouldBlockOnThemeWarmup()) {
519
+ await warmupThemeDevRoutes(projectRoot);
520
+ }
521
+ else {
522
+ warmupThemeDevRoutesInBackground(projectRoot);
523
+ }
524
+ }
525
+ return portOpen;
526
+ });
527
+ if (waitThemeInForeground) {
528
+ readinessWaits.push(themeWait);
529
+ }
530
+ else {
531
+ themeWait.then((ready) => {
532
+ if (ready)
533
+ logDevDetail('dev.themeReadyQuiet', { url: loadClientSiteUrl(projectRoot) });
534
+ });
535
+ }
536
+ }
537
+ if (readinessWaits.length > 1) {
538
+ logDevStatus('dev.waitingProxies');
539
+ }
540
+ await Promise.all(readinessWaits);
541
+ if (readinessWaits.length > 1) {
542
+ logDevStatus('dev.proxiesReady');
543
+ }
544
+ if (includeWebInStack && planNginx && nginxEnabled) {
545
+ const adminViaNginx = `${nginxEntryUrl(projectRoot).replace(/\/$/, '')}/admin/`;
546
+ waitForHttp(adminViaNginx, 15_000, DEV_POLL_MS).then((adminOk) => {
547
+ if (!adminOk) {
548
+ console.warn(t('dev.adminNginxSlow', { url: adminViaNginx }));
549
+ }
550
+ });
551
+ }
552
+ else if (planNginx && !nginxEnabled) {
553
+ startDevNginx(projectRoot).then((enabled) => {
554
+ nginxEnabled = enabled;
555
+ if (enabled) {
556
+ console.log(t('dev.nginxReady', { url: nginxEntryUrl(projectRoot) }));
557
+ }
558
+ });
559
+ }
560
+ const dbOk = isDesktopLocalMode()
561
+ ? true
562
+ : needsLocalApi
563
+ ? await probeMysqlHost(projectRoot)
564
+ : true;
565
+ if (needsLocalApi && !dbOk && !isDesktopLocalMode()) {
566
+ console.warn(t('dev.mysqlUnreachable'));
567
+ }
568
+ if (includeThemeSite && process.env.REACTPRESS_SKIP_PREVIEW_BUILD !== '1' && !prewarmPreviewBuilds) {
569
+ const { activeTheme } = readActiveThemeManifest(projectRoot);
570
+ scheduleBackgroundThemeBuilds(projectRoot, { excludeThemeId: activeTheme });
571
+ }
572
+ printDevReadyBanner(projectRoot, {
573
+ webOnly: (includeAdmin && !includeThemeSite) || localWebMode,
574
+ desktop: desktopMode && !localWebMode,
575
+ localWeb: localWebMode,
576
+ nginx: nginxEnabled,
577
+ hasThemeSite: includeThemeSite,
578
+ dbOk,
579
+ adminApiOrigin,
580
+ clientApiOrigin,
581
+ localApiUrl: isDesktopLocalMode() ? process.env.REACTPRESS_DESKTOP_LOCAL_API || null : null,
582
+ dbType: isDesktopLocalMode() ? 'sqlite' : needsLocalApi ? 'mysql' : null,
583
+ });
584
+ logDevTimingSummary({
585
+ apiReused: Boolean(apiSpawn?.reused),
586
+ });
587
+ devServicesReady = true;
588
+ }
589
+ async function runDevStartup(projectRoot, { webOnly = false, themeOnly = false, desktopMode = false, localWebMode = false, skipPrepareInfra = false, apiOrigins = { admin: null, client: null, needsLocalApi: true }, } = {}) {
590
+ startDevTimer();
591
+ try {
592
+ const result = await ensureProjectEnvironment(projectRoot, { skipDatabase: true });
593
+ if (result.message && isDevVerbose())
594
+ console.log(`[reactpress] ${result.message}`);
595
+ }
596
+ catch (err) {
597
+ console.error(t('dev.envFailed'), err.message || err);
598
+ console.error(formatDevFailureHint());
599
+ process.exit(1);
600
+ }
601
+ logDevPhase(1, 3, desktopPhaseKey('dev.phasePrerequisites'));
602
+ assertDevPrerequisites();
603
+ logDevPhase(2, 3, desktopPhaseKey('dev.phaseInfra'));
604
+ try {
605
+ const infraTasks = [buildToolkit(projectRoot)];
606
+ if (!skipPrepareInfra) {
607
+ infraTasks.unshift(prepareDevInfrastructure(projectRoot, { needsLocalApi: apiOrigins.needsLocalApi }));
608
+ }
609
+ await Promise.all(infraTasks);
610
+ markDevPhase('infra');
611
+ }
612
+ catch (err) {
613
+ console.error(t('dev.dbEnsureFailed', { message: err.message || err }));
614
+ console.error(formatDevFailureHint());
615
+ process.exit(1);
616
+ }
617
+ await startDevStack(projectRoot, {
618
+ webOnly,
619
+ themeOnly,
620
+ desktopMode,
621
+ localWebMode,
622
+ infraDone: true,
623
+ apiOrigins,
624
+ });
625
+ }
626
+ function ensureDesktopBuilt(projectRoot) {
627
+ const localServerJs = path.join(projectRoot, 'desktop/out/main/local-server.js');
628
+ if (fs.existsSync(localServerJs))
629
+ return;
630
+ const buildResult = spawnSync('pnpm', ['run', '--dir', './desktop', 'build'], {
631
+ cwd: projectRoot,
632
+ shell: true,
633
+ stdio: 'inherit',
634
+ env: {
635
+ ...process.env,
636
+ REACTPRESS_ORIGINAL_CWD: projectRoot,
637
+ },
638
+ });
639
+ if (buildResult.status !== 0) {
640
+ process.exit(buildResult.status ?? 1);
641
+ }
642
+ }
643
+ async function startDesktopLocalApi(projectRoot, { forceRestart = false } = {}) {
644
+ const desktopDir = path.join(projectRoot, 'desktop');
645
+ if (!fs.existsSync(path.join(desktopDir, 'package.json'))) {
646
+ console.error(`[reactpress] ${t('dev.desktopMissing')}`);
647
+ process.exit(1);
648
+ }
649
+ ensureDesktopBuilt(projectRoot);
650
+ const localServerPath = path.join(projectRoot, 'desktop/out/main/local-server.js');
651
+ const { startLocalServer, resolveDevSiteRoot, getLocalApiBaseUrl, stopLocalServer, DEFAULT_LOCAL_API_PORT, } = require(localServerPath);
652
+ if (forceRestart) {
653
+ try {
654
+ stopLocalServer();
655
+ }
656
+ catch {
657
+ // ignore
658
+ }
659
+ const { killPortListeners, isPortListening } = require('./ports');
660
+ const localApiPort = DEFAULT_LOCAL_API_PORT || 13102;
661
+ if (isPortListening(localApiPort)) {
662
+ killPortListeners(localApiPort, 'TERM');
663
+ await new Promise((r) => setTimeout(r, 400));
664
+ if (isPortListening(localApiPort)) {
665
+ killPortListeners(localApiPort, 'KILL');
666
+ await new Promise((r) => setTimeout(r, 200));
667
+ }
668
+ }
669
+ }
670
+ console.log('');
671
+ logDevStatus('dev.desktopLocalApiStarting');
672
+ const siteRoot = resolveDevSiteRoot(projectRoot);
673
+ await startLocalServer({ siteRoot, monorepoRoot: projectRoot, forceRestart });
674
+ const localApiBase = getLocalApiBaseUrl();
675
+ process.env.REACTPRESS_DESKTOP_LOCAL_API = localApiBase;
676
+ process.env.REACTPRESS_DESKTOP_SITE_ROOT = siteRoot;
677
+ process.env.REACTPRESS_THEME_API_URL = localApiBase;
678
+ process.env.REACTPRESS_THEME_PUBLIC_API_URL = localApiBase;
679
+ const localApiOrigin = localApiBase.replace(/\/api\/?$/, '');
680
+ process.env.VITE_DEV_API_PROXY_TARGET = localApiOrigin;
681
+ logDevStatus('dev.desktopLocalApiReady', { url: localApiBase, db: t('dev.dbTypeSqlite') });
682
+ return { siteRoot, localApiBase };
683
+ }
684
+ async function ensureDesktopLocalApiHealthy(projectRoot, { forceRestart = false } = {}) {
685
+ if (!isDesktopLocalMode())
686
+ return true;
687
+ const base = process.env.REACTPRESS_DESKTOP_LOCAL_API?.trim();
688
+ if (!base)
689
+ return false;
690
+ const healthUrl = `${base.replace(/\/api\/?$/, '')}/api/health`;
691
+ const health = await checkHealth(healthUrl, 2500);
692
+ if (health.ok && !forceRestart)
693
+ return true;
694
+ console.warn('[reactpress] Local API unreachable — restarting embedded SQLite API…');
695
+ await startDesktopLocalApi(projectRoot, { forceRestart: true });
696
+ const retry = await checkHealth(healthUrl, 5000);
697
+ if (!retry.ok) {
698
+ console.warn(`[reactpress] Local API still unhealthy after restart (${healthUrl})`);
699
+ }
700
+ return retry.ok;
701
+ }
702
+ function registerDevShutdownHandlers(projectRoot) {
703
+ process.on('SIGINT', () => shutdown('SIGINT'));
704
+ process.on('SIGTERM', () => {
705
+ // Stray SIGTERM during local web boot must not tear down the embedded API (Vite still starting).
706
+ if (!devServicesReady && isDesktopLocalMode())
707
+ return;
708
+ shutdown('SIGTERM');
709
+ });
710
+ process.on('exit', () => {
711
+ try {
712
+ releaseDevSession(projectRoot);
713
+ }
714
+ catch {
715
+ // ignore
716
+ }
717
+ });
718
+ }
719
+ /** Block until the primary dev child exits (admin Vite, Electron shell, or Nest API). */
720
+ function waitUntilDevChildExit(projectRoot = ensureOriginalCwd()) {
721
+ return new Promise((resolve) => {
722
+ const adminPort = readEnvPort(projectRoot, 'WEB_ADMIN_PORT', DEV_PORTS.ADMIN_WEB);
723
+ const waitForShutdownSignal = () => {
724
+ const onSignal = () => resolve(0);
725
+ process.once('SIGINT', onSignal);
726
+ process.once('SIGTERM', onSignal);
727
+ };
728
+ const child = webChild || desktopChild || apiChild;
729
+ if (!child) {
730
+ waitForShutdownSignal();
731
+ return;
732
+ }
733
+ const finish = (code) => {
734
+ if (child === webChild && isPortListening(adminPort)) {
735
+ waitForShutdownSignal();
736
+ return;
737
+ }
738
+ resolve(code ?? 0);
739
+ };
740
+ if (child.exitCode != null) {
741
+ finish(child.exitCode);
742
+ return;
743
+ }
744
+ if (child.killed) {
745
+ finish(1);
746
+ return;
747
+ }
748
+ child.once('close', (code) => finish(code));
749
+ });
750
+ }
751
+ function canUseDesktopLocalStack(projectRoot) {
752
+ return (isMonorepoCheckout(projectRoot) &&
753
+ fs.existsSync(path.join(projectRoot, 'desktop', 'package.json')));
754
+ }
755
+ async function spawnDesktopApp(projectRoot) {
756
+ const desktopDir = path.join(projectRoot, 'desktop');
757
+ if (!fs.existsSync(path.join(desktopDir, 'package.json'))) {
758
+ console.error(`[reactpress] ${t('dev.desktopMissing')}`);
759
+ shutdown('SIGINT');
760
+ process.exit(1);
761
+ }
762
+ const adminUrl = loadWebAdminUrl(projectRoot).replace(/\/$/, '');
763
+ logDevStatus('dev.desktopStarting', { url: adminUrl });
764
+ ensureDesktopBuilt(projectRoot);
765
+ desktopChild = spawnDevChild('pnpm', ['exec', 'cross-env', `VITE_DEV_SERVER_URL=${adminUrl}`, 'ELECTRON_IS_DEV=1', 'pnpm', 'run', 'dev:shell'], {
766
+ shell: true,
767
+ cwd: desktopDir,
768
+ env: {
769
+ ...process.env,
770
+ REACTPRESS_ORIGINAL_CWD: projectRoot,
771
+ VITE_DEV_SERVER_URL: adminUrl,
772
+ ELECTRON_IS_DEV: '1',
773
+ },
774
+ });
775
+ desktopChild.on('close', (code) => {
776
+ handlePrimaryDevChildClose(code, 'Desktop shell');
777
+ });
778
+ }
779
+ async function runDesktopDev(projectRoot = ensureOriginalCwd()) {
780
+ if (!hasWeb(projectRoot)) {
781
+ console.error(t('dev.noWeb'));
782
+ process.exit(1);
783
+ }
784
+ process.env.REACTPRESS_SKIP_NGINX = '1';
785
+ process.env.REACTPRESS_DESKTOP_LOCAL = '1';
786
+ registerDevShutdownHandlers(projectRoot);
787
+ console.log('');
788
+ logDevLine('dev.desktopIntro');
789
+ await prepareDevInfrastructure(projectRoot, { needsLocalApi: false });
790
+ await startDesktopLocalApi(projectRoot, { forceRestart: true });
791
+ await runDevStartup(projectRoot, {
792
+ webOnly: true,
793
+ desktopMode: true,
794
+ skipPrepareInfra: true,
795
+ apiOrigins: { admin: null, client: null, needsLocalApi: false },
796
+ });
797
+ await spawnDesktopApp(projectRoot);
798
+ const exitCode = await waitUntilDevChildExit(projectRoot);
799
+ process.exit(exitCode);
800
+ }
801
+ async function runLocalWebDev(projectRoot = ensureOriginalCwd(), { apiOrigins = { admin: null, client: null, needsLocalApi: true } } = {}) {
802
+ if (!hasWeb(projectRoot)) {
803
+ console.error(t('dev.noWeb'));
804
+ process.exit(1);
805
+ }
806
+ registerDevShutdownHandlers(projectRoot);
807
+ if (canUseDesktopLocalStack(projectRoot)) {
808
+ delete process.env.REACTPRESS_LOCAL_MODE;
809
+ process.env.REACTPRESS_SKIP_NGINX = '1';
810
+ process.env.REACTPRESS_DESKTOP_LOCAL = '1';
811
+ console.log('');
812
+ logDevLine('dev.localWebIntro');
813
+ await prepareDevInfrastructure(projectRoot, { needsLocalApi: false });
814
+ await startDesktopLocalApi(projectRoot, { forceRestart: true });
815
+ await runDevStartup(projectRoot, {
816
+ webOnly: true,
817
+ desktopMode: true,
818
+ localWebMode: true,
819
+ skipPrepareInfra: true,
820
+ apiOrigins: { admin: null, client: null, needsLocalApi: false },
821
+ });
822
+ await ensureDesktopLocalApiHealthy(projectRoot);
823
+ await new Promise((resolve) => {
824
+ const interval = setInterval(() => {
825
+ void ensureDesktopLocalApiHealthy(projectRoot).catch(() => { });
826
+ }, 20_000);
827
+ const onStop = (signal) => {
828
+ clearInterval(interval);
829
+ shutdown(signal);
830
+ resolve(0);
831
+ };
832
+ process.once('SIGINT', () => onStop('SIGINT'));
833
+ process.once('SIGTERM', () => onStop('SIGTERM'));
834
+ });
835
+ process.exit(0);
836
+ return;
837
+ }
838
+ process.env.REACTPRESS_LOCAL_MODE = '1';
839
+ process.env.REACTPRESS_SKIP_NGINX = '1';
840
+ console.log('');
841
+ logDevLine('dev.localWebIntro');
842
+ await runDevStartup(projectRoot, { webOnly: true, apiOrigins });
843
+ }
844
+ async function runThemeDev(projectRoot = ensureOriginalCwd(), { apiOrigins = { admin: null, client: null, needsLocalApi: true } } = {}) {
845
+ if (!hasResolvableActiveTheme(projectRoot)) {
846
+ console.error(t('dev.themeSiteSkipped'));
847
+ process.exit(1);
848
+ }
849
+ process.env.REACTPRESS_THEME_DEV_ONLY = '1';
850
+ process.on('SIGINT', () => shutdown('SIGINT'));
851
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
852
+ process.on('exit', () => {
853
+ try {
854
+ releaseDevSession(projectRoot);
855
+ }
856
+ catch {
857
+ // ignore
858
+ }
859
+ });
860
+ await runDevStartup(projectRoot, { themeOnly: true, apiOrigins });
861
+ }
862
+ async function runWebDev(projectRoot = ensureOriginalCwd(), { apiOrigins = { admin: null, client: null, needsLocalApi: true } } = {}) {
863
+ if (!hasWeb(projectRoot)) {
864
+ console.error(t('dev.noWeb'));
865
+ process.exit(1);
866
+ }
867
+ process.on('SIGINT', () => shutdown('SIGINT'));
868
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
869
+ process.on('exit', () => {
870
+ try {
871
+ releaseDevSession(projectRoot);
872
+ }
873
+ catch {
874
+ // ignore
875
+ }
876
+ });
877
+ await runDevStartup(projectRoot, { webOnly: true, apiOrigins });
878
+ }
879
+ async function runDev(projectRoot = ensureOriginalCwd(), { apiOrigins = { admin: null, client: null, needsLocalApi: true } } = {}) {
880
+ process.on('SIGINT', () => shutdown('SIGINT'));
881
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
882
+ process.on('exit', () => {
883
+ try {
884
+ releaseDevSession(projectRoot);
885
+ }
886
+ catch {
887
+ // ignore
888
+ }
889
+ });
890
+ await runDevStartup(projectRoot, { apiOrigins });
891
+ }
892
+ module.exports = {
893
+ runDev,
894
+ runWebDev,
895
+ runLocalWebDev,
896
+ runThemeDev,
897
+ runDesktopDev,
898
+ runDevStartup,
899
+ buildToolkit,
900
+ assertDevPrerequisites,
901
+ prepareDevInfrastructure,
902
+ startDevStack,
903
+ detectProjectType,
904
+ nginxEntryUrl,
905
+ };
906
+ //# sourceMappingURL=dev.js.map