codecrypto-cli 1.0.8 → 1.0.10

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 (272) hide show
  1. package/dist/commands/auth.d.ts.map +1 -1
  2. package/dist/commands/auth.js +64 -7
  3. package/dist/commands/auth.js.map +1 -1
  4. package/dist/commands/deploy-sc.d.ts.map +1 -1
  5. package/dist/commands/deploy-sc.js +162 -0
  6. package/dist/commands/deploy-sc.js.map +1 -1
  7. package/dist/commands/deploy.d.ts.map +1 -1
  8. package/dist/commands/deploy.js +644 -136
  9. package/dist/commands/deploy.js.map +1 -1
  10. package/dist/commands/doctor.d.ts +3 -0
  11. package/dist/commands/doctor.d.ts.map +1 -0
  12. package/dist/commands/doctor.js +518 -0
  13. package/dist/commands/doctor.js.map +1 -0
  14. package/dist/index.js +2 -0
  15. package/dist/index.js.map +1 -1
  16. package/package.json +1 -1
  17. package/src/commands/auth.ts +71 -8
  18. package/src/commands/deploy-sc.ts +182 -0
  19. package/src/commands/deploy.ts +688 -150
  20. package/src/commands/doctor.ts +498 -0
  21. package/src/index.ts +2 -0
  22. package/token.json +69 -0
  23. package/docker-build/Dockerfile +0 -14
  24. package/docker-build/standalone/.next/BUILD_ID +0 -1
  25. package/docker-build/standalone/.next/app-path-routes-manifest.json +0 -13
  26. package/docker-build/standalone/.next/build-manifest.json +0 -20
  27. package/docker-build/standalone/.next/package.json +0 -1
  28. package/docker-build/standalone/.next/prerender-manifest.json +0 -186
  29. package/docker-build/standalone/.next/required-server-files.json +0 -164
  30. package/docker-build/standalone/.next/routes-manifest.json +0 -110
  31. package/docker-build/standalone/.next/server/app/_global-error/page/app-paths-manifest.json +0 -3
  32. package/docker-build/standalone/.next/server/app/_global-error/page/build-manifest.json +0 -17
  33. package/docker-build/standalone/.next/server/app/_global-error/page/next-font-manifest.json +0 -6
  34. package/docker-build/standalone/.next/server/app/_global-error/page/react-loadable-manifest.json +0 -1
  35. package/docker-build/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +0 -4
  36. package/docker-build/standalone/.next/server/app/_global-error/page.js +0 -11
  37. package/docker-build/standalone/.next/server/app/_global-error/page.js.map +0 -5
  38. package/docker-build/standalone/.next/server/app/_global-error/page.js.nft.json +0 -1
  39. package/docker-build/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +0 -2
  40. package/docker-build/standalone/.next/server/app/_global-error.html +0 -2
  41. package/docker-build/standalone/.next/server/app/_global-error.meta +0 -15
  42. package/docker-build/standalone/.next/server/app/_global-error.rsc +0 -13
  43. package/docker-build/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +0 -5
  44. package/docker-build/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +0 -13
  45. package/docker-build/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +0 -6
  46. package/docker-build/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +0 -4
  47. package/docker-build/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +0 -1
  48. package/docker-build/standalone/.next/server/app/_not-found/page/app-paths-manifest.json +0 -3
  49. package/docker-build/standalone/.next/server/app/_not-found/page/build-manifest.json +0 -17
  50. package/docker-build/standalone/.next/server/app/_not-found/page/next-font-manifest.json +0 -11
  51. package/docker-build/standalone/.next/server/app/_not-found/page/react-loadable-manifest.json +0 -1
  52. package/docker-build/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +0 -4
  53. package/docker-build/standalone/.next/server/app/_not-found/page.js +0 -14
  54. package/docker-build/standalone/.next/server/app/_not-found/page.js.map +0 -5
  55. package/docker-build/standalone/.next/server/app/_not-found/page.js.nft.json +0 -1
  56. package/docker-build/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +0 -2
  57. package/docker-build/standalone/.next/server/app/_not-found.html +0 -1
  58. package/docker-build/standalone/.next/server/app/_not-found.meta +0 -16
  59. package/docker-build/standalone/.next/server/app/_not-found.rsc +0 -14
  60. package/docker-build/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +0 -14
  61. package/docker-build/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +0 -6
  62. package/docker-build/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +0 -5
  63. package/docker-build/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +0 -5
  64. package/docker-build/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +0 -4
  65. package/docker-build/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +0 -2
  66. package/docker-build/standalone/.next/server/app/api/deploy/route/app-paths-manifest.json +0 -3
  67. package/docker-build/standalone/.next/server/app/api/deploy/route/build-manifest.json +0 -11
  68. package/docker-build/standalone/.next/server/app/api/deploy/route/server-reference-manifest.json +0 -4
  69. package/docker-build/standalone/.next/server/app/api/deploy/route.js +0 -7
  70. package/docker-build/standalone/.next/server/app/api/deploy/route.js.map +0 -5
  71. package/docker-build/standalone/.next/server/app/api/deploy/route.js.nft.json +0 -1
  72. package/docker-build/standalone/.next/server/app/api/deploy/route_client-reference-manifest.js +0 -2
  73. package/docker-build/standalone/.next/server/app/api/deploy-image/route/app-paths-manifest.json +0 -3
  74. package/docker-build/standalone/.next/server/app/api/deploy-image/route/build-manifest.json +0 -11
  75. package/docker-build/standalone/.next/server/app/api/deploy-image/route/server-reference-manifest.json +0 -4
  76. package/docker-build/standalone/.next/server/app/api/deploy-image/route.js +0 -6
  77. package/docker-build/standalone/.next/server/app/api/deploy-image/route.js.map +0 -5
  78. package/docker-build/standalone/.next/server/app/api/deploy-image/route.js.nft.json +0 -1
  79. package/docker-build/standalone/.next/server/app/api/deploy-image/route_client-reference-manifest.js +0 -2
  80. package/docker-build/standalone/.next/server/app/api/docker-images/route/app-paths-manifest.json +0 -3
  81. package/docker-build/standalone/.next/server/app/api/docker-images/route/build-manifest.json +0 -11
  82. package/docker-build/standalone/.next/server/app/api/docker-images/route/server-reference-manifest.json +0 -4
  83. package/docker-build/standalone/.next/server/app/api/docker-images/route.js +0 -6
  84. package/docker-build/standalone/.next/server/app/api/docker-images/route.js.map +0 -5
  85. package/docker-build/standalone/.next/server/app/api/docker-images/route.js.nft.json +0 -1
  86. package/docker-build/standalone/.next/server/app/api/docker-images/route_client-reference-manifest.js +0 -2
  87. package/docker-build/standalone/.next/server/app/api/faucet/route/app-paths-manifest.json +0 -3
  88. package/docker-build/standalone/.next/server/app/api/faucet/route/build-manifest.json +0 -11
  89. package/docker-build/standalone/.next/server/app/api/faucet/route/server-reference-manifest.json +0 -4
  90. package/docker-build/standalone/.next/server/app/api/faucet/route.js +0 -9
  91. package/docker-build/standalone/.next/server/app/api/faucet/route.js.map +0 -5
  92. package/docker-build/standalone/.next/server/app/api/faucet/route.js.nft.json +0 -1
  93. package/docker-build/standalone/.next/server/app/api/faucet/route_client-reference-manifest.js +0 -2
  94. package/docker-build/standalone/.next/server/app/deploy/page/app-paths-manifest.json +0 -3
  95. package/docker-build/standalone/.next/server/app/deploy/page/build-manifest.json +0 -17
  96. package/docker-build/standalone/.next/server/app/deploy/page/next-font-manifest.json +0 -11
  97. package/docker-build/standalone/.next/server/app/deploy/page/react-loadable-manifest.json +0 -1
  98. package/docker-build/standalone/.next/server/app/deploy/page/server-reference-manifest.json +0 -4
  99. package/docker-build/standalone/.next/server/app/deploy/page.js +0 -16
  100. package/docker-build/standalone/.next/server/app/deploy/page.js.map +0 -5
  101. package/docker-build/standalone/.next/server/app/deploy/page.js.nft.json +0 -1
  102. package/docker-build/standalone/.next/server/app/deploy/page_client-reference-manifest.js +0 -2
  103. package/docker-build/standalone/.next/server/app/deploy.html +0 -1
  104. package/docker-build/standalone/.next/server/app/deploy.meta +0 -15
  105. package/docker-build/standalone/.next/server/app/deploy.rsc +0 -20
  106. package/docker-build/standalone/.next/server/app/deploy.segments/_full.segment.rsc +0 -20
  107. package/docker-build/standalone/.next/server/app/deploy.segments/_head.segment.rsc +0 -6
  108. package/docker-build/standalone/.next/server/app/deploy.segments/_index.segment.rsc +0 -5
  109. package/docker-build/standalone/.next/server/app/deploy.segments/_tree.segment.rsc +0 -4
  110. package/docker-build/standalone/.next/server/app/deploy.segments/deploy/__PAGE__.segment.rsc +0 -9
  111. package/docker-build/standalone/.next/server/app/deploy.segments/deploy.segment.rsc +0 -4
  112. package/docker-build/standalone/.next/server/app/faucet/page/app-paths-manifest.json +0 -3
  113. package/docker-build/standalone/.next/server/app/faucet/page/build-manifest.json +0 -17
  114. package/docker-build/standalone/.next/server/app/faucet/page/next-font-manifest.json +0 -11
  115. package/docker-build/standalone/.next/server/app/faucet/page/react-loadable-manifest.json +0 -1
  116. package/docker-build/standalone/.next/server/app/faucet/page/server-reference-manifest.json +0 -4
  117. package/docker-build/standalone/.next/server/app/faucet/page.js +0 -16
  118. package/docker-build/standalone/.next/server/app/faucet/page.js.map +0 -5
  119. package/docker-build/standalone/.next/server/app/faucet/page.js.nft.json +0 -1
  120. package/docker-build/standalone/.next/server/app/faucet/page_client-reference-manifest.js +0 -2
  121. package/docker-build/standalone/.next/server/app/faucet.html +0 -1
  122. package/docker-build/standalone/.next/server/app/faucet.meta +0 -15
  123. package/docker-build/standalone/.next/server/app/faucet.rsc +0 -20
  124. package/docker-build/standalone/.next/server/app/faucet.segments/_full.segment.rsc +0 -20
  125. package/docker-build/standalone/.next/server/app/faucet.segments/_head.segment.rsc +0 -6
  126. package/docker-build/standalone/.next/server/app/faucet.segments/_index.segment.rsc +0 -5
  127. package/docker-build/standalone/.next/server/app/faucet.segments/_tree.segment.rsc +0 -4
  128. package/docker-build/standalone/.next/server/app/faucet.segments/faucet/__PAGE__.segment.rsc +0 -9
  129. package/docker-build/standalone/.next/server/app/faucet.segments/faucet.segment.rsc +0 -4
  130. package/docker-build/standalone/.next/server/app/favicon.ico/route/app-paths-manifest.json +0 -3
  131. package/docker-build/standalone/.next/server/app/favicon.ico/route/build-manifest.json +0 -11
  132. package/docker-build/standalone/.next/server/app/favicon.ico/route.js +0 -7
  133. package/docker-build/standalone/.next/server/app/favicon.ico/route.js.map +0 -5
  134. package/docker-build/standalone/.next/server/app/favicon.ico/route.js.nft.json +0 -1
  135. package/docker-build/standalone/.next/server/app/favicon.ico.body +0 -0
  136. package/docker-build/standalone/.next/server/app/favicon.ico.meta +0 -1
  137. package/docker-build/standalone/.next/server/app/images/page/app-paths-manifest.json +0 -3
  138. package/docker-build/standalone/.next/server/app/images/page/build-manifest.json +0 -17
  139. package/docker-build/standalone/.next/server/app/images/page/next-font-manifest.json +0 -11
  140. package/docker-build/standalone/.next/server/app/images/page/react-loadable-manifest.json +0 -1
  141. package/docker-build/standalone/.next/server/app/images/page/server-reference-manifest.json +0 -4
  142. package/docker-build/standalone/.next/server/app/images/page.js +0 -16
  143. package/docker-build/standalone/.next/server/app/images/page.js.map +0 -5
  144. package/docker-build/standalone/.next/server/app/images/page.js.nft.json +0 -1
  145. package/docker-build/standalone/.next/server/app/images/page_client-reference-manifest.js +0 -2
  146. package/docker-build/standalone/.next/server/app/images.html +0 -1
  147. package/docker-build/standalone/.next/server/app/images.meta +0 -15
  148. package/docker-build/standalone/.next/server/app/images.rsc +0 -20
  149. package/docker-build/standalone/.next/server/app/images.segments/_full.segment.rsc +0 -20
  150. package/docker-build/standalone/.next/server/app/images.segments/_head.segment.rsc +0 -6
  151. package/docker-build/standalone/.next/server/app/images.segments/_index.segment.rsc +0 -5
  152. package/docker-build/standalone/.next/server/app/images.segments/_tree.segment.rsc +0 -4
  153. package/docker-build/standalone/.next/server/app/images.segments/images/__PAGE__.segment.rsc +0 -9
  154. package/docker-build/standalone/.next/server/app/images.segments/images.segment.rsc +0 -4
  155. package/docker-build/standalone/.next/server/app/index.html +0 -1
  156. package/docker-build/standalone/.next/server/app/index.meta +0 -14
  157. package/docker-build/standalone/.next/server/app/index.rsc +0 -25
  158. package/docker-build/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +0 -8
  159. package/docker-build/standalone/.next/server/app/index.segments/_full.segment.rsc +0 -25
  160. package/docker-build/standalone/.next/server/app/index.segments/_head.segment.rsc +0 -6
  161. package/docker-build/standalone/.next/server/app/index.segments/_index.segment.rsc +0 -5
  162. package/docker-build/standalone/.next/server/app/index.segments/_tree.segment.rsc +0 -4
  163. package/docker-build/standalone/.next/server/app/page/app-paths-manifest.json +0 -3
  164. package/docker-build/standalone/.next/server/app/page/build-manifest.json +0 -17
  165. package/docker-build/standalone/.next/server/app/page/next-font-manifest.json +0 -11
  166. package/docker-build/standalone/.next/server/app/page/react-loadable-manifest.json +0 -1
  167. package/docker-build/standalone/.next/server/app/page/server-reference-manifest.json +0 -4
  168. package/docker-build/standalone/.next/server/app/page.js +0 -16
  169. package/docker-build/standalone/.next/server/app/page.js.map +0 -5
  170. package/docker-build/standalone/.next/server/app/page.js.nft.json +0 -1
  171. package/docker-build/standalone/.next/server/app/page_client-reference-manifest.js +0 -2
  172. package/docker-build/standalone/.next/server/app-paths-manifest.json +0 -13
  173. package/docker-build/standalone/.next/server/chunks/10072_infra_server-cc__next-internal_server_app_api_deploy_route_actions_6cdc6432.js +0 -3
  174. package/docker-build/standalone/.next/server/chunks/10072_infra_server-cc__next-internal_server_app_api_faucet_route_actions_f54ec975.js +0 -3
  175. package/docker-build/standalone/.next/server/chunks/10072_infra_server-cc__next-internal_server_app_favicon_ico_route_actions_d73715d1.js +0 -3
  176. package/docker-build/standalone/.next/server/chunks/66d90_server-cc__next-internal_server_app_api_deploy-image_route_actions_b340a7f4.js +0 -3
  177. package/docker-build/standalone/.next/server/chunks/66d90_server-cc__next-internal_server_app_api_docker-images_route_actions_4adcb030.js +0 -3
  178. package/docker-build/standalone/.next/server/chunks/6f6aa_4d460f49._.js +0 -30
  179. package/docker-build/standalone/.next/server/chunks/6f6aa_@noble_curves_esm_secp256k1_c7f9b58b.js +0 -3
  180. package/docker-build/standalone/.next/server/chunks/6f6aa_next_dist_esm_build_templates_app-route_1a9ee783.js +0 -6
  181. package/docker-build/standalone/.next/server/chunks/6f6aa_next_dist_esm_build_templates_app-route_8d132e6a.js +0 -3
  182. package/docker-build/standalone/.next/server/chunks/6f6aa_viem__esm_utils_ccip_bb7bf310.js +0 -3
  183. package/docker-build/standalone/.next/server/chunks/[externals]_next_dist_b01ab6e1._.js +0 -3
  184. package/docker-build/standalone/.next/server/chunks/[root-of-the-server]__0928cca7._.js +0 -3
  185. package/docker-build/standalone/.next/server/chunks/[root-of-the-server]__0c6b3bd9._.js +0 -3
  186. package/docker-build/standalone/.next/server/chunks/[root-of-the-server]__1846bb23._.js +0 -3
  187. package/docker-build/standalone/.next/server/chunks/[root-of-the-server]__8f8a2ff9._.js +0 -3
  188. package/docker-build/standalone/.next/server/chunks/[root-of-the-server]__90ea784b._.js +0 -21
  189. package/docker-build/standalone/.next/server/chunks/[root-of-the-server]__f6379956._.js +0 -39
  190. package/docker-build/standalone/.next/server/chunks/[turbopack]_runtime.js +0 -795
  191. package/docker-build/standalone/.next/server/chunks/ssr/10072_infra_server-cc__next-internal_server_app__global-error_page_actions_bdbde336.js +0 -3
  192. package/docker-build/standalone/.next/server/chunks/ssr/10072_infra_server-cc__next-internal_server_app__not-found_page_actions_41269af3.js +0 -3
  193. package/docker-build/standalone/.next/server/chunks/ssr/10072_infra_server-cc__next-internal_server_app_deploy_page_actions_3988cfb8.js +0 -3
  194. package/docker-build/standalone/.next/server/chunks/ssr/10072_infra_server-cc__next-internal_server_app_faucet_page_actions_e5e8dd8a.js +0 -3
  195. package/docker-build/standalone/.next/server/chunks/ssr/10072_infra_server-cc__next-internal_server_app_images_page_actions_bcdfd86b.js +0 -3
  196. package/docker-build/standalone/.next/server/chunks/ssr/2025_cc_CODECRYPTO_infra_server-cc_293382c4._.js +0 -4
  197. package/docker-build/standalone/.next/server/chunks/ssr/2025_cc_CODECRYPTO_infra_server-cc_55723634._.js +0 -4
  198. package/docker-build/standalone/.next/server/chunks/ssr/2025_cc_CODECRYPTO_infra_server-cc_821445df._.js +0 -3
  199. package/docker-build/standalone/.next/server/chunks/ssr/2025_cc_CODECRYPTO_infra_server-cc_8545ebc7._.js +0 -4
  200. package/docker-build/standalone/.next/server/chunks/ssr/2025_cc_CODECRYPTO_infra_server-cc_acad38a1._.js +0 -6
  201. package/docker-build/standalone/.next/server/chunks/ssr/2025_cc_CODECRYPTO_infra_server-cc_app_b373a582._.js +0 -3
  202. package/docker-build/standalone/.next/server/chunks/ssr/2025_cc_CODECRYPTO_infra_server-cc_d03dcb7a._.js +0 -4
  203. package/docker-build/standalone/.next/server/chunks/ssr/6f6aa_7c51ed4c._.js +0 -3
  204. package/docker-build/standalone/.next/server/chunks/ssr/6f6aa_next_dist_05cd73d5._.js +0 -3
  205. package/docker-build/standalone/.next/server/chunks/ssr/6f6aa_next_dist_3e60adb5._.js +0 -6
  206. package/docker-build/standalone/.next/server/chunks/ssr/6f6aa_next_dist_5002976b._.js +0 -4
  207. package/docker-build/standalone/.next/server/chunks/ssr/6f6aa_next_dist_client_components_a432b2d3._.js +0 -3
  208. package/docker-build/standalone/.next/server/chunks/ssr/6f6aa_next_dist_client_components_builtin_forbidden_b4e63d3a.js +0 -3
  209. package/docker-build/standalone/.next/server/chunks/ssr/6f6aa_next_dist_client_components_builtin_global-error_edcabd66.js +0 -3
  210. package/docker-build/standalone/.next/server/chunks/ssr/6f6aa_next_dist_client_components_builtin_unauthorized_f08488ad.js +0 -3
  211. package/docker-build/standalone/.next/server/chunks/ssr/6f6aa_next_dist_esm_build_templates_app-page_c7a8656a.js +0 -4
  212. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e0d983d._.js +0 -3
  213. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__0f25bf3b._.js +0 -3
  214. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__10dae68a._.js +0 -3
  215. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ebd727b._.js +0 -3
  216. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__30996048._.js +0 -3
  217. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__587c95dd._.js +0 -3
  218. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__5ecc39a2._.js +0 -3
  219. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__6382fff8._.js +0 -3
  220. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__8ed1042a._.js +0 -3
  221. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__91644c56._.js +0 -3
  222. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__a2833bcd._.js +0 -10
  223. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__acf31a1c._.js +0 -3
  224. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__ae009f46._.js +0 -3
  225. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__daca67ae._.js +0 -3
  226. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__f2372d3f._.js +0 -4
  227. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__f2ed834a._.js +0 -3
  228. package/docker-build/standalone/.next/server/chunks/ssr/[root-of-the-server]__ff0dddf3._.js +0 -3
  229. package/docker-build/standalone/.next/server/chunks/ssr/[turbopack]_runtime.js +0 -795
  230. package/docker-build/standalone/.next/server/chunks/ssr/e6d68_cc_CODECRYPTO_infra_server-cc__next-internal_server_app_page_actions_12ae3ff1.js +0 -3
  231. package/docker-build/standalone/.next/server/functions-config-manifest.json +0 -4
  232. package/docker-build/standalone/.next/server/middleware-build-manifest.js +0 -21
  233. package/docker-build/standalone/.next/server/middleware-manifest.json +0 -6
  234. package/docker-build/standalone/.next/server/next-font-manifest.js +0 -1
  235. package/docker-build/standalone/.next/server/next-font-manifest.json +0 -27
  236. package/docker-build/standalone/.next/server/pages/404.html +0 -1
  237. package/docker-build/standalone/.next/server/pages/500.html +0 -2
  238. package/docker-build/standalone/.next/server/pages-manifest.json +0 -4
  239. package/docker-build/standalone/.next/server/server-reference-manifest.js +0 -1
  240. package/docker-build/standalone/.next/server/server-reference-manifest.json +0 -5
  241. package/docker-build/standalone/.next/static/ZrQJjBH5oznRmy8xN4NKX/_buildManifest.js +0 -11
  242. package/docker-build/standalone/.next/static/ZrQJjBH5oznRmy8xN4NKX/_clientMiddlewareManifest.json +0 -1
  243. package/docker-build/standalone/.next/static/ZrQJjBH5oznRmy8xN4NKX/_ssgManifest.js +0 -1
  244. package/docker-build/standalone/.next/static/chunks/0c03a563297c48f4.js +0 -1
  245. package/docker-build/standalone/.next/static/chunks/3142ddfdb448fd24.js +0 -1
  246. package/docker-build/standalone/.next/static/chunks/35b2ae0057b43b20.js +0 -1
  247. package/docker-build/standalone/.next/static/chunks/5a1aef391fd12242.js +0 -1
  248. package/docker-build/standalone/.next/static/chunks/66401b6fc62891de.js +0 -4
  249. package/docker-build/standalone/.next/static/chunks/782a67ca986fb1bd.js +0 -1
  250. package/docker-build/standalone/.next/static/chunks/8b27abf6cb0fca62.js +0 -2
  251. package/docker-build/standalone/.next/static/chunks/8dba80aa68873762.css +0 -3
  252. package/docker-build/standalone/.next/static/chunks/902797f337bf356c.js +0 -1
  253. package/docker-build/standalone/.next/static/chunks/9706b17cfd50df01.js +0 -1
  254. package/docker-build/standalone/.next/static/chunks/a6dad97d9634a72d.js +0 -1
  255. package/docker-build/standalone/.next/static/chunks/a6dad97d9634a72d.js.map +0 -1
  256. package/docker-build/standalone/.next/static/chunks/df3b8eb181fde7c2.js +0 -1
  257. package/docker-build/standalone/.next/static/chunks/turbopack-237950634fd3a365.js +0 -4
  258. package/docker-build/standalone/.next/static/media/4fa387ec64143e14-s.c1fdd6c2.woff2 +0 -0
  259. package/docker-build/standalone/.next/static/media/7178b3e590c64307-s.b97b3418.woff2 +0 -0
  260. package/docker-build/standalone/.next/static/media/797e433ab948586e-s.p.dbea232f.woff2 +0 -0
  261. package/docker-build/standalone/.next/static/media/8a480f0b521d4e75-s.8e0177b5.woff2 +0 -0
  262. package/docker-build/standalone/.next/static/media/bbc41e54d2fcbd21-s.799d8ef8.woff2 +0 -0
  263. package/docker-build/standalone/.next/static/media/caa3a2e1cccd8315-s.p.853070df.woff2 +0 -0
  264. package/docker-build/standalone/.next/static/media/favicon.0b3bf435.ico +0 -0
  265. package/docker-build/standalone/package.json +0 -35
  266. package/docker-build/standalone/public/deploy-test.html +0 -276
  267. package/docker-build/standalone/public/file.svg +0 -1
  268. package/docker-build/standalone/public/globe.svg +0 -1
  269. package/docker-build/standalone/public/next.svg +0 -1
  270. package/docker-build/standalone/public/vercel.svg +0 -1
  271. package/docker-build/standalone/public/window.svg +0 -1
  272. package/docker-build/standalone/server.js +0 -38
@@ -45,8 +45,8 @@ const fs = __importStar(require("fs"));
45
45
  const path = __importStar(require("path"));
46
46
  const os = __importStar(require("os"));
47
47
  exports.deployCommand = new commander_1.Command('deploy')
48
- .description('Build and deploy Docker image for Next.js standalone application')
49
- .argument('<project-path>', 'Path to the Next.js project directory')
48
+ .description('Build and deploy Docker image for Next.js or Express application')
49
+ .argument('<project-path>', 'Path to the project directory')
50
50
  .argument('[dest-folder]', 'Destination folder for Docker build context', './docker-build')
51
51
  .option('--skip-build', 'Skip npm run build (assume already built)', false)
52
52
  .option('--no-push', 'Build image but do not push to registry')
@@ -55,6 +55,8 @@ exports.deployCommand = new commander_1.Command('deploy')
55
55
  .option('--env-file <path>', 'Path to .env file with environment variables')
56
56
  .option('--port <port>', 'Application port', '3000')
57
57
  .option('--domain-base <domain>', 'Domain base for deployment', 'proyectos.codecrypto.academy')
58
+ .option('--image-version <version>', 'Image version/tag to deploy (overrides package.json version)')
59
+ .option('--skip-git-check', 'Skip Git repository status check', false)
58
60
  .action(async (projectPath, destFolder, options) => {
59
61
  console.log(chalk_1.default.blue('\n🐳 CodeCrypto Docker Deployment\n'));
60
62
  try {
@@ -70,9 +72,85 @@ exports.deployCommand = new commander_1.Command('deploy')
70
72
  console.error(chalk_1.default.red(`❌ Error: No se encontró package.json en el proyecto`));
71
73
  process.exit(1);
72
74
  }
73
- // Leer versión del package.json
75
+ // Validar que no hay archivos pendientes de commit (a menos que se omita)
76
+ if (!options.skipGitCheck) {
77
+ const gitCheckSpinner = (0, ora_1.default)('Checking Git status...').start();
78
+ try {
79
+ // Verificar si es un repositorio git usando git rev-parse
80
+ // Esto es más robusto que solo verificar .git ya que funciona con submodules y worktrees
81
+ let isGitRepo = false;
82
+ try {
83
+ (0, child_process_1.execSync)('git rev-parse --git-dir', {
84
+ cwd: resolvedProjectPath,
85
+ encoding: 'utf-8',
86
+ stdio: 'pipe',
87
+ });
88
+ isGitRepo = true;
89
+ }
90
+ catch {
91
+ // No es un repositorio git o git no está disponible
92
+ isGitRepo = false;
93
+ }
94
+ if (isGitRepo) {
95
+ // Verificar si hay cambios sin commitear
96
+ try {
97
+ const gitStatus = (0, child_process_1.execSync)('git status --porcelain', {
98
+ cwd: resolvedProjectPath,
99
+ encoding: 'utf-8',
100
+ stdio: 'pipe',
101
+ }).trim();
102
+ if (gitStatus) {
103
+ gitCheckSpinner.fail('Uncommitted changes detected');
104
+ console.error(chalk_1.default.red('\n❌ Error: Hay archivos pendientes de commit en el repositorio'));
105
+ console.error(chalk_1.default.yellow('\n📋 Archivos modificados/sin commitear:'));
106
+ console.log(chalk_1.default.gray('─'.repeat(60)));
107
+ // Mostrar los archivos pendientes
108
+ const files = gitStatus.split('\n').filter(line => line.trim());
109
+ files.forEach(file => {
110
+ const status = file.substring(0, 2);
111
+ const fileName = file.substring(3);
112
+ let statusColor = chalk_1.default.yellow;
113
+ if (status.includes('A'))
114
+ statusColor = chalk_1.default.green;
115
+ else if (status.includes('D'))
116
+ statusColor = chalk_1.default.red;
117
+ else if (status.includes('M'))
118
+ statusColor = chalk_1.default.yellow;
119
+ console.log(chalk_1.default.gray(` ${statusColor(status)} ${chalk_1.default.white(fileName)}`));
120
+ });
121
+ console.log(chalk_1.default.gray('─'.repeat(60)));
122
+ console.error(chalk_1.default.yellow('\n💡 Por favor, haz commit de tus cambios antes de desplegar:'));
123
+ console.error(chalk_1.default.cyan(' git add .'));
124
+ console.error(chalk_1.default.cyan(' git commit -m "your message"'));
125
+ console.error(chalk_1.default.yellow('\n O usa --skip-git-check para omitir esta validación (no recomendado)'));
126
+ process.exit(1);
127
+ }
128
+ else {
129
+ gitCheckSpinner.succeed('Git repository is clean');
130
+ }
131
+ }
132
+ catch (error) {
133
+ // Si git status falla, puede ser que haya algún problema
134
+ gitCheckSpinner.warn('Could not check Git status, continuing...');
135
+ if (error.message) {
136
+ console.log(chalk_1.default.yellow(` Warning: ${error.message}`));
137
+ }
138
+ }
139
+ }
140
+ else {
141
+ gitCheckSpinner.succeed('Not a Git repository (skipping check)');
142
+ }
143
+ }
144
+ catch (error) {
145
+ gitCheckSpinner.warn('Git check failed, continuing...');
146
+ }
147
+ }
148
+ else {
149
+ console.log(chalk_1.default.yellow('⚠️ Git status check skipped (--skip-git-check)'));
150
+ }
151
+ // Leer versión del package.json o usar la versión especificada
74
152
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
75
- const version = packageJson.version || 'latest';
153
+ const version = options.imageVersion || packageJson.version || 'latest';
76
154
  const projectName = path.basename(resolvedProjectPath);
77
155
  const imageBase = `jviejo/${projectName}`;
78
156
  const imageName = `${imageBase}:${version}`;
@@ -82,114 +160,145 @@ exports.deployCommand = new commander_1.Command('deploy')
82
160
  // - Por defecto (sin flags): options.push = true (hace push)
83
161
  // - Con --no-push: options.push = false (no hace push)
84
162
  const shouldPush = options.push !== false;
163
+ // Detectar automáticamente el tipo de proyecto analizando package.json
164
+ const allDependencies = {
165
+ ...(packageJson.dependencies || {}),
166
+ ...(packageJson.devDependencies || {}),
167
+ };
168
+ let projectType = null;
169
+ if (allDependencies.next || allDependencies['nextjs']) {
170
+ projectType = 'nextjs';
171
+ }
172
+ else if (allDependencies.express) {
173
+ projectType = 'express';
174
+ }
175
+ if (!projectType) {
176
+ console.error(chalk_1.default.red(`❌ Error: No se pudo detectar el tipo de proyecto`));
177
+ console.error(chalk_1.default.yellow(' El proyecto debe tener "next" o "express" en las dependencias del package.json'));
178
+ console.error(chalk_1.default.yellow(' Dependencias encontradas:'));
179
+ const depKeys = Object.keys(allDependencies).slice(0, 10);
180
+ depKeys.forEach(dep => {
181
+ console.error(chalk_1.default.gray(` - ${dep}`));
182
+ });
183
+ if (Object.keys(allDependencies).length > 10) {
184
+ console.error(chalk_1.default.gray(` ... y ${Object.keys(allDependencies).length - 10} más`));
185
+ }
186
+ process.exit(1);
187
+ }
85
188
  console.log(chalk_1.default.gray('Deployment Configuration:'));
86
189
  console.log(chalk_1.default.white(` Project: ${chalk_1.default.green(projectName)}`));
190
+ console.log(chalk_1.default.white(` Type: ${chalk_1.default.green(projectType)}`));
87
191
  console.log(chalk_1.default.white(` Version: ${chalk_1.default.green(version)}`));
88
192
  console.log(chalk_1.default.white(` Image: ${chalk_1.default.green(imageName)}`));
89
193
  console.log(chalk_1.default.white(` Latest: ${chalk_1.default.green(imageLatest)}`));
90
194
  console.log(chalk_1.default.white(` Push to Registry: ${shouldPush ? chalk_1.default.green('Yes') : chalk_1.default.yellow('No')}\n`));
91
- // Paso 1: Build del proyecto si es necesario
92
- if (!options.skipBuild) {
93
- const buildSpinner = (0, ora_1.default)('Building Next.js application...').start();
94
- try {
95
- (0, child_process_1.execSync)('npm run build', {
96
- cwd: resolvedProjectPath,
97
- stdio: 'pipe'
98
- });
99
- buildSpinner.succeed('Build completed successfully');
100
- }
101
- catch (error) {
102
- buildSpinner.fail('Build failed');
103
- console.error(chalk_1.default.red('Error during build. Make sure you have "output: standalone" in next.config.ts'));
104
- process.exit(1);
105
- }
106
- }
107
- // Verificar que existe .next/standalone
108
- const standalonePath = path.join(resolvedProjectPath, '.next', 'standalone');
109
- if (!fs.existsSync(standalonePath)) {
110
- console.error(chalk_1.default.red(`❌ Error: No se encontró .next/standalone`));
111
- console.error(chalk_1.default.yellow('Asegúrate de tener "output: standalone" en next.config.ts y ejecutar "npm run build"'));
112
- process.exit(1);
113
- }
114
- // Paso 2: Preparar directorio destino
195
+ // Preparar directorio destino
115
196
  const resolvedDestFolder = path.resolve(destFolder);
116
- const standaloneDest = path.join(resolvedDestFolder, 'standalone');
117
- const copySpinner = (0, ora_1.default)('Copying standalone files...').start();
118
197
  if (fs.existsSync(resolvedDestFolder)) {
119
198
  fs.rmSync(resolvedDestFolder, { recursive: true, force: true });
120
199
  }
121
- fs.mkdirSync(standaloneDest, { recursive: true });
122
- // Copiar contenido de standalone
123
- const nextDir = findDirectory(standalonePath, '.next');
124
- if (nextDir) {
125
- const parentDir = path.dirname(nextDir);
126
- copyDirectory(parentDir, standaloneDest);
127
- }
128
- else {
129
- copyDirectory(standalonePath, standaloneDest);
130
- }
131
- // Copiar .next/static
132
- const staticPath = path.join(resolvedProjectPath, '.next', 'static');
133
- if (fs.existsSync(staticPath)) {
134
- const staticDest = path.join(standaloneDest, '.next', 'static');
135
- fs.mkdirSync(staticDest, { recursive: true });
136
- copyDirectory(staticPath, staticDest);
137
- }
138
- // Copiar public
139
- const publicPath = path.join(resolvedProjectPath, 'public');
140
- if (fs.existsSync(publicPath)) {
141
- const publicDest = path.join(standaloneDest, 'public');
142
- fs.mkdirSync(publicDest, { recursive: true });
143
- copyDirectory(publicPath, publicDest);
144
- }
145
- // Verificar server.js
146
- const serverJsPath = path.join(standaloneDest, 'server.js');
147
- if (!fs.existsSync(serverJsPath)) {
148
- copySpinner.fail('server.js not found in standalone');
149
- process.exit(1);
150
- }
151
- copySpinner.succeed('Files copied successfully');
152
- // Leer y procesar archivo .env si existe
153
- let nextPublicEnvVars = [];
200
+ fs.mkdirSync(resolvedDestFolder, { recursive: true });
154
201
  let runtimeEnvVars = [];
202
+ let nextPublicEnvVars = [];
203
+ let dockerfileContent;
204
+ // Determinar ruta del archivo .env (común para ambos tipos de proyecto)
155
205
  const envFilePath = options.envFile
156
206
  ? path.resolve(options.envFile)
157
207
  : path.join(resolvedProjectPath, '.env');
158
- if (fs.existsSync(envFilePath)) {
159
- const envContent = fs.readFileSync(envFilePath, 'utf-8');
160
- const envLines = envContent.split('\n');
161
- for (const line of envLines) {
162
- const trimmed = line.trim();
163
- // Ignorar comentarios y líneas vacías
164
- if (!trimmed || trimmed.startsWith('#'))
165
- continue;
166
- const equalIndex = trimmed.indexOf('=');
167
- if (equalIndex === -1)
168
- continue;
169
- const key = trimmed.substring(0, equalIndex).trim();
170
- const value = trimmed.substring(equalIndex + 1).trim();
171
- if (key.startsWith('NEXT_PUBLIC_')) {
172
- nextPublicEnvVars.push(`${key}=${value}`);
208
+ if (projectType === 'nextjs') {
209
+ // ========== LÓGICA PARA NEXT.JS ==========
210
+ // Paso 1: Build del proyecto si es necesario
211
+ if (!options.skipBuild) {
212
+ const buildSpinner = (0, ora_1.default)('Building Next.js application...').start();
213
+ try {
214
+ (0, child_process_1.execSync)('npm run build', {
215
+ cwd: resolvedProjectPath,
216
+ stdio: 'pipe'
217
+ });
218
+ buildSpinner.succeed('Build completed successfully');
173
219
  }
174
- else {
175
- runtimeEnvVars.push(`${key}=${value}`);
220
+ catch (error) {
221
+ buildSpinner.fail('Build failed');
222
+ console.error(chalk_1.default.red('Error during build. Make sure you have "output: standalone" in next.config.ts'));
223
+ process.exit(1);
176
224
  }
177
225
  }
178
- }
179
- // Paso 3: Crear Dockerfile con variables NEXT_PUBLIC_*
180
- const dockerfilePath = path.join(resolvedDestFolder, 'Dockerfile');
181
- // Construir ARG y ENV para NEXT_PUBLIC_*
182
- const buildArgs = nextPublicEnvVars.map(env => {
183
- const [key, ...valueParts] = env.split('=');
184
- const value = valueParts.join('=');
185
- return `ARG ${key}=${value}`;
186
- }).join('\n');
187
- const buildEnvs = nextPublicEnvVars.map(env => {
188
- const [key, ...valueParts] = env.split('=');
189
- const value = valueParts.join('=');
190
- return `ENV ${key}=${value}`;
191
- }).join('\n');
192
- const dockerfileContent = `FROM node:20-alpine
226
+ // Verificar que existe .next/standalone
227
+ const standalonePath = path.join(resolvedProjectPath, '.next', 'standalone');
228
+ if (!fs.existsSync(standalonePath)) {
229
+ console.error(chalk_1.default.red(`❌ Error: No se encontró .next/standalone`));
230
+ console.error(chalk_1.default.yellow('Asegúrate de tener "output: standalone" en next.config.ts y ejecutar "npm run build"'));
231
+ process.exit(1);
232
+ }
233
+ // Paso 2: Preparar directorio destino
234
+ const standaloneDest = path.join(resolvedDestFolder, 'standalone');
235
+ const copySpinner = (0, ora_1.default)('Copying standalone files...').start();
236
+ fs.mkdirSync(standaloneDest, { recursive: true });
237
+ // Copiar contenido de standalone
238
+ const nextDir = findDirectory(standalonePath, '.next');
239
+ if (nextDir) {
240
+ const parentDir = path.dirname(nextDir);
241
+ copyDirectory(parentDir, standaloneDest);
242
+ }
243
+ else {
244
+ copyDirectory(standalonePath, standaloneDest);
245
+ }
246
+ // Copiar .next/static
247
+ const staticPath = path.join(resolvedProjectPath, '.next', 'static');
248
+ if (fs.existsSync(staticPath)) {
249
+ const staticDest = path.join(standaloneDest, '.next', 'static');
250
+ fs.mkdirSync(staticDest, { recursive: true });
251
+ copyDirectory(staticPath, staticDest);
252
+ }
253
+ // Copiar public
254
+ const publicPath = path.join(resolvedProjectPath, 'public');
255
+ if (fs.existsSync(publicPath)) {
256
+ const publicDest = path.join(standaloneDest, 'public');
257
+ fs.mkdirSync(publicDest, { recursive: true });
258
+ copyDirectory(publicPath, publicDest);
259
+ }
260
+ // Verificar server.js
261
+ const serverJsPath = path.join(standaloneDest, 'server.js');
262
+ if (!fs.existsSync(serverJsPath)) {
263
+ copySpinner.fail('server.js not found in standalone');
264
+ process.exit(1);
265
+ }
266
+ copySpinner.succeed('Files copied successfully');
267
+ // Leer y procesar archivo .env si existe
268
+ // (envFilePath ya está definido arriba)
269
+ if (fs.existsSync(envFilePath)) {
270
+ const envContent = fs.readFileSync(envFilePath, 'utf-8');
271
+ const envLines = envContent.split('\n');
272
+ for (const line of envLines) {
273
+ const trimmed = line.trim();
274
+ // Ignorar comentarios y líneas vacías
275
+ if (!trimmed || trimmed.startsWith('#'))
276
+ continue;
277
+ const equalIndex = trimmed.indexOf('=');
278
+ if (equalIndex === -1)
279
+ continue;
280
+ const key = trimmed.substring(0, equalIndex).trim();
281
+ const value = trimmed.substring(equalIndex + 1).trim();
282
+ if (key.startsWith('NEXT_PUBLIC_')) {
283
+ nextPublicEnvVars.push(`${key}=${value}`);
284
+ }
285
+ else {
286
+ runtimeEnvVars.push(`${key}=${value}`);
287
+ }
288
+ }
289
+ }
290
+ // Construir ARG y ENV para NEXT_PUBLIC_*
291
+ const buildArgs = nextPublicEnvVars.map(env => {
292
+ const [key, ...valueParts] = env.split('=');
293
+ const value = valueParts.join('=');
294
+ return `ARG ${key}=${value}`;
295
+ }).join('\n');
296
+ const buildEnvs = nextPublicEnvVars.map(env => {
297
+ const [key, ...valueParts] = env.split('=');
298
+ const value = valueParts.join('=');
299
+ return `ENV ${key}=${value}`;
300
+ }).join('\n');
301
+ dockerfileContent = `FROM node:20-alpine
193
302
  WORKDIR /app
194
303
 
195
304
  ENV NODE_ENV=production
@@ -208,23 +317,243 @@ EXPOSE 3000
208
317
  # Arrancamos directamente con Node
209
318
  CMD ["node", "server.js"]
210
319
  `;
320
+ }
321
+ else {
322
+ // ========== LÓGICA PARA EXPRESS ==========
323
+ // Paso 1: Instalar dependencias de producción si es necesario
324
+ if (!options.skipBuild) {
325
+ const installSpinner = (0, ora_1.default)('Installing production dependencies...').start();
326
+ try {
327
+ // Verificar si node_modules existe
328
+ const nodeModulesPath = path.join(resolvedProjectPath, 'node_modules');
329
+ if (!fs.existsSync(nodeModulesPath)) {
330
+ (0, child_process_1.execSync)('npm install --production', {
331
+ cwd: resolvedProjectPath,
332
+ stdio: 'pipe'
333
+ });
334
+ }
335
+ installSpinner.succeed('Dependencies ready');
336
+ }
337
+ catch (error) {
338
+ installSpinner.fail('Failed to install dependencies');
339
+ console.error(chalk_1.default.red('Error installing dependencies'));
340
+ process.exit(1);
341
+ }
342
+ }
343
+ // Paso 2: Copiar archivos del proyecto (sin node_modules, Docker lo instalará)
344
+ const copySpinner = (0, ora_1.default)('Copying project files...').start();
345
+ // Copiar todos los archivos excepto los que están en .dockerignore
346
+ const ignorePatterns = [
347
+ 'node_modules',
348
+ '.git',
349
+ '.next',
350
+ 'dist',
351
+ 'build',
352
+ '.env',
353
+ '.env.local',
354
+ '.env.*.local',
355
+ 'npm-debug.log*',
356
+ 'yarn-debug.log*',
357
+ 'yarn-error.log*',
358
+ '.DS_Store',
359
+ 'coverage',
360
+ '.nyc_output',
361
+ ];
362
+ function shouldIgnore(filePath, basePath) {
363
+ const relativePath = path.relative(basePath, filePath);
364
+ return ignorePatterns.some(pattern => {
365
+ if (relativePath.includes(pattern))
366
+ return true;
367
+ // Verificar si es un archivo que empieza con el patrón
368
+ const parts = relativePath.split(path.sep);
369
+ return parts.some(part => part === pattern || part.startsWith(pattern));
370
+ });
371
+ }
372
+ function copyProjectFiles(src, dest) {
373
+ if (!fs.existsSync(dest)) {
374
+ fs.mkdirSync(dest, { recursive: true });
375
+ }
376
+ const entries = fs.readdirSync(src, { withFileTypes: true });
377
+ for (const entry of entries) {
378
+ const srcPath = path.join(src, entry.name);
379
+ const destPath = path.join(dest, entry.name);
380
+ // Ignorar archivos y directorios según los patrones
381
+ if (shouldIgnore(srcPath, resolvedProjectPath)) {
382
+ continue;
383
+ }
384
+ try {
385
+ const stats = fs.lstatSync(srcPath);
386
+ if (stats.isDirectory()) {
387
+ copyProjectFiles(srcPath, destPath);
388
+ }
389
+ else if (stats.isFile()) {
390
+ fs.copyFileSync(srcPath, destPath);
391
+ }
392
+ }
393
+ catch (error) {
394
+ // Ignorar errores al copiar archivos especiales
395
+ if (error.code === 'ENOTSUP' || error.code === 'EINVAL' || error.code === 'EOPNOTSUPP') {
396
+ continue;
397
+ }
398
+ throw error;
399
+ }
400
+ }
401
+ }
402
+ // Copiar archivos del proyecto
403
+ copyProjectFiles(resolvedProjectPath, resolvedDestFolder);
404
+ // Verificar que existe package.json en el destino
405
+ const destPackageJson = path.join(resolvedDestFolder, 'package.json');
406
+ if (!fs.existsSync(destPackageJson)) {
407
+ copySpinner.fail('package.json not found');
408
+ console.error(chalk_1.default.red('❌ Error: package.json is required for Express application'));
409
+ process.exit(1);
410
+ }
411
+ // Verificar que existe un archivo principal
412
+ const packageJson = JSON.parse(fs.readFileSync(destPackageJson, 'utf-8'));
413
+ const mainFile = packageJson.main || 'index.js';
414
+ const mainFilePath = path.join(resolvedDestFolder, mainFile);
415
+ if (!fs.existsSync(mainFilePath)) {
416
+ // Buscar otros archivos comunes
417
+ const commonFiles = ['index.js', 'server.js', 'app.js', 'main.js'];
418
+ let found = false;
419
+ for (const file of commonFiles) {
420
+ if (fs.existsSync(path.join(resolvedDestFolder, file))) {
421
+ found = true;
422
+ break;
423
+ }
424
+ }
425
+ if (!found) {
426
+ copySpinner.fail(`Main entry file not found: ${mainFile}`);
427
+ console.error(chalk_1.default.red(`❌ Error: Could not find main entry file (${mainFile}) for Express application`));
428
+ process.exit(1);
429
+ }
430
+ }
431
+ copySpinner.succeed('Files copied successfully');
432
+ // Leer y procesar archivo .env si existe
433
+ // (envFilePath ya está definido arriba)
434
+ if (fs.existsSync(envFilePath)) {
435
+ const envContent = fs.readFileSync(envFilePath, 'utf-8');
436
+ const envLines = envContent.split('\n');
437
+ for (const line of envLines) {
438
+ const trimmed = line.trim();
439
+ // Ignorar comentarios y líneas vacías
440
+ if (!trimmed || trimmed.startsWith('#'))
441
+ continue;
442
+ const equalIndex = trimmed.indexOf('=');
443
+ if (equalIndex === -1)
444
+ continue;
445
+ const key = trimmed.substring(0, equalIndex).trim();
446
+ const value = trimmed.substring(equalIndex + 1).trim();
447
+ runtimeEnvVars.push(`${key}=${value}`);
448
+ }
449
+ }
450
+ // Crear Dockerfile optimizado para Express
451
+ // (destPackageJson, packageJson y mainFile ya están declaradas arriba)
452
+ const startScript = packageJson.scripts?.start;
453
+ // Determinar el comando de inicio
454
+ let startCmd;
455
+ if (startScript) {
456
+ // Si hay un script start, usarlo
457
+ startCmd = startScript.split(' ');
458
+ }
459
+ else {
460
+ // Si no, usar node con el archivo principal
461
+ startCmd = ['node', mainFile];
462
+ }
463
+ dockerfileContent = `FROM node:20-alpine
464
+
465
+ WORKDIR /app
466
+
467
+ ENV NODE_ENV=production
468
+ ENV PORT=3000
469
+
470
+ # Copiar package files primero para aprovechar cache de Docker
471
+ COPY package*.json ./
472
+
473
+ # Instalar solo dependencias de producción
474
+ RUN npm ci --only=production && npm cache clean --force
475
+
476
+ # Copiar código fuente
477
+ COPY . .
478
+
479
+ # Exponemos el puerto
480
+ EXPOSE 3000
481
+
482
+ # Comando de inicio
483
+ CMD ${JSON.stringify(startCmd)}
484
+ `;
485
+ }
486
+ // Paso 3: Crear Dockerfile
487
+ const dockerfileSpinner = (0, ora_1.default)('Creating Dockerfile...').start();
488
+ const dockerfilePath = path.join(resolvedDestFolder, 'Dockerfile');
211
489
  fs.writeFileSync(dockerfilePath, dockerfileContent);
490
+ dockerfileSpinner.succeed('Dockerfile created');
491
+ // Mostrar contenido del Dockerfile
492
+ if (projectType === 'nextjs' && nextPublicEnvVars.length > 0) {
493
+ console.log(chalk_1.default.gray('\n📄 Dockerfile content:'));
494
+ console.log(chalk_1.default.gray('─'.repeat(60)));
495
+ console.log(chalk_1.default.white(dockerfileContent));
496
+ console.log(chalk_1.default.gray('─'.repeat(60)));
497
+ console.log(chalk_1.default.gray(`\n NEXT_PUBLIC_* variables: ${chalk_1.default.cyan(nextPublicEnvVars.length)}`));
498
+ nextPublicEnvVars.forEach(env => {
499
+ const [key] = env.split('=');
500
+ console.log(chalk_1.default.gray(` - ${chalk_1.default.cyan(key)}`));
501
+ });
502
+ }
503
+ else {
504
+ console.log(chalk_1.default.gray(`\n📄 Dockerfile created for ${projectType} application`));
505
+ }
212
506
  // Paso 4: Verificar/crear builder multi-plataforma
213
507
  const builderSpinner = (0, ora_1.default)('Setting up multi-platform builder...').start();
214
508
  try {
215
- const builders = (0, child_process_1.execSync)('docker buildx ls', { encoding: 'utf-8' });
509
+ // Listar builders disponibles, ignorando errores de builders con problemas
510
+ let buildersOutput = '';
511
+ try {
512
+ // Redirigir stderr a /dev/null para ignorar errores de builders problemáticos
513
+ buildersOutput = (0, child_process_1.execSync)('docker buildx ls 2>/dev/null', {
514
+ encoding: 'utf-8',
515
+ stdio: 'pipe',
516
+ shell: '/bin/sh',
517
+ });
518
+ }
519
+ catch (error) {
520
+ // Si hay errores al listar builders (por ejemplo, builder "cc" con problemas SSH),
521
+ // intentar continuar de todas formas
522
+ console.log(chalk_1.default.yellow('⚠️ Warning: Some builders have connection issues, continuing...'));
523
+ }
216
524
  const builderName = 'multiarch-builder';
217
- if (!builders.includes(builderName)) {
218
- (0, child_process_1.execSync)(`docker buildx create --name ${builderName} --use --bootstrap`, { stdio: 'pipe' });
525
+ if (!buildersOutput.includes(builderName)) {
526
+ builderSpinner.text = 'Creating multi-platform builder...';
527
+ (0, child_process_1.execSync)(`docker buildx create --name ${builderName} --use --bootstrap`, {
528
+ stdio: 'pipe',
529
+ // No heredar stderr para evitar errores de otros builders
530
+ });
219
531
  }
220
532
  else {
221
- (0, child_process_1.execSync)(`docker buildx use ${builderName}`, { stdio: 'pipe' });
533
+ builderSpinner.text = 'Using existing multi-platform builder...';
534
+ try {
535
+ (0, child_process_1.execSync)(`docker buildx use ${builderName}`, { stdio: 'pipe' });
536
+ }
537
+ catch (error) {
538
+ // Si falla, intentar crearlo de nuevo
539
+ builderSpinner.text = 'Recreating multi-platform builder...';
540
+ try {
541
+ (0, child_process_1.execSync)(`docker buildx rm ${builderName}`, { stdio: 'pipe' });
542
+ }
543
+ catch {
544
+ // Ignorar si no existe
545
+ }
546
+ (0, child_process_1.execSync)(`docker buildx create --name ${builderName} --use --bootstrap`, { stdio: 'pipe' });
547
+ }
222
548
  }
223
549
  builderSpinner.succeed('Builder ready');
224
550
  }
225
551
  catch (error) {
226
552
  builderSpinner.fail('Failed to setup builder');
227
553
  console.error(chalk_1.default.red('Error setting up Docker buildx builder'));
554
+ console.error(chalk_1.default.yellow('💡 Tip: If you have problematic builders configured, you can remove them with:'));
555
+ console.error(chalk_1.default.cyan(' docker buildx rm <builder-name>'));
556
+ console.error(chalk_1.default.yellow(' Or inspect them with: docker buildx inspect <builder-name>'));
228
557
  process.exit(1);
229
558
  }
230
559
  // Verificar autenticación de Docker si se va a hacer push
@@ -261,13 +590,21 @@ CMD ["node", "server.js"]
261
590
  ${tags.join(' \\\n ')} \
262
591
  --progress=plain \
263
592
  .`;
593
+ console.log(chalk_1.default.gray('\n🔨 Build command:'));
594
+ console.log(chalk_1.default.gray('─'.repeat(60)));
595
+ console.log(chalk_1.default.cyan(buildCommand));
596
+ console.log(chalk_1.default.gray('─'.repeat(60)));
597
+ console.log(chalk_1.default.gray(`\n Working directory: ${chalk_1.default.cyan(resolvedDestFolder)}`));
598
+ console.log(chalk_1.default.gray(` Platforms: ${chalk_1.default.cyan('linux/amd64, linux/arm64')}`));
599
+ console.log(chalk_1.default.gray(` Push to registry: ${shouldPush ? chalk_1.default.green('Yes') : chalk_1.default.yellow('No')}\n`));
264
600
  (0, child_process_1.execSync)(buildCommand, {
265
601
  cwd: resolvedDestFolder,
266
602
  stdio: 'inherit'
267
603
  });
268
604
  buildDockerSpinner.succeed('Docker image built successfully');
269
- console.log(chalk_1.default.green('\n✅ Deployment completed successfully!'));
270
- console.log(chalk_1.default.gray('Image details:'));
605
+ console.log(chalk_1.default.green('\n✅ Image build and push completed successfully!'));
606
+ console.log(chalk_1.default.gray('📦 Image details:'));
607
+ console.log(chalk_1.default.gray('─'.repeat(60)));
271
608
  console.log(chalk_1.default.white(` Platforms: ${chalk_1.default.cyan('linux/amd64, linux/arm64')}`));
272
609
  console.log(chalk_1.default.white(` Version: ${chalk_1.default.cyan(version)}`));
273
610
  console.log(chalk_1.default.white(` Tags:`));
@@ -276,6 +613,12 @@ CMD ["node", "server.js"]
276
613
  if (shouldPush) {
277
614
  console.log(chalk_1.default.white(` Registry: ${chalk_1.default.cyan('Docker Hub')}`));
278
615
  console.log(chalk_1.default.white(` URL: ${chalk_1.default.cyan(`https://hub.docker.com/r/${imageBase}`)}`));
616
+ console.log(chalk_1.default.gray('─'.repeat(60)));
617
+ console.log(chalk_1.default.green(`\n✅ Image pushed to Docker Hub successfully!`));
618
+ }
619
+ else {
620
+ console.log(chalk_1.default.gray('─'.repeat(60)));
621
+ console.log(chalk_1.default.yellow(`\n⚠️ Image built locally (not pushed to registry)`));
279
622
  }
280
623
  }
281
624
  catch (error) {
@@ -288,8 +631,12 @@ CMD ["node", "server.js"]
288
631
  }
289
632
  // Paso 6: Desplegar en servidor remoto si se solicita
290
633
  if (options.deploy) {
634
+ // Para despliegue, usar la versión especificada o la del package.json
635
+ const deployImageName = options.imageVersion
636
+ ? `${imageBase}:${options.imageVersion}`
637
+ : (shouldPush ? imageName : imageLatest);
291
638
  await deployToRemoteServer({
292
- imageName: shouldPush ? imageName : imageLatest,
639
+ imageName: deployImageName,
293
640
  serviceName: options.serviceName || projectName,
294
641
  domainBase: options.domainBase,
295
642
  port: options.port,
@@ -303,16 +650,117 @@ CMD ["node", "server.js"]
303
650
  process.exit(1);
304
651
  }
305
652
  });
653
+ // Función para leer certificados Docker desde token.json
654
+ function loadDockerCertificatesFromToken() {
655
+ const tokenFilePath = path.join(os.homedir(), '.codecrypto', 'token.json');
656
+ if (!fs.existsSync(tokenFilePath)) {
657
+ throw new Error(`Token file not found at ${tokenFilePath}. Please run 'codecrypto auth' first.`);
658
+ }
659
+ let tokenData;
660
+ try {
661
+ tokenData = JSON.parse(fs.readFileSync(tokenFilePath, 'utf-8'));
662
+ }
663
+ catch (error) {
664
+ throw new Error(`Failed to read token file: ${error.message}`);
665
+ }
666
+ if (!tokenData.adminGlobals || !Array.isArray(tokenData.adminGlobals)) {
667
+ throw new Error('adminGlobals not found in token.json. Please run "codecrypto auth --force" to refresh your token.');
668
+ }
669
+ // Buscar los certificados Docker en el array adminGlobals
670
+ // Las keys que buscamos son:
671
+ // - docker-client/ca-pem
672
+ // - docker-client/cert.pem
673
+ // - docker-client/key.pem
674
+ const certKeys = {
675
+ ca: 'docker-client/ca-pem',
676
+ cert: 'docker-client/cert.pem',
677
+ key: 'docker-client/key.pem'
678
+ };
679
+ const certificates = {};
680
+ // Lista de keys encontradas para debugging
681
+ const foundKeys = [];
682
+ // Iterar sobre adminGlobals para encontrar los certificados
683
+ for (const global of tokenData.adminGlobals) {
684
+ if (global && global.key) {
685
+ foundKeys.push(global.key);
686
+ // Buscar cada certificado por su key exacta
687
+ if (global.key === certKeys.ca) {
688
+ certificates.ca = global.value;
689
+ }
690
+ else if (global.key === certKeys.cert) {
691
+ certificates.cert = global.value;
692
+ }
693
+ else if (global.key === certKeys.key) {
694
+ certificates.key = global.value;
695
+ }
696
+ }
697
+ }
698
+ // Verificar que todos los certificados estén presentes
699
+ if (!certificates.ca) {
700
+ const availableKeys = foundKeys.filter(k => k.includes('docker-client')).join(', ') || 'none';
701
+ throw new Error(`Certificate not found: ${certKeys.ca} in adminGlobals.\n` +
702
+ ` Available docker-client keys: ${availableKeys || 'none'}\n` +
703
+ ` Total adminGlobals entries: ${tokenData.adminGlobals.length}\n` +
704
+ ` Please run "codecrypto auth --force" to refresh your token.`);
705
+ }
706
+ if (!certificates.cert) {
707
+ const availableKeys = foundKeys.filter(k => k.includes('docker-client')).join(', ') || 'none';
708
+ throw new Error(`Certificate not found: ${certKeys.cert} in adminGlobals.\n` +
709
+ ` Available docker-client keys: ${availableKeys || 'none'}\n` +
710
+ ` Total adminGlobals entries: ${tokenData.adminGlobals.length}\n` +
711
+ ` Please run "codecrypto auth --force" to refresh your token.`);
712
+ }
713
+ if (!certificates.key) {
714
+ const availableKeys = foundKeys.filter(k => k.includes('docker-client')).join(', ') || 'none';
715
+ throw new Error(`Certificate not found: ${certKeys.key} in adminGlobals.\n` +
716
+ ` Available docker-client keys: ${availableKeys || 'none'}\n` +
717
+ ` Total adminGlobals entries: ${tokenData.adminGlobals.length}\n` +
718
+ ` Please run "codecrypto auth --force" to refresh your token.`);
719
+ }
720
+ // Crear directorio para certificados si no existe
721
+ const dockerCertPath = path.join(os.homedir(), '.codecrypto', 'docker-client');
722
+ if (!fs.existsSync(dockerCertPath)) {
723
+ fs.mkdirSync(dockerCertPath, { recursive: true });
724
+ }
725
+ // Escribir certificados a archivos
726
+ const caPemPath = path.join(dockerCertPath, 'ca.pem');
727
+ const certPemPath = path.join(dockerCertPath, 'cert.pem');
728
+ const keyPemPath = path.join(dockerCertPath, 'key.pem');
729
+ fs.writeFileSync(caPemPath, certificates.ca, 'utf-8');
730
+ fs.writeFileSync(certPemPath, certificates.cert, 'utf-8');
731
+ fs.writeFileSync(keyPemPath, certificates.key, 'utf-8');
732
+ // Establecer permisos correctos para la clave privada (solo lectura para el propietario)
733
+ try {
734
+ fs.chmodSync(keyPemPath, 0o600);
735
+ }
736
+ catch (error) {
737
+ // Ignorar errores de chmod en Windows
738
+ }
739
+ return {
740
+ caPem: certificates.ca,
741
+ certPem: certificates.cert,
742
+ keyPem: certificates.key,
743
+ certPath: dockerCertPath
744
+ };
745
+ }
306
746
  // Función para desplegar en servidor remoto
307
747
  async function deployToRemoteServer(config) {
308
748
  const deploySpinner = (0, ora_1.default)('Configuring remote Docker connection...').start();
309
749
  try {
310
- // Configurar variables de entorno para Docker remoto
311
- const dockerCertPath = path.join(os.homedir(), '.codecrypto', 'docker-client');
312
- if (!fs.existsSync(dockerCertPath)) {
313
- deploySpinner.fail('Docker certificates not found');
314
- console.error(chalk_1.default.red(`❌ Error: Docker certificates not found at ${dockerCertPath}`));
315
- console.error(chalk_1.default.yellow(' Make sure you have the certificates in ~/.codecrypto/docker-client'));
750
+ // Cargar certificados desde token.json
751
+ let dockerCertPath;
752
+ try {
753
+ const certs = loadDockerCertificatesFromToken();
754
+ dockerCertPath = certs.certPath;
755
+ deploySpinner.succeed('Docker certificates loaded from token.json');
756
+ }
757
+ catch (error) {
758
+ deploySpinner.fail('Failed to load Docker certificates');
759
+ console.error(chalk_1.default.red(`❌ Error: ${error.message}`));
760
+ console.error(chalk_1.default.yellow('\n💡 To fix this issue:'));
761
+ console.error(chalk_1.default.yellow(' 1. Run: codecrypto auth --force'));
762
+ console.error(chalk_1.default.yellow(' 2. This will refresh your token with the latest adminGlobals'));
763
+ console.error(chalk_1.default.yellow(' 3. Then try the deploy command again\n'));
316
764
  process.exit(1);
317
765
  }
318
766
  // Verificar que existen los certificados necesarios
@@ -325,43 +773,80 @@ async function deployToRemoteServer(config) {
325
773
  process.exit(1);
326
774
  }
327
775
  }
328
- // Configurar variables de entorno para Docker
329
- const dockerEnv = {
330
- ...process.env,
331
- DOCKER_HOST: 'https://server.codecrypto.academy:2376',
332
- DOCKER_TLS_VERIFY: '1',
333
- DOCKER_CERT_PATH: dockerCertPath,
334
- };
335
- deploySpinner.succeed('Docker connection configured');
776
+ // Construir prefijo de comando Docker con parámetros TLS
777
+ const dockerHost = 'tcp://server.codecrypto.academy:2376';
778
+ const dockerTlsPrefix = `docker -H ${dockerHost} \\
779
+ --tlsverify \\
780
+ --tlscacert="${path.join(dockerCertPath, 'ca.pem')}" \\
781
+ --tlscert="${path.join(dockerCertPath, 'cert.pem')}" \\
782
+ --tlskey="${path.join(dockerCertPath, 'key.pem')}"`;
783
+ console.log(chalk_1.default.gray('\n🔌 Remote Docker configuration:'));
784
+ console.log(chalk_1.default.gray('─'.repeat(60)));
785
+ console.log(chalk_1.default.white(` Docker Host: ${chalk_1.default.cyan(dockerHost)}`));
786
+ console.log(chalk_1.default.white(` TLS Verify: ${chalk_1.default.cyan('enabled')}`));
787
+ console.log(chalk_1.default.white(` Certificates Source: ${chalk_1.default.cyan('token.json (adminGlobals)')}`));
788
+ console.log(chalk_1.default.white(` Certificates Path: ${chalk_1.default.cyan(dockerCertPath)}`));
789
+ console.log(chalk_1.default.gray(' Certificates loaded:'));
790
+ requiredCerts.forEach(cert => {
791
+ const certPath = path.join(dockerCertPath, cert);
792
+ const exists = fs.existsSync(certPath);
793
+ console.log(chalk_1.default.gray(` ${exists ? '✓' : '✗'} ${chalk_1.default.cyan(cert)}`));
794
+ });
795
+ console.log(chalk_1.default.gray('─'.repeat(60)));
796
+ console.log(chalk_1.default.yellow('\n💡 All docker commands will use TLS parameters directly\n'));
336
797
  // Construir nombre completo del dominio
337
798
  const fullDomain = `${config.serviceName}.${config.domainBase}`;
338
799
  const serviceName = config.serviceName.toLowerCase().replace(/[^a-z0-9-]/g, '-');
339
800
  // Detener y eliminar contenedor existente si existe
340
- const stopSpinner = (0, ora_1.default)('Checking for existing container...').start();
801
+ const stopSpinner = (0, ora_1.default)('Checking and removing existing container...').start();
341
802
  try {
342
- (0, child_process_1.execSync)(`docker ps -a --filter name=^${fullDomain}$ --format "{{.Names}}"`, {
343
- env: dockerEnv,
803
+ // Verificar si el contenedor existe
804
+ const checkCmd = `${dockerTlsPrefix} ps -a --filter name=^${fullDomain}$ --format "{{.Names}}"`;
805
+ const existingContainer = (0, child_process_1.execSync)(checkCmd, {
344
806
  stdio: 'pipe',
345
807
  encoding: 'utf-8',
346
- });
347
- // Si existe, detenerlo y eliminarlo
348
- try {
349
- (0, child_process_1.execSync)(`docker stop ${fullDomain}`, { env: dockerEnv, stdio: 'pipe' });
808
+ shell: '/bin/sh',
809
+ }).trim();
810
+ if (existingContainer === fullDomain) {
811
+ // Contenedor existe, detenerlo primero (si está corriendo)
812
+ try {
813
+ const stopCmd = `${dockerTlsPrefix} stop ${fullDomain}`;
814
+ (0, child_process_1.execSync)(stopCmd, { stdio: 'pipe', shell: '/bin/sh' });
815
+ console.log(chalk_1.default.gray(` ✓ Container ${fullDomain} stopped`));
816
+ }
817
+ catch (error) {
818
+ // Container might not be running, that's okay
819
+ console.log(chalk_1.default.gray(` ℹ Container ${fullDomain} was not running`));
820
+ }
821
+ // Eliminar el contenedor
822
+ try {
823
+ const rmCmd = `${dockerTlsPrefix} rm -f ${fullDomain}`;
824
+ (0, child_process_1.execSync)(rmCmd, { stdio: 'pipe', shell: '/bin/sh' });
825
+ stopSpinner.succeed(`Existing container ${fullDomain} removed`);
826
+ }
827
+ catch (error) {
828
+ stopSpinner.fail(`Failed to remove container ${fullDomain}`);
829
+ console.error(chalk_1.default.red(` Error: ${error.message}`));
830
+ process.exit(1);
831
+ }
350
832
  }
351
- catch {
352
- // Container might not be running
833
+ else {
834
+ stopSpinner.succeed('No existing container found');
353
835
  }
836
+ }
837
+ catch (error) {
838
+ // Si el comando falla, puede ser que el contenedor no exista
839
+ // Intentar eliminarlo de todas formas con -f para forzar
354
840
  try {
355
- (0, child_process_1.execSync)(`docker rm ${fullDomain}`, { env: dockerEnv, stdio: 'pipe' });
356
- stopSpinner.succeed('Existing container removed');
841
+ const forceRmCmd = `${dockerTlsPrefix} rm -f ${fullDomain}`;
842
+ (0, child_process_1.execSync)(forceRmCmd, { stdio: 'pipe', shell: '/bin/sh' });
843
+ stopSpinner.succeed('Existing container removed (forced)');
357
844
  }
358
845
  catch {
359
- stopSpinner.warn('No existing container found');
846
+ // Si falla, asumir que no existe y continuar
847
+ stopSpinner.succeed('No existing container found');
360
848
  }
361
849
  }
362
- catch (error) {
363
- stopSpinner.warn('Could not check for existing container');
364
- }
365
850
  // Preparar opciones de entorno
366
851
  // Para despliegue remoto, pasamos las variables directamente con -e
367
852
  // ya que --env-file requiere que el archivo esté en el servidor remoto
@@ -376,33 +861,56 @@ async function deployToRemoteServer(config) {
376
861
  envOpts.push(`-e "${key}=${escapedValue}"`);
377
862
  });
378
863
  }
379
- // Construir comando docker run
380
- const dockerRunCmd = `docker run -d \\
864
+ // Construir comando docker run con parámetros TLS
865
+ const dockerRunCmd = `${dockerTlsPrefix} run -d \\
381
866
  --name ${fullDomain} \\
382
867
  --network academy-network \\
383
868
  --restart unless-stopped \\
384
- ${envOpts.join(' \\\n ')} \\
869
+ ${envOpts.length > 0 ? envOpts.join(' \\\n ') + ' \\' : ''}
385
870
  -l traefik.enable=true \\
386
871
  -l "traefik.http.routers.${serviceName}-router.rule=Host(\\\`${fullDomain}\\\`)" \\
387
872
  -l traefik.http.routers.${serviceName}-router.entrypoints=websecure \\
388
873
  -l traefik.http.routers.${serviceName}-router.tls=true \\
389
874
  -l traefik.http.services.${serviceName}-service.loadbalancer.server.port=${config.port} \\
390
875
  ${config.imageName}`;
876
+ console.log(chalk_1.default.gray('\n🚀 Deployment command (executing on remote Docker):'));
877
+ console.log(chalk_1.default.gray('─'.repeat(60)));
878
+ console.log(chalk_1.default.cyan(dockerRunCmd));
879
+ console.log(chalk_1.default.gray('─'.repeat(60)));
880
+ console.log(chalk_1.default.gray(`\n Remote Docker: ${chalk_1.default.cyan(dockerHost)}`));
881
+ console.log(chalk_1.default.gray(` TLS Certificates: ${chalk_1.default.cyan(dockerCertPath)}`));
882
+ console.log(chalk_1.default.gray(` Service name: ${chalk_1.default.cyan(config.serviceName)}`));
883
+ console.log(chalk_1.default.gray(` Full domain: ${chalk_1.default.cyan(fullDomain)}`));
884
+ console.log(chalk_1.default.gray(` Image: ${chalk_1.default.cyan(config.imageName)}`));
885
+ console.log(chalk_1.default.gray(` Port: ${chalk_1.default.cyan(config.port)}`));
886
+ console.log(chalk_1.default.gray(` Environment variables: ${chalk_1.default.cyan(config.envVars.length)}`));
887
+ if (config.envVars.length > 0) {
888
+ config.envVars.forEach(env => {
889
+ const [key] = env.split('=');
890
+ console.log(chalk_1.default.gray(` - ${chalk_1.default.cyan(key)}`));
891
+ });
892
+ }
893
+ console.log(chalk_1.default.gray('─'.repeat(60)));
391
894
  const runSpinner = (0, ora_1.default)('Deploying container to remote server...').start();
392
895
  try {
896
+ // Ejecutar comando docker con parámetros TLS directamente
393
897
  (0, child_process_1.execSync)(dockerRunCmd, {
394
- env: dockerEnv,
395
898
  stdio: 'inherit',
396
899
  shell: '/bin/sh',
397
900
  });
398
901
  runSpinner.succeed('Container deployed successfully');
399
902
  console.log(chalk_1.default.green('\n✅ Remote deployment completed successfully!'));
400
- console.log(chalk_1.default.gray('Deployment details:'));
903
+ console.log(chalk_1.default.gray('📋 Deployment details:'));
904
+ console.log(chalk_1.default.gray('─'.repeat(60)));
401
905
  console.log(chalk_1.default.white(` Service: ${chalk_1.default.cyan(config.serviceName)}`));
402
906
  console.log(chalk_1.default.white(` Domain: ${chalk_1.default.cyan(fullDomain)}`));
403
907
  console.log(chalk_1.default.white(` URL: ${chalk_1.default.cyan(`https://${fullDomain}`)}`));
404
908
  console.log(chalk_1.default.white(` Image: ${chalk_1.default.cyan(config.imageName)}`));
405
909
  console.log(chalk_1.default.white(` Port: ${chalk_1.default.cyan(config.port)}`));
910
+ console.log(chalk_1.default.white(` Network: ${chalk_1.default.cyan('academy-network')}`));
911
+ console.log(chalk_1.default.white(` Restart policy: ${chalk_1.default.cyan('unless-stopped')}`));
912
+ console.log(chalk_1.default.gray('─'.repeat(60)));
913
+ console.log(chalk_1.default.green(`\n🌐 Your application is now available at: ${chalk_1.default.cyan.underline(`https://${fullDomain}`)}`));
406
914
  }
407
915
  catch (error) {
408
916
  runSpinner.fail('Failed to deploy container');