@fecommunity/reactpress 3.7.0 → 4.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 (413) 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 +566 -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 +914 -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 +1192 -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 +95 -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 +378 -0
  272. package/out/ui/interactive.js.map +1 -0
  273. package/out/ui/prompts.d.ts +2 -0
  274. package/out/ui/prompts.d.ts.map +1 -0
  275. package/out/ui/prompts.js +91 -0
  276. package/out/ui/prompts.js.map +1 -0
  277. package/out/ui/theme.d.ts +2 -0
  278. package/out/ui/theme.d.ts.map +1 -0
  279. package/out/ui/theme.js +250 -0
  280. package/out/ui/theme.js.map +1 -0
  281. package/package.json +13 -7
  282. package/server/dist/common/api-messages.d.ts +9 -0
  283. package/server/dist/common/api-messages.js +9 -0
  284. package/server/dist/common/api-messages.js.map +1 -1
  285. package/server/dist/database/typeorm-options.d.ts +3 -0
  286. package/server/dist/database/typeorm-options.js +60 -0
  287. package/server/dist/database/typeorm-options.js.map +1 -0
  288. package/server/dist/modules/api-key/api-key.controller.js.map +1 -1
  289. package/server/dist/modules/api-key/api-key.entity.js.map +1 -1
  290. package/server/dist/modules/api-key/api-key.guard.js +2 -3
  291. package/server/dist/modules/api-key/api-key.guard.js.map +1 -1
  292. package/server/dist/modules/api-key/api-key.module.js.map +1 -1
  293. package/server/dist/modules/api-key/api-key.service.js +1 -1
  294. package/server/dist/modules/api-key/api-key.service.js.map +1 -1
  295. package/server/dist/modules/article/article-revision.entity.js +3 -3
  296. package/server/dist/modules/article/article-revision.entity.js.map +1 -1
  297. package/server/dist/modules/article/article-slug.util.d.ts +2 -0
  298. package/server/dist/modules/article/article-slug.util.js +19 -0
  299. package/server/dist/modules/article/article-slug.util.js.map +1 -0
  300. package/server/dist/modules/article/scheduled-publish.service.js.map +1 -1
  301. package/server/dist/modules/bootstrap/bootstrap.constants.d.ts +20 -0
  302. package/server/dist/modules/bootstrap/bootstrap.constants.js +171 -0
  303. package/server/dist/modules/bootstrap/bootstrap.constants.js.map +1 -0
  304. package/server/dist/modules/bootstrap/bootstrap.service.d.ts +22 -0
  305. package/server/dist/modules/bootstrap/bootstrap.service.js +183 -0
  306. package/server/dist/modules/bootstrap/bootstrap.service.js.map +1 -0
  307. package/server/dist/modules/bootstrap/install-locale.d.ts +2 -0
  308. package/server/dist/modules/bootstrap/install-locale.js +11 -0
  309. package/server/dist/modules/bootstrap/install-locale.js.map +1 -0
  310. package/server/dist/modules/extension/extension.module.d.ts +9 -0
  311. package/server/dist/modules/extension/extension.module.js +50 -0
  312. package/server/dist/modules/extension/extension.module.js.map +1 -0
  313. package/server/dist/modules/extension/plugin-loader.service.d.ts +12 -0
  314. package/server/dist/modules/extension/plugin-loader.service.js +96 -0
  315. package/server/dist/modules/extension/plugin-loader.service.js.map +1 -0
  316. package/server/dist/modules/extension/plugin-registry.bridge.d.ts +3 -0
  317. package/server/dist/modules/extension/plugin-registry.bridge.js +44 -0
  318. package/server/dist/modules/extension/plugin-registry.bridge.js.map +1 -0
  319. package/server/dist/modules/extension/plugin.controller.d.ts +22 -0
  320. package/server/dist/modules/extension/plugin.controller.js +155 -0
  321. package/server/dist/modules/extension/plugin.controller.js.map +1 -0
  322. package/server/dist/modules/extension/plugin.service.d.ts +52 -0
  323. package/server/dist/modules/extension/plugin.service.js +391 -0
  324. package/server/dist/modules/extension/plugin.service.js.map +1 -0
  325. package/server/dist/modules/extension/preview-draft.store.d.ts +13 -0
  326. package/server/dist/modules/extension/preview-draft.store.js +41 -0
  327. package/server/dist/modules/extension/preview-draft.store.js.map +1 -0
  328. package/server/dist/modules/extension/theme-registry.bridge.d.ts +56 -0
  329. package/server/dist/modules/extension/theme-registry.bridge.js +46 -0
  330. package/server/dist/modules/extension/theme-registry.bridge.js.map +1 -0
  331. package/server/dist/modules/extension/theme.controller.d.ts +66 -0
  332. package/server/dist/modules/extension/theme.controller.js +301 -0
  333. package/server/dist/modules/extension/theme.controller.js.map +1 -0
  334. package/server/dist/modules/extension/theme.service.d.ts +140 -0
  335. package/server/dist/modules/extension/theme.service.js +1039 -0
  336. package/server/dist/modules/extension/theme.service.js.map +1 -0
  337. package/server/dist/modules/file/file-optimization.controller.d.ts +12 -0
  338. package/server/dist/modules/file/file-optimization.controller.js +79 -0
  339. package/server/dist/modules/file/file-optimization.controller.js.map +1 -0
  340. package/server/dist/modules/file/file-optimization.service.d.ts +36 -0
  341. package/server/dist/modules/file/file-optimization.service.js +385 -0
  342. package/server/dist/modules/file/file-optimization.service.js.map +1 -0
  343. package/server/dist/modules/file/file-optimization.types.d.ts +66 -0
  344. package/server/dist/modules/file/file-optimization.types.js +5 -0
  345. package/server/dist/modules/file/file-optimization.types.js.map +1 -0
  346. package/server/dist/modules/file/image-optimizer-plugin.guard.d.ts +7 -0
  347. package/server/dist/modules/file/image-optimizer-plugin.guard.js +33 -0
  348. package/server/dist/modules/file/image-optimizer-plugin.guard.js.map +1 -0
  349. package/server/dist/modules/health/health.controller.js +2 -4
  350. package/server/dist/modules/health/health.controller.js.map +1 -1
  351. package/server/dist/modules/health/health.module.js.map +1 -1
  352. package/server/dist/modules/hook/hook.module.d.ts +2 -0
  353. package/server/dist/modules/hook/hook.module.js +22 -0
  354. package/server/dist/modules/hook/hook.module.js.map +1 -0
  355. package/server/dist/modules/hook/hook.service.d.ts +26 -0
  356. package/server/dist/modules/hook/hook.service.js +105 -0
  357. package/server/dist/modules/hook/hook.service.js.map +1 -0
  358. package/server/dist/modules/webhook/webhook.controller.js.map +1 -1
  359. package/server/dist/modules/webhook/webhook.entity.js.map +1 -1
  360. package/server/dist/modules/webhook/webhook.module.js.map +1 -1
  361. package/server/dist/modules/webhook/webhook.service.d.ts +1 -1
  362. package/server/dist/modules/webhook/webhook.service.js +5 -2
  363. package/server/dist/modules/webhook/webhook.service.js.map +1 -1
  364. package/server/dist/node-polyfills.d.ts +18 -0
  365. package/server/dist/node-polyfills.js +24 -0
  366. package/server/dist/node-polyfills.js.map +1 -0
  367. package/server/dist/public/uploads/2026-05-30/QR3X4UZQ93ZTUPGXCFA9II..png +0 -0
  368. package/server/dist/public/uploads/2026-05-31/BXQV3NX9ZVWHGNOSX9AXD8.webp +0 -0
  369. package/server/dist/public/uploads/2026-05-31/BXQV3NX9ZVWHGNOSX9AXD8_medium.webp +0 -0
  370. package/server/dist/public/uploads/2026-05-31/BXQV3NX9ZVWHGNOSX9AXD8_thumb.webp +0 -0
  371. package/server/dist/public/uploads/2026-05-31/I2SZC0ONA7CF31UM46MN56..jpg +0 -0
  372. package/server/dist/tsconfig.tsbuildinfo +1 -0
  373. package/server/dist/utils/image-processor.util.d.ts +23 -0
  374. package/server/dist/utils/image-processor.util.js +88 -0
  375. package/server/dist/utils/image-processor.util.js.map +1 -0
  376. package/server/dist/utils/local-api-quiet.util.d.ts +1 -0
  377. package/server/dist/utils/local-api-quiet.util.js +8 -0
  378. package/server/dist/utils/local-api-quiet.util.js.map +1 -0
  379. package/server/dist/utils/project-root.util.d.ts +2 -0
  380. package/server/dist/utils/project-root.util.js +42 -0
  381. package/server/dist/utils/project-root.util.js.map +1 -0
  382. package/server/public/uploads/2026-05-30/QR3X4UZQ93ZTUPGXCFA9II..png +0 -0
  383. package/server/public/uploads/2026-05-31/BXQV3NX9ZVWHGNOSX9AXD8.webp +0 -0
  384. package/server/public/uploads/2026-05-31/BXQV3NX9ZVWHGNOSX9AXD8_medium.webp +0 -0
  385. package/server/public/uploads/2026-05-31/BXQV3NX9ZVWHGNOSX9AXD8_thumb.webp +0 -0
  386. package/server/public/uploads/2026-05-31/I2SZC0ONA7CF31UM46MN56..jpg +0 -0
  387. package/templates/config.local.json +13 -0
  388. package/templates/env.local.default +10 -0
  389. package/templates/theme-catalog.json +27 -0
  390. package/lib/api-dev.js +0 -89
  391. package/lib/bootstrap.js +0 -114
  392. package/lib/build.js +0 -162
  393. package/lib/db-backup.js +0 -67
  394. package/lib/dev-banner.js +0 -72
  395. package/lib/dev.js +0 -141
  396. package/lib/docker.js +0 -275
  397. package/lib/doctor.js +0 -266
  398. package/lib/http.js +0 -182
  399. package/lib/i18n/index.js +0 -32
  400. package/lib/i18n/strings.js +0 -846
  401. package/lib/lifecycle.js +0 -190
  402. package/lib/nginx.js +0 -342
  403. package/lib/paths.js +0 -108
  404. package/lib/pm2.js +0 -32
  405. package/lib/process.js +0 -45
  406. package/lib/project-type.js +0 -72
  407. package/lib/publish.js +0 -968
  408. package/lib/root.js +0 -88
  409. package/lib/spawn.js +0 -92
  410. package/lib/status.js +0 -132
  411. package/ui/banner.js +0 -441
  412. package/ui/interactive.js +0 -380
  413. package/ui/theme.js +0 -265
@@ -0,0 +1,759 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // @ts-nocheck
4
+ const { spawnSync } = require('child_process');
5
+ const { spawnDevChild } = require('./dev-child-io');
6
+ const path = require('path');
7
+ const fs = require('fs');
8
+ const { loadClientSiteUrl, loadServerSiteUrl, getApiPrefix, waitForHttpOk } = require('./http');
9
+ const { warmupThemeHomepage } = require('./theme-warmup');
10
+ const { nginxEntryUrl } = require('./nginx');
11
+ const { readActiveThemeManifest, readPreviewThemeManifest, resolveThemeDirectory, readManifestSignature, readPreviewManifestSignature, getPreviewThemePort, isThemePackageDir, isAllowedThemePort, themeWorkspaceRoot, listAvailableThemeIds, } = require('./theme-runtime');
12
+ const { isDevVerbose, logDevDetail, logDevLine } = require('./dev-log');
13
+ const { resolveProjectRoot } = require('./paths');
14
+ const { t } = require('./i18n');
15
+ const { ensurePreviewThemeRunning, stopAllPreviewPool, stopPreviewPoolTheme, isPreviewHomepageReady, getPreviewSiteUrlForPort, getPreviewProxyPort, ensurePreviewProxyRunning, resolvePreviewThemeLaunchPlan, spawnThemeProcess, withPreviewPortLock, setPreviewProxyTarget, isIntegratedDesktopDev, } = require('./theme-preview-pool');
16
+ const { enqueueThemeBuild, ensureThemeDependenciesInstalled } = require('./theme-prod');
17
+ let themeChild = null;
18
+ let themeWatchStop = null;
19
+ let runningSignature = null;
20
+ let trackedThemePid = null;
21
+ let restartChain = Promise.resolve();
22
+ let previewRunningSignature = null;
23
+ let previewRestartChain = Promise.resolve();
24
+ /** Drop `.next` only when it does not match the theme package React major (avoids wiping React 17 caches). */
25
+ function cleanStaleThemeDevCache(themeDir) {
26
+ if (process.env.REACTPRESS_KEEP_THEME_CACHE === '1')
27
+ return;
28
+ const nextDir = path.join(themeDir, '.next');
29
+ if (!fs.existsSync(nextDir))
30
+ return;
31
+ if (process.env.REACTPRESS_CLEAR_THEME_CACHE === '1') {
32
+ fs.rmSync(nextDir, { recursive: true, force: true });
33
+ logDevDetail('themeDev.cacheCleared');
34
+ return;
35
+ }
36
+ let expectedMajor = '17';
37
+ try {
38
+ const pkg = JSON.parse(fs.readFileSync(path.join(themeDir, 'package.json'), 'utf8'));
39
+ const reactDep = pkg.dependencies?.react || pkg.devDependencies?.react || '';
40
+ const match = String(reactDep).match(/(\d+)/);
41
+ if (match)
42
+ expectedMajor = match[1];
43
+ }
44
+ catch {
45
+ return;
46
+ }
47
+ try {
48
+ const marker = `react@${expectedMajor}`;
49
+ const result = spawnSync('grep', ['-rl', marker, nextDir], {
50
+ encoding: 'utf8',
51
+ maxBuffer: 1024 * 1024,
52
+ });
53
+ if (result.stdout?.trim())
54
+ return;
55
+ fs.rmSync(nextDir, { recursive: true, force: true });
56
+ logDevDetail('themeDev.cacheStaleCleared', { marker });
57
+ }
58
+ catch {
59
+ // ignore grep / rm failures
60
+ }
61
+ }
62
+ function getClientPort(projectRoot) {
63
+ try {
64
+ const url = new URL(loadClientSiteUrl(projectRoot));
65
+ const port = parseInt(url.port || '3001', 10);
66
+ if (isAllowedThemePort(port))
67
+ return String(port);
68
+ }
69
+ catch {
70
+ // fall through
71
+ }
72
+ return '3001';
73
+ }
74
+ function assertThemePort(port) {
75
+ const n = parseInt(port, 10);
76
+ if (!isAllowedThemePort(n)) {
77
+ throw new Error(`Refusing theme dev on protected port ${port}`);
78
+ }
79
+ return n;
80
+ }
81
+ function isPortListening(port) {
82
+ const result = spawnSync('lsof', [`-tiTCP:${port}`, '-sTCP:LISTEN'], { encoding: 'utf8' });
83
+ return result.status === 0 && Boolean(result.stdout?.trim());
84
+ }
85
+ function getProcessCwd(pid) {
86
+ const n = parseInt(pid, 10);
87
+ if (!Number.isFinite(n) || n <= 0)
88
+ return null;
89
+ const res = spawnSync('lsof', ['-p', String(n)], { encoding: 'utf8' });
90
+ if (res.status !== 0)
91
+ return null;
92
+ const line = res.stdout.split('\n').find((row) => row.includes(' cwd '));
93
+ if (!line)
94
+ return null;
95
+ const parts = line.trim().split(/\s+/);
96
+ return parts[parts.length - 1] || null;
97
+ }
98
+ function isUnderThemesDir(projectRoot, cwd) {
99
+ if (!cwd)
100
+ return false;
101
+ const themesRoot = path.join(path.resolve(projectRoot), 'themes');
102
+ const resolved = path.resolve(cwd);
103
+ return resolved === themesRoot || resolved.startsWith(`${themesRoot}${path.sep}`);
104
+ }
105
+ /** Child PIDs of `rootPid` (pnpm → next dev tree). */
106
+ function collectDescendantPids(rootPid) {
107
+ const root = parseInt(rootPid, 10);
108
+ if (!Number.isFinite(root) || root <= 0)
109
+ return [];
110
+ const out = [];
111
+ const queue = [String(root)];
112
+ const seen = new Set();
113
+ while (queue.length) {
114
+ const pid = queue.shift();
115
+ if (!pid || seen.has(pid))
116
+ continue;
117
+ seen.add(pid);
118
+ const children = spawnSync('pgrep', ['-P', pid], { encoding: 'utf8' });
119
+ if (children.status !== 0 || !children.stdout?.trim())
120
+ continue;
121
+ for (const child of children.stdout.trim().split(/\s+/)) {
122
+ if (!child || seen.has(child))
123
+ continue;
124
+ out.push(child);
125
+ queue.push(child);
126
+ }
127
+ }
128
+ return out;
129
+ }
130
+ function isPidSafeToSignal(pid) {
131
+ const n = parseInt(pid, 10);
132
+ if (!Number.isFinite(n) || n <= 1)
133
+ return false;
134
+ if (n === process.pid)
135
+ return false;
136
+ if (process.ppid && n === process.ppid)
137
+ return false;
138
+ return true;
139
+ }
140
+ /** LISTEN pids for this theme dev port (package cwd, themes/, or tracked child tree). */
141
+ function getThemeListenerPids(projectRoot, port) {
142
+ const result = spawnSync('lsof', [`-tiTCP:${port}`, '-sTCP:LISTEN'], { encoding: 'utf8' });
143
+ if (result.status !== 0 || !result.stdout?.trim())
144
+ return [];
145
+ const allowed = new Set();
146
+ if (trackedThemePid && isPidSafeToSignal(trackedThemePid)) {
147
+ allowed.add(String(trackedThemePid));
148
+ for (const child of collectDescendantPids(trackedThemePid)) {
149
+ if (isPidSafeToSignal(child))
150
+ allowed.add(child);
151
+ }
152
+ }
153
+ for (const pid of result.stdout.trim().split(/\s+/)) {
154
+ if (!isPidSafeToSignal(pid))
155
+ continue;
156
+ const cwd = getProcessCwd(pid);
157
+ if (cwd &&
158
+ (isThemePackageDir(projectRoot, cwd) || isUnderThemesDir(projectRoot, cwd))) {
159
+ allowed.add(pid);
160
+ for (const child of collectDescendantPids(pid)) {
161
+ if (isPidSafeToSignal(child))
162
+ allowed.add(child);
163
+ }
164
+ }
165
+ }
166
+ return [...allowed];
167
+ }
168
+ function signalPids(pids, signal) {
169
+ const flag = signal === 'KILL' ? '-9' : '-TERM';
170
+ for (const pid of pids) {
171
+ if (isPidSafeToSignal(pid)) {
172
+ spawnSync('kill', [flag, pid], { stdio: 'ignore' });
173
+ }
174
+ }
175
+ }
176
+ function killThemeListenersOnPort(projectRoot, port, signal = 'TERM') {
177
+ signalPids(getThemeListenerPids(projectRoot, port), signal);
178
+ }
179
+ function waitForPortFree(port, timeoutMs = 10_000) {
180
+ const start = Date.now();
181
+ return new Promise((resolve) => {
182
+ const tick = () => {
183
+ if (!isPortListening(port)) {
184
+ resolve(true);
185
+ return;
186
+ }
187
+ if (Date.now() - start >= timeoutMs) {
188
+ resolve(false);
189
+ return;
190
+ }
191
+ setTimeout(tick, 250);
192
+ };
193
+ tick();
194
+ });
195
+ }
196
+ async function releaseThemePort(projectRoot, port, { fast = false } = {}) {
197
+ stopActiveThemeProcess();
198
+ const maxAttempts = fast ? 3 : 4;
199
+ const waitSchedule = fast ? [1200, 800, 800] : [12_000, 6000, 6000, 6000];
200
+ for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
201
+ const signal = fast ? (attempt === 0 ? 'TERM' : 'KILL') : attempt < 2 ? 'TERM' : 'KILL';
202
+ killThemeListenersOnPort(projectRoot, port, signal);
203
+ if (trackedThemePid && isPidSafeToSignal(trackedThemePid)) {
204
+ const tree = [String(trackedThemePid), ...collectDescendantPids(trackedThemePid)];
205
+ signalPids(tree, signal);
206
+ }
207
+ const waitMs = waitSchedule[attempt] ?? 6000;
208
+ const freed = await waitForPortFree(port, waitMs);
209
+ if (freed) {
210
+ trackedThemePid = null;
211
+ return true;
212
+ }
213
+ }
214
+ trackedThemePid = null;
215
+ return false;
216
+ }
217
+ /** Optional theme-only API override (admin / Nest API stay on SERVER_SITE_URL). */
218
+ function readThemeApiOverride(projectRoot, envKey) {
219
+ const fromShell = process.env[envKey]?.trim();
220
+ if (fromShell)
221
+ return fromShell.replace(/\/$/, '');
222
+ const envPath = path.join(projectRoot, '.env');
223
+ try {
224
+ const content = fs.readFileSync(envPath, 'utf8');
225
+ const match = content.match(new RegExp(`^${envKey}=(.+)$`, 'm'));
226
+ if (match) {
227
+ const raw = match[1].trim().replace(/^['"]|['"]$/g, '');
228
+ if (raw)
229
+ return raw.replace(/\/$/, '');
230
+ }
231
+ }
232
+ catch {
233
+ // ignore
234
+ }
235
+ return null;
236
+ }
237
+ function useLocalThemeApiInDev() {
238
+ return process.env.REACTPRESS_DEV_FORCE_LOCAL_THEME_API === '1';
239
+ }
240
+ function buildLocalThemeApiUrl(projectRoot, { forBrowser = false } = {}) {
241
+ const desktopApi = process.env.REACTPRESS_DESKTOP_LOCAL_API?.trim().replace(/\/$/, '');
242
+ if (desktopApi) {
243
+ return desktopApi;
244
+ }
245
+ if (forBrowser && process.env.REACTPRESS_BEHIND_NGINX === '1') {
246
+ return `${nginxEntryUrl(projectRoot).replace(/\/$/, '')}/api`;
247
+ }
248
+ const server = loadServerSiteUrl(projectRoot).replace(/\/$/, '');
249
+ const prefix = getApiPrefix(projectRoot).replace(/\/$/, '') || '/api';
250
+ return `${server}${prefix.startsWith('/') ? prefix : `/${prefix}`}`;
251
+ }
252
+ /** Direct Nest API — used for Next.js SSR (runs before nginx is up). */
253
+ function buildThemeServerApiUrl(projectRoot) {
254
+ if (useLocalThemeApiInDev()) {
255
+ return buildLocalThemeApiUrl(projectRoot, { forBrowser: false });
256
+ }
257
+ const override = readThemeApiOverride(projectRoot, 'REACTPRESS_THEME_API_URL');
258
+ if (override)
259
+ return override;
260
+ return buildLocalThemeApiUrl(projectRoot);
261
+ }
262
+ /** Browser-facing API — nginx unified entry when behind proxy. */
263
+ function buildThemePublicApiUrl(projectRoot) {
264
+ if (useLocalThemeApiInDev()) {
265
+ return buildLocalThemeApiUrl(projectRoot, { forBrowser: true });
266
+ }
267
+ const publicOverride = readThemeApiOverride(projectRoot, 'REACTPRESS_THEME_PUBLIC_API_URL');
268
+ if (publicOverride)
269
+ return publicOverride;
270
+ const themeOverride = readThemeApiOverride(projectRoot, 'REACTPRESS_THEME_API_URL');
271
+ if (themeOverride)
272
+ return themeOverride;
273
+ return buildLocalThemeApiUrl(projectRoot);
274
+ }
275
+ /** @deprecated use buildThemeServerApiUrl / buildThemePublicApiUrl */
276
+ function buildThemeApiUrl(projectRoot) {
277
+ return buildThemeServerApiUrl(projectRoot);
278
+ }
279
+ function buildThemeChildEnv(projectRoot, { port, serverApiUrl, publicApiUrl, themeId }) {
280
+ const keys = [
281
+ 'PATH',
282
+ 'HOME',
283
+ 'USER',
284
+ 'LANG',
285
+ 'LC_ALL',
286
+ 'NODE_ENV',
287
+ 'PNPM_HOME',
288
+ 'npm_config_user_agent',
289
+ ];
290
+ const env = {};
291
+ for (const key of keys) {
292
+ if (process.env[key] !== undefined)
293
+ env[key] = process.env[key];
294
+ }
295
+ return {
296
+ ...env,
297
+ PORT: String(port),
298
+ // Next inlines SERVER_API_URL from next.config (localhost); override for remote dev SSR.
299
+ SERVER_API_URL: serverApiUrl,
300
+ REACTPRESS_API_URL: serverApiUrl,
301
+ NEXT_PUBLIC_REACTPRESS_API_URL: publicApiUrl,
302
+ REACTPRESS_THEME_ID: themeId || '',
303
+ REACTPRESS_ORIGINAL_CWD: projectRoot,
304
+ REACTPRESS_SKIP_BROWSER_OPEN: '1',
305
+ NEXT_IGNORE_INCORRECT_LOCKFILE: '1',
306
+ NEXT_TELEMETRY_DISABLED: '1',
307
+ ...(process.env.REACTPRESS_NGINX_ENTRY_URL
308
+ ? {
309
+ REACTPRESS_NGINX_ENTRY_URL: process.env.REACTPRESS_NGINX_ENTRY_URL,
310
+ NGINX_ENTRY_URL: process.env.REACTPRESS_NGINX_ENTRY_URL,
311
+ NEXT_PUBLIC_REACTPRESS_ADMIN_URL: `${String(process.env.REACTPRESS_NGINX_ENTRY_URL).replace(/\/$/, '')}/admin`,
312
+ }
313
+ : { REACTPRESS_SKIP_DEV_PORT_REDIRECT: '1' }),
314
+ ...(process.env.REACTPRESS_DESKTOP_LOCAL === '1' || process.env.REACTPRESS_DESKTOP_SITE_ROOT
315
+ ? { REACTPRESS_HONOR_PREVIEW: '1' }
316
+ : {}),
317
+ };
318
+ }
319
+ function stopThemeProcess(childRef, trackedPidRef) {
320
+ const child = childRef.current;
321
+ if (!child || child.killed) {
322
+ childRef.current = null;
323
+ return;
324
+ }
325
+ const pid = child.pid;
326
+ if (pid && isPidSafeToSignal(pid)) {
327
+ trackedPidRef.current = pid;
328
+ }
329
+ try {
330
+ if (process.platform !== 'win32' && pid && isPidSafeToSignal(pid)) {
331
+ try {
332
+ process.kill(-pid, 'SIGTERM');
333
+ }
334
+ catch {
335
+ spawnSync('pkill', ['-TERM', '-P', String(pid)], { stdio: 'ignore' });
336
+ child.kill('SIGTERM');
337
+ }
338
+ for (const descendant of collectDescendantPids(pid)) {
339
+ if (isPidSafeToSignal(descendant)) {
340
+ spawnSync('kill', ['-TERM', descendant], { stdio: 'ignore' });
341
+ }
342
+ }
343
+ }
344
+ else if (pid && isPidSafeToSignal(pid)) {
345
+ child.kill('SIGTERM');
346
+ }
347
+ }
348
+ catch {
349
+ // ignore — process may already be gone
350
+ }
351
+ childRef.current = null;
352
+ }
353
+ const activeChildRef = { get current() { return themeChild; }, set current(v) { themeChild = v; } };
354
+ const activeTrackedPidRef = {
355
+ get current() { return trackedThemePid; },
356
+ set current(v) { trackedThemePid = v; },
357
+ };
358
+ function stopActiveThemeProcess() {
359
+ stopThemeProcess(activeChildRef, activeTrackedPidRef);
360
+ }
361
+ function stopPreviewThemeProcess() {
362
+ /* Preview pool stays warm — torn down only on full dev shutdown. */
363
+ }
364
+ function stopThemeSite() {
365
+ if (themeWatchStop) {
366
+ themeWatchStop();
367
+ themeWatchStop = null;
368
+ }
369
+ stopActiveThemeProcess();
370
+ void stopAllPreviewPool(resolveProjectRoot());
371
+ runningSignature = null;
372
+ previewRunningSignature = null;
373
+ restartChain = Promise.resolve();
374
+ previewRestartChain = Promise.resolve();
375
+ }
376
+ async function spawnThemeSite(projectRoot, { onClose } = {}) {
377
+ const signature = readManifestSignature(projectRoot);
378
+ if (!signature) {
379
+ console.warn(`[reactpress] ${t('themeDev.invalidManifest')}`);
380
+ runningSignature = null;
381
+ return null;
382
+ }
383
+ const { activeTheme } = readActiveThemeManifest(projectRoot);
384
+ const themeDir = resolveThemeDirectory(projectRoot, activeTheme);
385
+ const port = assertThemePort(getClientPort(projectRoot));
386
+ const serverApiUrl = buildThemeServerApiUrl(projectRoot);
387
+ const publicApiUrl = buildThemePublicApiUrl(projectRoot);
388
+ const siteUrl = loadClientSiteUrl(projectRoot);
389
+ if (!themeDir || !isThemePackageDir(projectRoot, themeDir)) {
390
+ console.warn(`[reactpress] ${t('themeDev.notFound', { id: activeTheme })} — ${siteUrl} ${t('themeDev.unavailable')}`);
391
+ runningSignature = null;
392
+ return null;
393
+ }
394
+ const relDir = path.relative(projectRoot, themeDir) || themeDir;
395
+ const launch = resolvePreviewThemeLaunchPlan(themeDir, port);
396
+ const useProduction = launch.mode === 'production';
397
+ logDevDetail('themeDev.startingShort', {
398
+ id: activeTheme,
399
+ port,
400
+ dir: relDir,
401
+ mode: useProduction ? 'production' : 'dev',
402
+ });
403
+ if (isDevVerbose()) {
404
+ logDevLine('themeDev.apiSplit', { ssr: serverApiUrl, browser: publicApiUrl });
405
+ }
406
+ if (useProduction) {
407
+ try {
408
+ ensureThemeDependenciesInstalled(projectRoot, themeDir, activeTheme, 'themeProd');
409
+ }
410
+ catch (err) {
411
+ console.warn(`[reactpress] ${t('themePreview.buildFailed', {
412
+ id: activeTheme,
413
+ message: err.message || err,
414
+ })}`);
415
+ runningSignature = null;
416
+ return null;
417
+ }
418
+ try {
419
+ await enqueueThemeBuild(projectRoot, activeTheme, { logPrefix: 'themeProd' });
420
+ const { ensureBuildAllowsPreviewFrame } = require('./theme-preview-frame');
421
+ ensureBuildAllowsPreviewFrame(themeDir, '.next');
422
+ }
423
+ catch (err) {
424
+ console.warn(`[reactpress] ${t('themePreview.buildFailed', {
425
+ id: activeTheme,
426
+ message: err.message || err,
427
+ })}`);
428
+ runningSignature = null;
429
+ return null;
430
+ }
431
+ }
432
+ else {
433
+ cleanStaleThemeDevCache(themeDir);
434
+ }
435
+ try {
436
+ const { ensurePreviewFrameAllowed } = require('./theme-preview-frame');
437
+ ensurePreviewFrameAllowed(themeDir);
438
+ }
439
+ catch {
440
+ // ignore — preview patch optional for themes without next.config headers
441
+ }
442
+ if (useProduction) {
443
+ themeChild = spawnThemeProcess(projectRoot, {
444
+ themeDir,
445
+ themeId: activeTheme,
446
+ port,
447
+ serverApiUrl,
448
+ publicApiUrl,
449
+ launch,
450
+ role: 'visitor',
451
+ });
452
+ }
453
+ else {
454
+ themeChild = spawnDevChild('pnpm', ['run', 'dev'], {
455
+ cwd: themeDir,
456
+ detached: process.platform !== 'win32',
457
+ shell: process.platform === 'win32',
458
+ env: buildThemeChildEnv(projectRoot, { port, serverApiUrl, publicApiUrl, themeId: activeTheme }),
459
+ });
460
+ }
461
+ const child = themeChild;
462
+ trackedThemePid = child.pid ?? null;
463
+ runningSignature = signature;
464
+ child.on('close', (code) => {
465
+ if (themeChild === child) {
466
+ themeChild = null;
467
+ trackedThemePid = null;
468
+ if (runningSignature === signature) {
469
+ runningSignature = null;
470
+ }
471
+ }
472
+ if (onClose)
473
+ onClose(code);
474
+ });
475
+ if (process.env.REACTPRESS_DEV_FORCE_LOCAL_THEME_API !== '1') {
476
+ const homepageUrl = `${siteUrl.replace(/\/$/, '')}/`;
477
+ const pollMs = parseInt(process.env.REACTPRESS_THEME_READY_POLL_MS || '150', 10) || 150;
478
+ waitForHttpOk(homepageUrl, 120_000, pollMs).then((ready) => {
479
+ if (ready && runningSignature === signature) {
480
+ console.log(t('themeDev.ready', { url: siteUrl, id: activeTheme }));
481
+ warmupThemeHomepage(projectRoot, siteUrl).catch(() => { });
482
+ }
483
+ else if (!ready && runningSignature === signature) {
484
+ console.warn(t('themeDev.slow', { url: siteUrl }));
485
+ }
486
+ });
487
+ }
488
+ return themeChild;
489
+ }
490
+ async function restartThemeSite(projectRoot, { onClose } = {}) {
491
+ const signature = readManifestSignature(projectRoot);
492
+ if (!signature)
493
+ return;
494
+ if (signature === runningSignature && themeChild && !themeChild.killed) {
495
+ return;
496
+ }
497
+ const port = assertThemePort(getClientPort(projectRoot));
498
+ let freed = await releaseThemePort(projectRoot, port, { fast: true });
499
+ if (!freed || isPortListening(port)) {
500
+ freed = await releaseThemePort(projectRoot, port, { fast: true });
501
+ }
502
+ if (!freed || isPortListening(port)) {
503
+ console.warn(`[reactpress] ${t('themeDev.portBusy', { port })}`);
504
+ console.warn(`[reactpress] ${t('themeDev.portBusyHint', {
505
+ port,
506
+ cmd: `lsof -tiTCP:${port} -sTCP:LISTEN | xargs kill -9`,
507
+ })}`);
508
+ return;
509
+ }
510
+ await spawnThemeSite(projectRoot, { onClose });
511
+ }
512
+ async function restartPreviewThemeSite(projectRoot, { onClose } = {}) {
513
+ await withPreviewPortLock(async () => {
514
+ const signature = readPreviewManifestSignature(projectRoot);
515
+ if (!signature) {
516
+ previewRunningSignature = null;
517
+ await stopAllPreviewPool(projectRoot);
518
+ if (onClose)
519
+ onClose(0);
520
+ return;
521
+ }
522
+ const previewManifest = readPreviewThemeManifest(projectRoot);
523
+ const themeId = previewManifest?.activeTheme;
524
+ if (!themeId)
525
+ return;
526
+ const { activeTheme } = readActiveThemeManifest(projectRoot);
527
+ if (themeId === activeTheme) {
528
+ previewRunningSignature = null;
529
+ await stopAllPreviewPool(projectRoot);
530
+ if (onClose)
531
+ onClose(0);
532
+ return;
533
+ }
534
+ await ensurePreviewProxyRunning(getPreviewProxyPort());
535
+ if (signature === previewRunningSignature) {
536
+ const { previewPool } = require('./theme-preview-pool');
537
+ const entry = previewPool.get(themeId);
538
+ const proxyPort = getPreviewProxyPort();
539
+ const childAlive = entry?.child &&
540
+ !entry.child.killed &&
541
+ entry.child.exitCode == null &&
542
+ entry.child.signalCode == null;
543
+ if (childAlive && entry?.backendPort) {
544
+ setPreviewProxyTarget(entry.backendPort);
545
+ entry.lastUsed = Date.now();
546
+ const ready = await isPreviewHomepageReady(projectRoot, proxyPort);
547
+ if (ready)
548
+ return;
549
+ }
550
+ if (entry) {
551
+ stopPreviewPoolTheme(themeId);
552
+ }
553
+ previewRunningSignature = null;
554
+ }
555
+ const serverApiUrl = buildThemeServerApiUrl(projectRoot);
556
+ const publicApiUrl = buildThemePublicApiUrl(projectRoot);
557
+ const result = await ensurePreviewThemeRunning(projectRoot, themeId, {
558
+ serverApiUrl,
559
+ publicApiUrl,
560
+ });
561
+ if (!result) {
562
+ previewRunningSignature = null;
563
+ console.warn(`[reactpress] Preview failed to start for theme "${themeId}"`);
564
+ if (onClose)
565
+ onClose(1);
566
+ return;
567
+ }
568
+ previewRunningSignature = signature;
569
+ if (result.reused) {
570
+ console.log(`[reactpress] Preview ready (reused): ${result.url} (theme: ${themeId})`);
571
+ }
572
+ else {
573
+ console.log(`[reactpress] Preview ready: ${result.url} (theme: ${themeId})`);
574
+ }
575
+ if (onClose)
576
+ onClose(0);
577
+ });
578
+ }
579
+ async function prewarmPreviewThemeBackends(projectRoot) {
580
+ if (process.env.REACTPRESS_SKIP_PREVIEW_BUILD === '1')
581
+ return;
582
+ if (!isIntegratedDesktopDev())
583
+ return;
584
+ const { activeTheme } = readActiveThemeManifest(projectRoot);
585
+ const themeIds = listAvailableThemeIds(projectRoot).filter((id) => id !== activeTheme);
586
+ if (themeIds.length === 0)
587
+ return;
588
+ console.log(`[reactpress] ${t('dev.previewPrewarmStarting')} (${themeIds.length} backend(s) on :${getPreviewProxyPort()}+)`);
589
+ await ensurePreviewProxyRunning(getPreviewProxyPort());
590
+ const serverApiUrl = buildThemeServerApiUrl(projectRoot);
591
+ const publicApiUrl = buildThemePublicApiUrl(projectRoot);
592
+ for (const themeId of themeIds) {
593
+ try {
594
+ const result = await ensurePreviewThemeRunning(projectRoot, themeId, {
595
+ serverApiUrl,
596
+ publicApiUrl,
597
+ });
598
+ if (result?.reused) {
599
+ console.log(`[reactpress] Preview backend reused for "${themeId}" (:${result.backendPort})`);
600
+ }
601
+ else if (result) {
602
+ console.log(`[reactpress] Preview backend ready for "${themeId}" (:${result.backendPort})`);
603
+ }
604
+ }
605
+ catch (err) {
606
+ console.warn(`[reactpress] Preview backend prewarm failed for "${themeId}": ${err.message || err}`);
607
+ }
608
+ }
609
+ }
610
+ function watchActiveThemeManifest(projectRoot, onChange) {
611
+ const manifestPath = path.join(themeWorkspaceRoot(projectRoot), '.reactpress', 'active-theme.json');
612
+ const dir = path.dirname(manifestPath);
613
+ fs.mkdirSync(dir, { recursive: true });
614
+ let lastSignature = readManifestSignature(projectRoot);
615
+ let debounce = null;
616
+ const scheduleCheck = () => {
617
+ clearTimeout(debounce);
618
+ debounce = setTimeout(() => {
619
+ const next = readManifestSignature(projectRoot);
620
+ if (!next || next === lastSignature)
621
+ return;
622
+ lastSignature = next;
623
+ console.log(`\n[reactpress] ${t('themeDev.restart')}`);
624
+ restartChain = restartChain
625
+ .then(() => onChange())
626
+ .catch((err) => {
627
+ console.warn(`[reactpress] ${t('themeDev.restartFailed', { message: err.message || err })}`);
628
+ });
629
+ }, 200);
630
+ };
631
+ const watcher = fs.watch(dir, scheduleCheck);
632
+ const poller = setInterval(scheduleCheck, 1000);
633
+ return () => {
634
+ clearTimeout(debounce);
635
+ clearInterval(poller);
636
+ watcher.close();
637
+ };
638
+ }
639
+ function watchPreviewThemeManifest(projectRoot, onChange) {
640
+ const manifestPath = path.join(themeWorkspaceRoot(projectRoot), '.reactpress', 'preview-theme.json');
641
+ const dir = path.dirname(manifestPath);
642
+ fs.mkdirSync(dir, { recursive: true });
643
+ let lastSignature = readPreviewManifestSignature(projectRoot);
644
+ let debounce = null;
645
+ /** Delay teardown when manifest is deleted — admin preview session may remount immediately. */
646
+ let clearDebounce = null;
647
+ const PREVIEW_CLEAR_GRACE_MS = 500;
648
+ const enqueueRestart = (nextSignature) => {
649
+ if (nextSignature === lastSignature)
650
+ return;
651
+ lastSignature = nextSignature;
652
+ if (nextSignature) {
653
+ console.log('\n[reactpress] preview-theme.json changed — restarting preview theme…');
654
+ }
655
+ previewRestartChain = previewRestartChain
656
+ .then(() => onChange())
657
+ .catch((err) => {
658
+ console.warn(`[reactpress] ${t('themeDev.restartFailed', { message: err.message || err })}`);
659
+ });
660
+ };
661
+ const scheduleCheck = () => {
662
+ clearTimeout(debounce);
663
+ debounce = setTimeout(() => {
664
+ const next = readPreviewManifestSignature(projectRoot);
665
+ if (next === lastSignature)
666
+ return;
667
+ if (!next && lastSignature) {
668
+ if (clearDebounce)
669
+ clearTimeout(clearDebounce);
670
+ clearDebounce = setTimeout(() => {
671
+ clearDebounce = null;
672
+ const still = readPreviewManifestSignature(projectRoot);
673
+ if (still) {
674
+ if (still !== lastSignature)
675
+ enqueueRestart(still);
676
+ return;
677
+ }
678
+ enqueueRestart('');
679
+ }, PREVIEW_CLEAR_GRACE_MS);
680
+ return;
681
+ }
682
+ if (clearDebounce) {
683
+ clearTimeout(clearDebounce);
684
+ clearDebounce = null;
685
+ }
686
+ enqueueRestart(next);
687
+ }, 200);
688
+ };
689
+ const watcher = fs.watch(dir, (event, filename) => {
690
+ if (filename && filename !== 'preview-theme.json')
691
+ return;
692
+ scheduleCheck();
693
+ });
694
+ const poller = setInterval(scheduleCheck, 1000);
695
+ return () => {
696
+ clearTimeout(debounce);
697
+ if (clearDebounce)
698
+ clearTimeout(clearDebounce);
699
+ clearInterval(poller);
700
+ watcher.close();
701
+ };
702
+ }
703
+ /** Drop stale preview manifest so `pnpm dev` does not auto-start :3003 from a prior admin session. */
704
+ function clearPreviewThemeManifestFile(projectRoot) {
705
+ const manifestPath = path.join(themeWorkspaceRoot(projectRoot), '.reactpress', 'preview-theme.json');
706
+ if (fs.existsSync(manifestPath)) {
707
+ fs.unlinkSync(manifestPath);
708
+ }
709
+ }
710
+ async function releaseThemePortIfBusy(projectRoot, port, options) {
711
+ if (!isPortListening(port))
712
+ return true;
713
+ return releaseThemePort(projectRoot, port, options);
714
+ }
715
+ async function prepareThemeDevBoot(projectRoot) {
716
+ clearPreviewThemeManifestFile(projectRoot);
717
+ stopActiveThemeProcess();
718
+ previewRunningSignature = null;
719
+ runningSignature = null;
720
+ trackedThemePid = null;
721
+ await ensurePreviewProxyRunning(getPreviewProxyPort());
722
+ const visitorPort = assertThemePort(getClientPort(projectRoot));
723
+ await releaseThemePortIfBusy(projectRoot, visitorPort);
724
+ }
725
+ async function startThemeSiteWithWatch(projectRoot, { onClose } = {}) {
726
+ await prepareThemeDevBoot(projectRoot);
727
+ const restartActive = () => restartThemeSite(projectRoot, { onClose });
728
+ const restartPreview = () => restartPreviewThemeSite(projectRoot, { onClose });
729
+ restartChain = restartChain.then(() => restartThemeSite(projectRoot, { onClose }));
730
+ await restartChain;
731
+ const stopActiveWatch = watchActiveThemeManifest(projectRoot, restartActive);
732
+ const stopPreviewWatch = watchPreviewThemeManifest(projectRoot, restartPreview);
733
+ const initialPreviewSignature = readPreviewManifestSignature(projectRoot);
734
+ if (initialPreviewSignature) {
735
+ previewRestartChain = previewRestartChain.then(() => restartPreviewThemeSite(projectRoot, { onClose }));
736
+ }
737
+ themeWatchStop = () => {
738
+ stopActiveWatch();
739
+ stopPreviewWatch();
740
+ };
741
+ if (isIntegratedDesktopDev()) {
742
+ void prewarmPreviewThemeBackends(projectRoot);
743
+ }
744
+ return Boolean(runningSignature && themeChild && !themeChild.killed);
745
+ }
746
+ module.exports = {
747
+ spawnThemeSite,
748
+ restartThemeSite,
749
+ startThemeSiteWithWatch,
750
+ stopThemeSite,
751
+ getClientPort,
752
+ buildThemeApiUrl,
753
+ buildThemeServerApiUrl,
754
+ buildThemePublicApiUrl,
755
+ readManifestSignature,
756
+ isPortListening,
757
+ getThemeListenerPids,
758
+ };
759
+ //# sourceMappingURL=theme-dev.js.map