@griddo/cx 11.9.11-rc.9 → 11.9.12-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/README.md +13 -240
  2. package/build/commands/end-render.d.ts +0 -1
  3. package/build/commands/end-render.js +31 -0
  4. package/build/commands/end-render.js.map +7 -0
  5. package/build/commands/prepare-assets-directory.js +9 -0
  6. package/build/commands/prepare-assets-directory.js.map +7 -0
  7. package/build/commands/prepare-domains-render.js +38 -0
  8. package/build/commands/prepare-domains-render.js.map +7 -0
  9. package/build/commands/reset-render.d.ts +0 -1
  10. package/build/commands/reset-render.js +31 -0
  11. package/build/commands/reset-render.js.map +7 -0
  12. package/build/commands/single-domain-upload-search-content.d.ts +1 -0
  13. package/build/commands/start-render.d.ts +0 -1
  14. package/build/commands/start-render.js +66 -0
  15. package/build/commands/start-render.js.map +7 -0
  16. package/build/commands/upload-search-content.d.ts +0 -1
  17. package/build/commands/upload-search-content.js +32 -0
  18. package/build/commands/upload-search-content.js.map +7 -0
  19. package/build/core/GriddoLog.d.ts +16 -0
  20. package/build/{utils/health-checks.d.ts → core/check-env-health.d.ts} +4 -2
  21. package/build/core/db-class.d.ts +11 -0
  22. package/build/core/db.d.ts +4 -0
  23. package/build/core/dist-rollback.d.ts +11 -0
  24. package/build/core/errors.d.ts +26 -0
  25. package/build/core/fs.d.ts +69 -0
  26. package/build/core/life-cycle.d.ts +26 -0
  27. package/build/core/logger.d.ts +18 -0
  28. package/build/core/objects.d.ts +11 -0
  29. package/build/core/print-logos.d.ts +5 -0
  30. package/build/index.d.ts +10 -29
  31. package/build/index.js +406 -73
  32. package/build/react/DynamicScript/index.d.ts +4 -0
  33. package/build/react/GriddoFavicon/index.d.ts +4 -0
  34. package/build/react/GriddoIntegrations/index.d.ts +3 -4
  35. package/build/react/GriddoIntegrations/utils.d.ts +7 -6
  36. package/build/react/GriddoOpenGraph/index.d.ts +10 -0
  37. package/build/react/index.d.ts +3 -2
  38. package/build/react/index.js +1 -3
  39. package/build/{utils → services}/api.d.ts +1 -1
  40. package/build/services/auth.d.ts +2 -5
  41. package/build/services/domains.d.ts +3 -4
  42. package/build/services/manage-sites.d.ts +22 -0
  43. package/build/services/manage-store.d.ts +32 -0
  44. package/build/services/navigation.d.ts +16 -16
  45. package/build/{utils → services}/pages.d.ts +3 -3
  46. package/build/services/reference-fields.d.ts +3 -3
  47. package/build/services/render-artifacts.d.ts +6 -0
  48. package/build/services/render.d.ts +70 -0
  49. package/build/services/robots.d.ts +2 -19
  50. package/build/services/sitemaps.d.ts +5 -0
  51. package/build/services/sites.d.ts +8 -5
  52. package/build/services/store.d.ts +10 -1
  53. package/build/shared/context.d.ts +36 -0
  54. package/build/shared/envs.d.ts +19 -0
  55. package/build/{errors/errors-data.d.ts → shared/errors.d.ts} +5 -3
  56. package/build/shared/npm-modules/brush.d.ts +18 -0
  57. package/build/shared/npm-modules/find-up-simple.d.ts +34 -0
  58. package/build/shared/npm-modules/pkg-dir.d.ts +7 -0
  59. package/build/shared/npm-modules/xml-parser.d.ts +4 -0
  60. package/build/{types → shared/types}/api.d.ts +18 -18
  61. package/build/{types → shared/types}/global.d.ts +15 -16
  62. package/build/{types → shared/types}/navigation.d.ts +5 -5
  63. package/build/{types → shared/types}/pages.d.ts +9 -9
  64. package/build/shared/types/render.d.ts +54 -0
  65. package/build/{types → shared/types}/sites.d.ts +18 -19
  66. package/build/shared/types.d.ts +15 -0
  67. package/build/ssg-adapters/gatsby/actions/clean.d.ts +3 -0
  68. package/build/ssg-adapters/gatsby/actions/close.d.ts +3 -0
  69. package/build/ssg-adapters/gatsby/actions/data.d.ts +2 -0
  70. package/build/ssg-adapters/gatsby/actions/healthCheck.d.ts +2 -0
  71. package/build/ssg-adapters/gatsby/actions/init.d.ts +2 -0
  72. package/build/ssg-adapters/gatsby/actions/logs.d.ts +3 -0
  73. package/build/ssg-adapters/gatsby/actions/meta.d.ts +2 -0
  74. package/build/ssg-adapters/gatsby/actions/prepare.d.ts +2 -0
  75. package/build/ssg-adapters/gatsby/actions/relocation.d.ts +2 -0
  76. package/build/ssg-adapters/gatsby/actions/restore.d.ts +3 -0
  77. package/build/ssg-adapters/gatsby/actions/ssg.d.ts +3 -0
  78. package/build/ssg-adapters/gatsby/actions/sync.d.ts +3 -0
  79. package/build/ssg-adapters/gatsby/index.d.ts +9 -0
  80. package/build/ssg-adapters/gatsby/shared/artifacts.d.ts +4 -0
  81. package/build/ssg-adapters/gatsby/shared/diff-assets.d.ts +15 -0
  82. package/build/ssg-adapters/gatsby/shared/extract-assets.d.ts +7 -0
  83. package/build/ssg-adapters/gatsby/shared/gatsby-build.d.ts +7 -0
  84. package/build/ssg-adapters/gatsby/shared/render-rollback.d.ts +18 -0
  85. package/build/ssg-adapters/gatsby/shared/sync-render.d.ts +26 -0
  86. package/build/ssg-adapters/gatsby/shared/types.d.ts +34 -0
  87. package/cli.mjs +231 -0
  88. package/exporter/build-esbuild.noop +42 -0
  89. package/exporter/build.sh +16 -24
  90. package/exporter/commands/README.md +151 -0
  91. package/exporter/commands/end-render.ts +65 -86
  92. package/exporter/commands/prepare-assets-directory.ts +35 -0
  93. package/exporter/commands/prepare-domains-render.ts +132 -35
  94. package/exporter/commands/reset-render.ts +13 -8
  95. package/exporter/commands/single-domain-upload-search-content.ts +206 -0
  96. package/exporter/commands/start-render.ts +26 -64
  97. package/exporter/commands/upload-search-content.ts +204 -26
  98. package/exporter/core/GriddoLog.ts +45 -0
  99. package/exporter/core/check-env-health.ts +204 -0
  100. package/exporter/core/db-class.ts +54 -0
  101. package/exporter/core/db.ts +33 -0
  102. package/exporter/core/dist-rollback.ts +49 -0
  103. package/exporter/core/errors.ts +93 -0
  104. package/exporter/core/fs.ts +385 -0
  105. package/exporter/{utils → core}/images.ts +1 -6
  106. package/exporter/{utils → core}/instance.ts +9 -13
  107. package/exporter/core/life-cycle.ts +73 -0
  108. package/exporter/core/logger.ts +141 -0
  109. package/exporter/core/objects.ts +37 -0
  110. package/exporter/core/print-logos.ts +21 -0
  111. package/exporter/index.ts +14 -56
  112. package/exporter/react/DynamicScript/index.tsx +33 -0
  113. package/exporter/react/{Favicon → GriddoFavicon}/index.tsx +3 -9
  114. package/exporter/react/GriddoIntegrations/index.tsx +17 -23
  115. package/exporter/react/GriddoIntegrations/utils.ts +24 -12
  116. package/exporter/react/GriddoOpenGraph/index.tsx +39 -0
  117. package/exporter/react/index.tsx +3 -9
  118. package/exporter/services/api.ts +306 -0
  119. package/exporter/services/auth.ts +8 -10
  120. package/exporter/services/domains.ts +23 -8
  121. package/exporter/services/manage-sites.ts +116 -0
  122. package/exporter/services/manage-store.ts +173 -0
  123. package/exporter/services/navigation.ts +12 -18
  124. package/exporter/{utils → services}/pages.ts +27 -92
  125. package/exporter/services/reference-fields.ts +14 -32
  126. package/exporter/services/render-artifacts.ts +44 -0
  127. package/exporter/services/render.ts +229 -0
  128. package/exporter/services/robots.ts +33 -61
  129. package/exporter/services/sitemaps.ts +129 -0
  130. package/exporter/services/sites.ts +40 -28
  131. package/exporter/services/store.ts +354 -321
  132. package/exporter/shared/context.ts +49 -0
  133. package/exporter/{constants → shared}/endpoints.ts +12 -11
  134. package/exporter/shared/envs.ts +62 -0
  135. package/exporter/{errors/errors-data.ts → shared/errors.ts} +24 -14
  136. package/exporter/shared/npm-modules/README.md +36 -0
  137. package/exporter/shared/npm-modules/brush.ts +34 -0
  138. package/exporter/shared/npm-modules/find-up-simple.ts +100 -0
  139. package/exporter/shared/npm-modules/pkg-dir.ts +17 -0
  140. package/exporter/shared/npm-modules/xml-parser.ts +57 -0
  141. package/exporter/{types → shared/types}/api.ts +40 -41
  142. package/exporter/{types → shared/types}/global.ts +17 -21
  143. package/exporter/{types → shared/types}/navigation.ts +3 -3
  144. package/exporter/{types → shared/types}/pages.ts +10 -11
  145. package/exporter/shared/types/render.ts +63 -0
  146. package/exporter/{types → shared/types}/sites.ts +18 -19
  147. package/exporter/shared/types.ts +15 -0
  148. package/exporter/ssg-adapters/gatsby/actions/clean.ts +26 -0
  149. package/exporter/ssg-adapters/gatsby/actions/close.ts +17 -0
  150. package/exporter/ssg-adapters/gatsby/actions/data.ts +22 -0
  151. package/exporter/ssg-adapters/gatsby/actions/healthCheck.ts +10 -0
  152. package/exporter/ssg-adapters/gatsby/actions/init.ts +12 -0
  153. package/exporter/ssg-adapters/gatsby/actions/logs.ts +10 -0
  154. package/exporter/ssg-adapters/gatsby/actions/meta.ts +13 -0
  155. package/exporter/ssg-adapters/gatsby/actions/prepare.ts +9 -0
  156. package/exporter/ssg-adapters/gatsby/actions/relocation.ts +15 -0
  157. package/exporter/ssg-adapters/gatsby/actions/restore.ts +21 -0
  158. package/exporter/ssg-adapters/gatsby/actions/ssg.ts +12 -0
  159. package/exporter/ssg-adapters/gatsby/actions/sync.ts +65 -0
  160. package/exporter/ssg-adapters/gatsby/index.ts +114 -0
  161. package/exporter/ssg-adapters/gatsby/shared/artifacts.ts +17 -0
  162. package/exporter/ssg-adapters/gatsby/shared/diff-assets.ts +128 -0
  163. package/exporter/ssg-adapters/gatsby/shared/extract-assets.ts +75 -0
  164. package/exporter/ssg-adapters/gatsby/shared/gatsby-build.ts +58 -0
  165. package/exporter/ssg-adapters/gatsby/shared/render-rollback.ts +33 -0
  166. package/exporter/ssg-adapters/gatsby/shared/sync-render.ts +298 -0
  167. package/exporter/ssg-adapters/gatsby/shared/types.ts +35 -0
  168. package/gatsby-browser.tsx +41 -58
  169. package/gatsby-config.ts +10 -17
  170. package/gatsby-node.ts +20 -79
  171. package/gatsby-ssr.tsx +2 -1
  172. package/package.json +41 -80
  173. package/plugins/gatsby-plugin-svgr-loader/gatsby-node.js +55 -0
  174. package/plugins/gatsby-plugin-svgr-loader/package.json +8 -0
  175. package/src/components/Head.tsx +28 -73
  176. package/src/components/template.tsx +6 -29
  177. package/src/gatsby-node-utils.ts +76 -2
  178. package/src/html.tsx +2 -11
  179. package/src/types.ts +3 -3
  180. package/tsconfig.commands.json +36 -0
  181. package/tsconfig.exporter.json +21 -0
  182. package/tsconfig.json +5 -3
  183. package/build/adapters/gatsby/index.d.ts +0 -4
  184. package/build/adapters/gatsby/utils.d.ts +0 -22
  185. package/build/artifacts/index.d.ts +0 -6
  186. package/build/constants/envs.d.ts +0 -37
  187. package/build/constants/index.d.ts +0 -57
  188. package/build/end-render.js +0 -74
  189. package/build/end-render.js.map +0 -7
  190. package/build/errors/index.d.ts +0 -15
  191. package/build/index.js.map +0 -7
  192. package/build/prepare-domains-render.js +0 -73
  193. package/build/prepare-domains-render.js.map +0 -7
  194. package/build/react/Favicon/index.d.ts +0 -5
  195. package/build/registers/api.d.ts +0 -9
  196. package/build/registers/gatsby.d.ts +0 -9
  197. package/build/registers/index.d.ts +0 -3
  198. package/build/reset-render.js +0 -74
  199. package/build/reset-render.js.map +0 -7
  200. package/build/services/register.d.ts +0 -36
  201. package/build/services/settings.d.ts +0 -4
  202. package/build/start-render.js +0 -100
  203. package/build/start-render.js.map +0 -7
  204. package/build/upload-search-content.js +0 -74
  205. package/build/upload-search-content.js.map +0 -7
  206. package/build/utils/alerts.d.ts +0 -3
  207. package/build/utils/cache.d.ts +0 -35
  208. package/build/utils/core-utils.d.ts +0 -107
  209. package/build/utils/create-build-data.d.ts +0 -8
  210. package/build/utils/domains.d.ts +0 -13
  211. package/build/utils/folders.d.ts +0 -53
  212. package/build/utils/loggin.d.ts +0 -51
  213. package/build/utils/render.d.ts +0 -13
  214. package/build/utils/searches.d.ts +0 -15
  215. package/build/utils/sites.d.ts +0 -31
  216. package/build/utils/store.d.ts +0 -81
  217. package/cx.config.d.ts +0 -5
  218. package/cx.config.js +0 -36
  219. package/exporter/adapters/gatsby/index.ts +0 -162
  220. package/exporter/adapters/gatsby/utils.ts +0 -161
  221. package/exporter/artifacts/README.md +0 -34
  222. package/exporter/artifacts/index.ts +0 -33
  223. package/exporter/commands/move-assets.ts +0 -11
  224. package/exporter/constants/envs.ts +0 -94
  225. package/exporter/constants/index.ts +0 -129
  226. package/exporter/errors/index.ts +0 -40
  227. package/exporter/registers/api.ts +0 -14
  228. package/exporter/registers/gatsby.ts +0 -14
  229. package/exporter/registers/index.ts +0 -4
  230. package/exporter/services/register.ts +0 -113
  231. package/exporter/services/settings.ts +0 -17
  232. package/exporter/utils/alerts.ts +0 -29
  233. package/exporter/utils/api.ts +0 -243
  234. package/exporter/utils/cache.ts +0 -142
  235. package/exporter/utils/core-utils.ts +0 -458
  236. package/exporter/utils/create-build-data.ts +0 -17
  237. package/exporter/utils/domains.ts +0 -39
  238. package/exporter/utils/folders.ts +0 -320
  239. package/exporter/utils/health-checks.ts +0 -64
  240. package/exporter/utils/loggin.ts +0 -184
  241. package/exporter/utils/render.ts +0 -71
  242. package/exporter/utils/searches.ts +0 -156
  243. package/exporter/utils/sites.ts +0 -312
  244. package/exporter/utils/store.ts +0 -314
  245. package/src/README.md +0 -7
  246. package/start-render.js +0 -7
  247. /package/build/commands/{move-assets.d.ts → prepare-assets-directory.d.ts} +0 -0
  248. /package/build/{utils → core}/images.d.ts +0 -0
  249. /package/build/{utils → core}/instance.d.ts +0 -0
  250. /package/build/react/{Favicon → GriddoFavicon}/utils.d.ts +0 -0
  251. /package/build/{constants → shared}/endpoints.d.ts +0 -0
  252. /package/build/{types → shared/types}/templates.d.ts +0 -0
  253. /package/exporter/react/{Favicon → GriddoFavicon}/utils.ts +0 -0
  254. /package/exporter/{types → shared/types}/templates.ts +0 -0
@@ -0,0 +1,114 @@
1
+ import type { SSG } from "./shared/types";
2
+
3
+ import path from "node:path";
4
+
5
+ import { readDB, writeDB } from "../../core/db";
6
+ import { pathExists } from "../../core/fs";
7
+ import { GriddoLog } from "../../core/GriddoLog";
8
+ import { doLifeCycle } from "../../core/life-cycle";
9
+ import { initializeLogFile } from "../../core/logger";
10
+ import {
11
+ getRenderMetadataFromDB,
12
+ getRenderModeFromDB,
13
+ getRenderPathsHydratedWithDomainFromDB,
14
+ } from "../../services/render";
15
+ import { getRenderArtifacts } from "../../services/render-artifacts";
16
+ import { RenderContext } from "../../shared/context";
17
+ import { GRIDDO_ASSET_PREFIX, GRIDDO_BUILD_LOGS } from "../../shared/envs";
18
+ import { RENDER_MODE } from "../../shared/types/render";
19
+ import { cleanAction } from "./actions/clean";
20
+ import { closeAction } from "./actions/close";
21
+ import { dataAction } from "./actions/data";
22
+ import { healthCheckAction } from "./actions/healthCheck";
23
+ import { initAction } from "./actions/init";
24
+ import { logsAction } from "./actions/logs";
25
+ import { metaAction } from "./actions/meta";
26
+ import { prepareAction } from "./actions/prepare";
27
+ import { relocationAction } from "./actions/relocation";
28
+ import { restoreAction } from "./actions/restore";
29
+ import { ssgAction } from "./actions/ssg";
30
+ import { syncAction } from "./actions/sync";
31
+ import { getGatsbyArtifacts } from "./shared/artifacts";
32
+ import { disableRollbackOnError, enableRollbackOnError } from "./shared/render-rollback";
33
+
34
+ const FILE_LOGS_ENABLED = GRIDDO_BUILD_LOGS; // && GRIDDO_BUILD_LOGS_TO_FILE;
35
+
36
+ /**
37
+ * Executes a complete Gatsby render process for a given domain.
38
+ *
39
+ * The render process consists of multiple lifecycle steps that handle cleaning,
40
+ * preparing, building and syncing the site. It can run in two modes:
41
+ * - FROM_SCRATCH: Performs a complete rebuild of the domains sites.
42
+ * - INCREMENTAL: Only rebuilds changed pages while preserving the rest.
43
+ */
44
+ export async function gatsbyRenderDomain(domain: string) {
45
+ // Init render log
46
+ await initializeLogFile();
47
+
48
+ // Render data
49
+ const { renderMode, reason } = await getRenderModeFromDB(domain);
50
+ const renderMetadata = await getRenderMetadataFromDB();
51
+ const pathsHydratedWithDomain = await getRenderPathsHydratedWithDomainFromDB({ domain });
52
+ const { __ssg } = pathsHydratedWithDomain;
53
+
54
+ // Artifacts
55
+ const renderArtifacts = await getRenderArtifacts(domain);
56
+ const ssgArtifacts = await getGatsbyArtifacts();
57
+
58
+ // SSG Gatsby assetPrefix
59
+ const assetPrefix = GRIDDO_ASSET_PREFIX ? `${GRIDDO_ASSET_PREFIX}/${domain}` : "";
60
+
61
+ // Previous render error management
62
+ const domainSentinelFile = await pathExists(path.join(__ssg, `.render-sentinel-${domain}`));
63
+ const derivedRenderMode = domainSentinelFile ? RENDER_MODE.FROM_SCRATCH : renderMode;
64
+ const derivedRenderModeReason = domainSentinelFile ? "previous render error" : reason;
65
+
66
+ const data = await readDB();
67
+ data.domains[domain].renderMode = derivedRenderMode;
68
+ data.domains[domain].renderModeReason = derivedRenderModeReason;
69
+ data.domains[domain].isRendering = false;
70
+
71
+ if (renderMode === RENDER_MODE.IDLE && derivedRenderMode === RENDER_MODE.IDLE) {
72
+ GriddoLog.info(
73
+ `(From Current Render) [${domain}]: Skipping start-render as it is marked as IDLE with the reason ${reason}.`,
74
+ );
75
+ return;
76
+ }
77
+
78
+ data.domains[domain].isRendering = true;
79
+ data.currentRenderingDomain = domain;
80
+ await writeDB(data);
81
+
82
+ // Render mode reason to log information to the terminal
83
+ const renderModeReason = derivedRenderModeReason ? ` <${derivedRenderModeReason}>` : "";
84
+ GriddoLog.info(`Init render (${derivedRenderMode})${renderModeReason} for domain ${domain}\n`);
85
+
86
+ // Render context
87
+ const context = new RenderContext<SSG>({
88
+ domain,
89
+ pathsHydratedWithDomain,
90
+ renderArtifacts,
91
+ renderMetadata,
92
+ renderMode: derivedRenderMode,
93
+ ssg: { assetPrefix, ssgArtifacts },
94
+ });
95
+
96
+ // A las actions se les pasa siempre `context` y cada action ya utiliza lo que necesita.
97
+ // Si una action necesita devolver algo para otra, se guarda en el context.
98
+ // Ejemplo: el dataAction obtiene los ids de páginas para renderizar y
99
+ // borrar y los guarda en context.pathsToRender y context.pathsToDelete.
100
+ await doLifeCycle("Init", async () => initAction(context));
101
+ await doLifeCycle("Clean", async () => cleanAction(context));
102
+ await doLifeCycle("Prepare", async () => prepareAction(context));
103
+ await doLifeCycle("Restore", async () => restoreAction(context));
104
+ await enableRollbackOnError();
105
+ await doLifeCycle("Data", async () => dataAction(context));
106
+ await doLifeCycle("SSG", async () => ssgAction(context));
107
+ await doLifeCycle("Relocation", async () => relocationAction(context));
108
+ await doLifeCycle("Meta", async () => metaAction(context));
109
+ await doLifeCycle("Sync", async () => syncAction(context));
110
+ await doLifeCycle("HealthCheck", async () => healthCheckAction(context));
111
+ await doLifeCycle("Logs", async () => logsAction(context), { skip: !FILE_LOGS_ENABLED ? "Build logs to file are disabled" : false }); // biome-ignore format: oneliner
112
+ await doLifeCycle("Close", async () => closeAction(context));
113
+ await disableRollbackOnError();
114
+ }
@@ -0,0 +1,17 @@
1
+ import path from "node:path";
2
+
3
+ import { readDB } from "../../../core/db";
4
+
5
+ export async function getGatsbyArtifacts() {
6
+ const { ssg } = (await readDB()).paths;
7
+
8
+ return {
9
+ disposables: [
10
+ //
11
+ path.join(ssg, "public"),
12
+ path.join(ssg, "static"),
13
+ path.join(ssg, ".cache"),
14
+ ],
15
+ cacheables: [".cache"],
16
+ };
17
+ }
@@ -0,0 +1,128 @@
1
+ import { createHash } from "node:crypto";
2
+ import fsp from "node:fs/promises";
3
+ import { join } from "node:path";
4
+
5
+ import { GriddoLog } from "../../../core/GriddoLog";
6
+
7
+ /**
8
+ * Patrones de archivos de assets críticos para la comparación de builds.
9
+ * Estos archivos son los que realmente afectan el webpackCompilationHash:
10
+ * - app-*.js: Código principal de la aplicación
11
+ * - framework-*.js: Framework de Gatsby/React
12
+ * - webpack-runtime-*.js: Runtime de webpack
13
+ *
14
+ * Si estos archivos no cambian entre renders, el hash debería ser el mismo.
15
+ */
16
+ // const _KEY_ASSET_PATTERNS = [/^app-.*\.js$/, /^framework-.*\.js$/, /^webpack-runtime-.*\.js$/];
17
+
18
+ const KEY_ASSET_PATTERNS = [/\.js$/];
19
+
20
+ /**
21
+ * Calcula los hashes SHA256 del contenido de los assets clave en un directorio.
22
+ * Solo procesa archivos que coincidan con KEY_ASSET_PATTERNS.
23
+ *
24
+ * @param dir La ruta al directorio (ej. './public')
25
+ * @returns Un Map donde la clave es el nombre del fichero y el valor es su hash.
26
+ * Si el directorio no existe o hay errores, retorna un Map vacío.
27
+ */
28
+ async function getAssetHashes(dir: string): Promise<Map<string, string>> {
29
+ const assetHashes = new Map<string, string>();
30
+
31
+ try {
32
+ const allFiles = await fsp.readdir(dir);
33
+ const keyAssetFiles = allFiles.filter((fileName) =>
34
+ KEY_ASSET_PATTERNS.some((pattern) => pattern.test(fileName)),
35
+ );
36
+
37
+ for (const fileName of keyAssetFiles) {
38
+ const filePath = join(dir, fileName);
39
+ const fileContent = await fsp.readFile(filePath);
40
+ const hash = createHash("sha256").update(fileContent).digest("hex");
41
+ assetHashes.set(fileName, hash);
42
+ }
43
+
44
+ return assetHashes;
45
+ } catch (error) {
46
+ GriddoLog.build(`ERROR: Error processing directory ${dir}: ${error}`);
47
+ // Si un directorio no existe (ej. el de producción la primera vez),
48
+ // lo tratamos como si no tuviera assets.
49
+ return assetHashes;
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Compara los assets clave entre dos directorios de build de Gatsby.
55
+ * Solo compara los archivos definidos en KEY_ASSET_PATTERNS.
56
+ *
57
+ * @param dir1 Ruta al primer directorio (ej. el de producción)
58
+ * @param dir2 Ruta al segundo directorio (ej. el del nuevo build)
59
+ * @returns `true` si hay diferencias en los assets clave, `false` si son idénticos.
60
+ */
61
+ export async function getAssetsDiffBetweenRenders(dir1: string, dir2: string): Promise<boolean> {
62
+ const [hashes1, hashes2] = await Promise.all([getAssetHashes(dir1), getAssetHashes(dir2)]);
63
+
64
+ // Si el número de assets clave es diferente, hay cambios.
65
+ if (hashes1.size !== hashes2.size) {
66
+ return true;
67
+ }
68
+
69
+ // Comparamos los hashes de cada fichero.
70
+ for (const [fileName, hash1] of hashes1.entries()) {
71
+ const hash2 = hashes2.get(fileName);
72
+
73
+ // Si un fichero existe en el primero pero no en el segundo, hay cambios.
74
+ if (!hash2) {
75
+ return true;
76
+ }
77
+
78
+ // Si el contenido (hash) de un fichero ha cambiado.
79
+ if (hash1 !== hash2) {
80
+ return true;
81
+ }
82
+ }
83
+
84
+ return false;
85
+ }
86
+
87
+ /**
88
+ * Actualiza el webpackCompilationHash en un único fichero HTML.
89
+ * @param filePath Ruta al fichero HTML.
90
+ * @param newHash El nuevo hash a insertar.
91
+ */
92
+ export async function patchHtmlFile(filePath: string, newHash: string): Promise<void> {
93
+ try {
94
+ const content = await fsp.readFile(filePath, "utf-8");
95
+
96
+ // Esta expresión regular captura tres grupos:
97
+ // 1. La parte ANTES del hash (window.___webpackCompilationHash=")
98
+ // 2. El hash ANTIGUO ([^"]*)
99
+ // 3. La parte DESPUÉS del hash (";</script>)
100
+ const regex = /(window\.___webpackCompilationHash=")([^"]*)(";<\/script>)/;
101
+
102
+ // Solo reemplazamos el segundo grupo (el hash)
103
+ const newContent = content.replace(regex, `$1${newHash}$3`);
104
+
105
+ if (content === newContent) {
106
+ // GriddoLog.warn(`WARN: No se encontró el hash en ${filePath}. El fichero no fue modificado.`);
107
+ return;
108
+ }
109
+
110
+ await fsp.writeFile(filePath, newContent, "utf-8");
111
+ } catch (error) {
112
+ GriddoLog.error(`Failed to process file ${filePath}: ${error}`);
113
+ }
114
+ }
115
+
116
+ // --- Ejemplo de uso ---
117
+ // async function miScriptDeDeploy() {
118
+ // const dirProduccion = '/ruta/a/produccion/public';
119
+ // const dirNuevoBuild = './public';
120
+
121
+ // const hayDiferencias = await getAssetsDiffBetweenRenders(dirProduccion, dirNuevoBuild);
122
+
123
+ // if (hayDiferencias) {
124
+ // // Lógica para el CAMINO A (cambio de código)
125
+ // } else {
126
+ // // Lógica para el CAMINO B (solo contenido)
127
+ // }
128
+ // }
@@ -0,0 +1,75 @@
1
+ import fsp from "node:fs/promises";
2
+ import path from "node:path";
3
+
4
+ import { pathExists } from "../../../core/fs";
5
+ import { getRenderPathsHydratedWithDomainFromDB } from "../../../services/render";
6
+
7
+ /**
8
+ * Update the Griddo's `/dist` dir with the contents from `public` dir only
9
+ * with files of type: js, json and css.
10
+ * TODO: Explicar que el static se copia a assets porque el js va en el subdominio de assets.
11
+ */
12
+ async function extractAssetsFromDist(domain: string) {
13
+ const { __root, __exports } = await getRenderPathsHydratedWithDomainFromDB({ domain });
14
+
15
+ // Archivos (no carpetas) válidos de public
16
+ const filesFromDist = (await fsp.readdir(path.join(__exports, "dist"))).filter(
17
+ (file) =>
18
+ path.extname(file) === ".js" ||
19
+ path.extname(file) === ".json" ||
20
+ path.extname(file) === ".css",
21
+ );
22
+
23
+ // Creamos assets si es necesario (needsAssetPrefix)
24
+ await fsp.mkdir(path.join(__root, "assets"), { recursive: true });
25
+ // page-data folder
26
+ await fsp.cp(
27
+ path.join(__exports, "dist", "page-data"),
28
+ path.join(__root, "assets", "page-data"),
29
+ {
30
+ preserveTimestamps: true,
31
+ recursive: true,
32
+ },
33
+ );
34
+ // static folder si existe
35
+ if (await pathExists(path.join(__root, "static"))) {
36
+ await fsp.cp(path.join(__root, "static"), path.join(__root, "assets"), {
37
+ force: false,
38
+ preserveTimestamps: true,
39
+ recursive: true,
40
+ });
41
+ }
42
+ // dist/static -> assets/static
43
+ if (await pathExists(path.join(__exports, "dist", "static"))) {
44
+ await fsp.cp(path.join(__exports, "dist", "static"), path.join(__root, "assets", "static"), {
45
+ force: false,
46
+ preserveTimestamps: true,
47
+ recursive: true,
48
+ });
49
+ }
50
+ // otro static...
51
+ if (await pathExists(path.join(__root, "static"))) {
52
+ await fsp.cp(path.join(__root, "static"), path.join(__exports, "dist", domain), {
53
+ preserveTimestamps: true,
54
+ recursive: true,
55
+ force: false,
56
+ });
57
+ }
58
+
59
+ // Copia el resto de archivos...
60
+ // for (const file of filesFromDist) {
61
+ // const fileSrc = path.join(__exports, "dist", file);
62
+ // const fileDest = path.join(__root, "assets", file);
63
+ // await fsp.cp(fileSrc, fileDest, { preserveTimestamps: true, recursive: true });
64
+ // }
65
+
66
+ const arraysOfPromises: Promise<void>[] = filesFromDist.map((file) => {
67
+ const fileSrc = path.join(__exports, "dist", file);
68
+ const fileDest = path.join(__root, "assets", file);
69
+ return fsp.cp(fileSrc, fileDest, { preserveTimestamps: true, recursive: true });
70
+ });
71
+
72
+ await Promise.all(arraysOfPromises);
73
+ }
74
+
75
+ export { extractAssetsFromDist };
@@ -0,0 +1,58 @@
1
+ import { spawn } from "node:child_process";
2
+ import path from "node:path";
3
+
4
+ import { GriddoLog } from "../../../core/GriddoLog";
5
+ import { getRenderPathsHydratedWithDomainFromDB } from "../../../services/render";
6
+ import { GRIDDO_SSG_VERBOSE_LOGS } from "../../../shared/envs";
7
+
8
+ /**
9
+ * Spawn a new node process `gatsby build`
10
+ * @note This proccess can not access to the custom Griddo `process.env` so it
11
+ * needs variables passed to it via the `env` prop.
12
+ */
13
+ async function gatsbyBuild(assetPrefixWithDomain: string): Promise<void> {
14
+ GriddoLog.verbose(`read assetPrefixWithDomain, ${assetPrefixWithDomain}`);
15
+ GriddoLog.verbose(`using this NODE_OPTIONS in gatsby command: ${process.env.NODE_OPTIONS}`);
16
+
17
+ const { __ssg } = await getRenderPathsHydratedWithDomainFromDB();
18
+
19
+ // Remove `--openssl-legacy-provider` from NODE_OPTIONS because this value
20
+ // break Gatsby render.
21
+ const nodeOptionsWithoutLegacyOpenSSL = process.env.NODE_OPTIONS
22
+ ? process.env.NODE_OPTIONS.replace(/--openssl-legacy-provider\s*/g, "").trim()
23
+ : "";
24
+
25
+ // Ruta al ejecutable de Gatsby
26
+ const gatsbyExecutable = path.join(__ssg, "node_modules", ".bin", "gatsby");
27
+
28
+ const args = ["build", "--prefix-paths"];
29
+ if (GRIDDO_SSG_VERBOSE_LOGS) {
30
+ args.push("--verbose");
31
+ }
32
+
33
+ return new Promise((resolve, reject) => {
34
+ const child = spawn(gatsbyExecutable, args, {
35
+ cwd: __ssg,
36
+ stdio: ["ignore", "inherit", "inherit"],
37
+ env: {
38
+ ...process.env,
39
+ SPAWN_ASSET_PREFIX_WITH_DOMAIN: assetPrefixWithDomain,
40
+ NODE_OPTIONS: nodeOptionsWithoutLegacyOpenSSL,
41
+ },
42
+ });
43
+
44
+ child.on("close", (code) => {
45
+ if (code === 0) {
46
+ resolve();
47
+ } else {
48
+ reject(new Error(`Gatsby build failed with exit code ${code}`));
49
+ }
50
+ });
51
+
52
+ child.on("error", (error) => {
53
+ reject(new Error(`Failed to start Gatsby build process: ${error.message}`));
54
+ });
55
+ });
56
+ }
57
+
58
+ export { gatsbyBuild };
@@ -0,0 +1,33 @@
1
+ import { readDB, writeDB } from "../../../core/db";
2
+ import { GriddoLog } from "../../../core/GriddoLog";
3
+
4
+ /**
5
+ * Enables the rollback-on-error feature for subsequent render lifecycles.
6
+ * When this feature is active, if an error occurs during a render process,
7
+ * the application will automatically restore the 'exports' directory to its
8
+ * state before the render began. This function updates the configuration
9
+ * in the database to reflect this change.
10
+ * @async
11
+ */
12
+ async function enableRollbackOnError() {
13
+ const data = await readDB();
14
+ data.needsRollbackOnError = true;
15
+ await writeDB(data);
16
+ GriddoLog.info("Render lifecycles that follow will restore the exports dir on error if needed\n");
17
+ }
18
+
19
+ /**
20
+ * Disables the rollback-on-error feature for subsequent render lifecycles.
21
+ * When this feature is inactive, the application will not restore the
22
+ * 'exports' directory if a render process fails. This is the default behavior.
23
+ * This function updates the configuration in the database.
24
+ * @async
25
+ */
26
+ async function disableRollbackOnError() {
27
+ const data = await readDB();
28
+ data.needsRollbackOnError = false;
29
+ await writeDB(data);
30
+ GriddoLog.info("Render lifecycles that follow will not restore the exports dir on error\n");
31
+ }
32
+
33
+ export { disableRollbackOnError, enableRollbackOnError };