@griddo/cx 11.9.8-rc.0 → 11.9.8-rc.2

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 (222) hide show
  1. package/README.md +193 -78
  2. package/build/adapters/gatsby/index.d.ts +4 -0
  3. package/build/adapters/gatsby/utils.d.ts +22 -0
  4. package/build/artifacts/index.d.ts +6 -0
  5. package/build/commands/end-render.d.ts +2 -0
  6. package/build/commands/move-assets.d.ts +1 -0
  7. package/build/commands/prepare-domains-render.d.ts +1 -0
  8. package/build/commands/reset-render.d.ts +2 -0
  9. package/build/commands/start-render.d.ts +2 -0
  10. package/build/commands/upload-search-content.d.ts +2 -0
  11. package/build/constants/envs.d.ts +37 -0
  12. package/build/constants/index.d.ts +57 -0
  13. package/build/end-render.js +74 -0
  14. package/build/end-render.js.map +7 -0
  15. package/build/{shared/errors.d.ts → errors/errors-data.d.ts} +3 -5
  16. package/build/{core/errors.d.ts → errors/index.d.ts} +4 -5
  17. package/build/index.d.ts +29 -10
  18. package/build/index.js +73 -406
  19. package/build/index.js.map +7 -0
  20. package/build/prepare-domains-render.js +73 -0
  21. package/build/prepare-domains-render.js.map +7 -0
  22. package/build/react/Favicon/index.d.ts +5 -0
  23. package/build/react/Favicon/utils.d.ts +9 -0
  24. package/build/react/GriddoIntegrations/index.d.ts +20 -0
  25. package/build/react/GriddoIntegrations/utils.d.ts +26 -0
  26. package/build/react/index.d.ts +3 -0
  27. package/build/react/index.js +3 -0
  28. package/build/registers/api.d.ts +9 -0
  29. package/build/registers/gatsby.d.ts +9 -0
  30. package/build/registers/index.d.ts +3 -0
  31. package/build/reset-render.js +74 -0
  32. package/build/reset-render.js.map +7 -0
  33. package/build/services/auth.d.ts +5 -2
  34. package/build/services/domains.d.ts +6 -0
  35. package/build/services/navigation.d.ts +50 -0
  36. package/build/services/reference-fields.d.ts +20 -0
  37. package/build/services/register.d.ts +36 -0
  38. package/build/services/robots.d.ts +19 -0
  39. package/build/services/settings.d.ts +4 -0
  40. package/build/services/sites.d.ts +29 -0
  41. package/build/services/store.d.ts +6 -0
  42. package/build/start-render.js +100 -0
  43. package/build/start-render.js.map +7 -0
  44. package/build/{shared/types → types}/api.d.ts +18 -18
  45. package/build/{shared/types → types}/global.d.ts +16 -15
  46. package/build/{shared/types → types}/navigation.d.ts +5 -5
  47. package/build/{shared/types → types}/pages.d.ts +9 -9
  48. package/build/{shared/types → types}/sites.d.ts +19 -18
  49. package/build/types/templates.d.ts +8 -0
  50. package/build/upload-search-content.js +74 -0
  51. package/build/upload-search-content.js.map +7 -0
  52. package/build/utils/alerts.d.ts +3 -0
  53. package/build/utils/api.d.ts +23 -0
  54. package/build/utils/cache.d.ts +35 -0
  55. package/build/utils/core-utils.d.ts +107 -0
  56. package/build/utils/create-build-data.d.ts +8 -0
  57. package/build/utils/domains.d.ts +13 -0
  58. package/build/utils/folders.d.ts +53 -0
  59. package/build/utils/health-checks.d.ts +7 -0
  60. package/build/utils/images.d.ts +16 -0
  61. package/build/utils/loggin.d.ts +51 -0
  62. package/build/utils/pages.d.ts +34 -0
  63. package/build/utils/render.d.ts +13 -0
  64. package/build/utils/searches.d.ts +15 -0
  65. package/build/utils/sites.d.ts +31 -0
  66. package/build/utils/store.d.ts +81 -0
  67. package/cx.config.d.ts +5 -0
  68. package/cx.config.js +36 -0
  69. package/exporter/adapters/gatsby/index.ts +162 -0
  70. package/exporter/adapters/gatsby/utils.ts +161 -0
  71. package/exporter/artifacts/README.md +34 -0
  72. package/exporter/artifacts/index.ts +33 -0
  73. package/exporter/build.sh +28 -17
  74. package/exporter/commands/end-render.ts +86 -65
  75. package/exporter/commands/move-assets.ts +11 -0
  76. package/exporter/commands/prepare-domains-render.ts +35 -143
  77. package/exporter/commands/reset-render.ts +7 -12
  78. package/exporter/commands/start-render.ts +64 -26
  79. package/exporter/commands/upload-search-content.ts +26 -201
  80. package/exporter/{shared → constants}/endpoints.ts +11 -12
  81. package/exporter/constants/envs.ts +94 -0
  82. package/exporter/constants/index.ts +129 -0
  83. package/exporter/{shared/errors.ts → errors/errors-data.ts} +14 -24
  84. package/exporter/errors/index.ts +40 -0
  85. package/exporter/index.ts +56 -14
  86. package/{react/GriddoFavicon → exporter/react/Favicon}/index.tsx +9 -3
  87. package/{react → exporter/react}/GriddoIntegrations/index.tsx +23 -17
  88. package/{react → exporter/react}/GriddoIntegrations/utils.ts +12 -24
  89. package/exporter/react/index.tsx +11 -0
  90. package/exporter/registers/api.ts +14 -0
  91. package/exporter/registers/gatsby.ts +14 -0
  92. package/exporter/registers/index.ts +4 -0
  93. package/exporter/services/auth.ts +10 -8
  94. package/exporter/services/domains.ts +8 -23
  95. package/exporter/services/navigation.ts +18 -12
  96. package/exporter/services/reference-fields.ts +32 -14
  97. package/exporter/services/register.ts +113 -0
  98. package/exporter/services/robots.ts +61 -33
  99. package/exporter/services/settings.ts +17 -0
  100. package/exporter/services/sites.ts +28 -40
  101. package/exporter/services/store.ts +319 -386
  102. package/exporter/{shared/types → types}/api.ts +41 -40
  103. package/exporter/{shared/types → types}/global.ts +21 -17
  104. package/exporter/{shared/types → types}/navigation.ts +3 -3
  105. package/exporter/{shared/types → types}/pages.ts +11 -10
  106. package/exporter/{shared/types → types}/sites.ts +19 -18
  107. package/exporter/utils/alerts.ts +29 -0
  108. package/exporter/utils/api.ts +243 -0
  109. package/exporter/utils/cache.ts +142 -0
  110. package/exporter/utils/core-utils.ts +458 -0
  111. package/exporter/utils/create-build-data.ts +17 -0
  112. package/exporter/utils/domains.ts +39 -0
  113. package/exporter/utils/folders.ts +320 -0
  114. package/exporter/utils/health-checks.ts +64 -0
  115. package/exporter/{core → utils}/images.ts +6 -1
  116. package/exporter/{core → utils}/instance.ts +13 -9
  117. package/exporter/utils/loggin.ts +184 -0
  118. package/exporter/{services → utils}/pages.ts +92 -27
  119. package/exporter/utils/render.ts +71 -0
  120. package/exporter/utils/searches.ts +156 -0
  121. package/exporter/utils/sites.ts +312 -0
  122. package/exporter/utils/store.ts +314 -0
  123. package/gatsby-browser.tsx +58 -41
  124. package/gatsby-config.ts +17 -10
  125. package/gatsby-node.ts +80 -20
  126. package/gatsby-ssr.tsx +1 -2
  127. package/package.json +92 -41
  128. package/src/README.md +7 -0
  129. package/src/components/Head.tsx +73 -30
  130. package/src/components/template.tsx +30 -8
  131. package/src/gatsby-node-utils.ts +2 -76
  132. package/src/html.tsx +11 -2
  133. package/src/types.ts +5 -5
  134. package/start-render.js +7 -0
  135. package/tsconfig.json +3 -5
  136. package/build/commands/end-render.js +0 -31
  137. package/build/commands/end-render.js.map +0 -7
  138. package/build/commands/prepare-assets-directory.js +0 -9
  139. package/build/commands/prepare-assets-directory.js.map +0 -7
  140. package/build/commands/prepare-domains-render.js +0 -38
  141. package/build/commands/prepare-domains-render.js.map +0 -7
  142. package/build/commands/reset-render.js +0 -31
  143. package/build/commands/reset-render.js.map +0 -7
  144. package/build/commands/start-embeddings.js +0 -31
  145. package/build/commands/start-embeddings.js.map +0 -7
  146. package/build/commands/start-render.js +0 -66
  147. package/build/commands/start-render.js.map +0 -7
  148. package/build/commands/upload-search-content.js +0 -31
  149. package/build/commands/upload-search-content.js.map +0 -7
  150. package/build/core/GriddoLog.d.ts +0 -16
  151. package/build/core/db.d.ts +0 -4
  152. package/build/core/dist-rollback.d.ts +0 -2
  153. package/build/core/fs.d.ts +0 -69
  154. package/build/core/logger.d.ts +0 -18
  155. package/build/services/manage-store.d.ts +0 -48
  156. package/build/services/render.d.ts +0 -70
  157. package/build/shared/envs.d.ts +0 -19
  158. package/build/shared/npm-modules/brush.d.ts +0 -18
  159. package/build/shared/npm-modules/find-up-simple.d.ts +0 -34
  160. package/build/shared/npm-modules/pkg-dir.d.ts +0 -7
  161. package/build/shared/types/render.d.ts +0 -54
  162. package/cli.mjs +0 -239
  163. package/exporter/build-esbuild.noop +0 -42
  164. package/exporter/commands/README.md +0 -151
  165. package/exporter/commands/prepare-assets-directory.ts +0 -34
  166. package/exporter/commands/single-domain-upload-search-content.noop +0 -206
  167. package/exporter/commands/start-embeddings.ts +0 -29
  168. package/exporter/core/GriddoLog.ts +0 -45
  169. package/exporter/core/check-env-health.ts +0 -200
  170. package/exporter/core/db-class.ts +0 -54
  171. package/exporter/core/db.ts +0 -33
  172. package/exporter/core/dist-rollback.ts +0 -40
  173. package/exporter/core/errors.ts +0 -82
  174. package/exporter/core/fs.ts +0 -385
  175. package/exporter/core/life-cycle.ts +0 -73
  176. package/exporter/core/logger.ts +0 -141
  177. package/exporter/core/objects.ts +0 -37
  178. package/exporter/core/print-logos.ts +0 -21
  179. package/exporter/services/api.ts +0 -306
  180. package/exporter/services/manage-sites.ts +0 -116
  181. package/exporter/services/manage-store.ts +0 -235
  182. package/exporter/services/render-artifacts.ts +0 -44
  183. package/exporter/services/render.ts +0 -229
  184. package/exporter/services/sitemaps.ts +0 -129
  185. package/exporter/shared/context.ts +0 -49
  186. package/exporter/shared/envs.ts +0 -62
  187. package/exporter/shared/npm-modules/README.md +0 -36
  188. package/exporter/shared/npm-modules/brush.ts +0 -34
  189. package/exporter/shared/npm-modules/find-up-simple.ts +0 -100
  190. package/exporter/shared/npm-modules/pkg-dir.ts +0 -17
  191. package/exporter/shared/npm-modules/xml-parser.ts +0 -57
  192. package/exporter/shared/types/render.ts +0 -63
  193. package/exporter/ssg-adapters/gatsby/actions/clean.ts +0 -26
  194. package/exporter/ssg-adapters/gatsby/actions/close.ts +0 -17
  195. package/exporter/ssg-adapters/gatsby/actions/data.ts +0 -22
  196. package/exporter/ssg-adapters/gatsby/actions/healthCheck.ts +0 -10
  197. package/exporter/ssg-adapters/gatsby/actions/init.ts +0 -12
  198. package/exporter/ssg-adapters/gatsby/actions/logs.ts +0 -10
  199. package/exporter/ssg-adapters/gatsby/actions/meta.ts +0 -13
  200. package/exporter/ssg-adapters/gatsby/actions/prepare.ts +0 -9
  201. package/exporter/ssg-adapters/gatsby/actions/relocation.ts +0 -15
  202. package/exporter/ssg-adapters/gatsby/actions/restore.ts +0 -21
  203. package/exporter/ssg-adapters/gatsby/actions/ssg.ts +0 -12
  204. package/exporter/ssg-adapters/gatsby/actions/sync.ts +0 -65
  205. package/exporter/ssg-adapters/gatsby/index.ts +0 -114
  206. package/exporter/ssg-adapters/gatsby/shared/artifacts.ts +0 -16
  207. package/exporter/ssg-adapters/gatsby/shared/diff-assets.ts +0 -128
  208. package/exporter/ssg-adapters/gatsby/shared/extract-assets.ts +0 -75
  209. package/exporter/ssg-adapters/gatsby/shared/gatsby-build.ts +0 -58
  210. package/exporter/ssg-adapters/gatsby/shared/sync-render.ts +0 -300
  211. package/exporter/ssg-adapters/gatsby/shared/types.ts +0 -35
  212. package/exporter/ssg-adapters/gatsby/shared/utils.ts +0 -33
  213. package/plugins/gatsby-plugin-svgr-loader/gatsby-node.js +0 -55
  214. package/plugins/gatsby-plugin-svgr-loader/package.json +0 -8
  215. package/react/DynamicScript/index.tsx +0 -33
  216. package/react/GriddoOpenGraph/index.tsx +0 -39
  217. package/tsconfig.commands.json +0 -36
  218. package/tsconfig.exporter.json +0 -20
  219. /package/build/{shared → constants}/endpoints.d.ts +0 -0
  220. /package/build/{core → utils}/instance.d.ts +0 -0
  221. /package/{react/GriddoFavicon → exporter/react/Favicon}/utils.ts +0 -0
  222. /package/exporter/{shared/types → types}/templates.ts +0 -0
@@ -1,306 +0,0 @@
1
- import type {
2
- APIRequest,
3
- APIResponses,
4
- GetAPI,
5
- PostAPI,
6
- PutAPI,
7
- ShowApiErrorOptions,
8
- } from "../shared/types/api";
9
- import type { Petition } from "../shared/types/global";
10
-
11
- import crypto from "node:crypto";
12
- import fsp from "node:fs/promises";
13
- import path from "node:path";
14
-
15
- import { RenderError } from "../core/errors";
16
- import { pathExists } from "../core/fs";
17
- import { GriddoLog } from "../core/GriddoLog";
18
- import { addLogToBuffer } from "../core/logger";
19
- import { brush } from "../shared/npm-modules/brush";
20
- import { AuthService } from "./auth";
21
- import { getRenderPathsHydratedWithDomainFromDB } from "./render";
22
-
23
- // Envs
24
- const { env } = process;
25
- const { RETRY_WAIT_SECONDS = "4", RETRY_ATTEMPTS = "4" } = env;
26
-
27
- /**
28
- * Make a GET/PUT/POST request to the Griddo API.
29
- *
30
- * @template T Response Type returned.
31
- * @returns {Promise<T>} A promise that is resolved with the data from the API response.
32
- *
33
- * @example
34
- * const response = await requestAPI<Site>(
35
- * { endpoint: "...", cacheKey: "...", ... },
36
- * "get",
37
- * "..."
38
- * );
39
- */
40
- async function requestAPI<T extends APIResponses>(
41
- props: APIRequest,
42
- method: string,
43
- appendToLog = "",
44
- ): Promise<T> {
45
- const {
46
- endpoint,
47
- body,
48
- cacheKey = "",
49
- attempt = 1,
50
- headers,
51
- useApiCacheDir = true,
52
- logToFile = true,
53
- } = props;
54
- const cacheOptions = { endpoint, body, headers, cacheKey };
55
-
56
- // Cache
57
- if (cacheKey && useApiCacheDir) {
58
- const start = new Date();
59
- const cacheData = await searchCacheData<T>(cacheOptions);
60
-
61
- if (cacheData) {
62
- if (logToFile) {
63
- const siteId = getSafeSiteId(cacheData);
64
- const siteIdMsg = siteId ? `site: ${siteId}` : "";
65
- const duration = msToSec(Date.now() - start.getTime());
66
- addLogToBuffer(`${method} (cache) ${siteIdMsg} ${endpoint} - ${duration}s ${appendToLog}`);
67
- }
68
- return cacheData;
69
- }
70
- }
71
-
72
- // Network
73
- try {
74
- const start = new Date();
75
-
76
- // Prepare fetch options
77
- const fetchOptions: RequestInit = {
78
- method: method.toUpperCase(),
79
- headers: Object.assign({}, headers, AuthService.headers) as Record<string, string>,
80
- };
81
-
82
- // Add body for non-GET requests
83
- if (method.toLowerCase() !== "get" && body) {
84
- fetchOptions.body = JSON.stringify(body);
85
- if (!fetchOptions.headers) fetchOptions.headers = {};
86
- (fetchOptions.headers as Record<string, string>)["Content-Type"] = "application/json";
87
- }
88
-
89
- const response = await fetch(endpoint, fetchOptions);
90
-
91
- // Handle non-2xx responses
92
- if (!response.ok) {
93
- if (response.status === 404) {
94
- // @ts-expect-error page maybe will be 404
95
- return null;
96
- }
97
-
98
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
99
- }
100
-
101
- const data: T = await response.json();
102
-
103
- if (logToFile) {
104
- const siteId = getSafeSiteId(data);
105
- const siteIdMsg = siteId ? `site: ${siteId}` : "";
106
- const duration = msToSec(Date.now() - start.getTime());
107
- addLogToBuffer(`${method} (fetch) ${siteIdMsg} ${endpoint} - ${duration}s ${appendToLog}`);
108
- }
109
-
110
- if (useApiCacheDir) {
111
- await saveCache(cacheOptions, data);
112
- }
113
-
114
- return data;
115
- } catch (e) {
116
- const error = e as Error;
117
-
118
- if (attempt > parseInt(RETRY_ATTEMPTS)) {
119
- GriddoLog.log(`
120
- Max attempts ${RETRY_ATTEMPTS} reached
121
- --------------------------------------
122
- - ${method.toUpperCase()} ${endpoint}
123
- - BODY: ${JSON.stringify(body)}
124
- - HEADERS: ${JSON.stringify(headers)}
125
- - ERROR: ${error.message}
126
- --------------------------------------
127
- `);
128
- throw new RenderError(error);
129
- }
130
-
131
- showApiError(error, {
132
- callInfo: { endpoint, body },
133
- });
134
-
135
- GriddoLog.warn(`Waiting for retry: ${method}`, endpoint);
136
-
137
- await delay(parseInt(RETRY_WAIT_SECONDS) * 1000);
138
-
139
- return requestAPI<T>(
140
- {
141
- endpoint,
142
- body,
143
- headers,
144
- cacheKey,
145
- attempt: attempt + 1,
146
- },
147
- method,
148
- appendToLog,
149
- );
150
- }
151
- }
152
-
153
- /**
154
- * Make a GET request to the Griddo API.
155
- *
156
- * @template T Response Type returned.
157
- * @returns A promise that is resolved with the data from the API response.
158
- */
159
- async function getApi<T extends APIResponses>(props: GetAPI) {
160
- return requestAPI<T>(props, "get");
161
- }
162
-
163
- /**
164
- * Make a PUT request to the Griddo API.
165
- *
166
- * @template T Response Type returned.
167
- * @returns A promise that is resolved with the data from the API response.
168
- */
169
- async function putApi<T extends APIResponses>(props: PutAPI) {
170
- return requestAPI<T>(props, "put");
171
- }
172
-
173
- /**
174
- * Make a POST request to the Griddo API.
175
- *
176
- * @template T Response Type returned.
177
- * @returns A promise that is resolved with the data from the API response.
178
- */
179
- async function postApi<T extends APIResponses>(props: PostAPI) {
180
- const { endpoint, body, headers } = props;
181
- const referenceFieldBodyParams =
182
- endpoint.endsWith("/distributor") &&
183
- `# ReferenceField body: ${JSON.stringify(body)} lang: ${JSON.stringify(headers?.lang)}`;
184
-
185
- return requestAPI<T>(props, "post", referenceFieldBodyParams || "");
186
- }
187
-
188
- /**
189
- * Shows an API error through the terminal.
190
- */
191
- function showApiError(error: Error, options: ShowApiErrorOptions) {
192
- const { message, stack } = error;
193
- const { callInfo } = options;
194
- const callInfoArray = [];
195
-
196
- for (const item of Object.keys(callInfo) as (keyof typeof callInfo)[]) {
197
- callInfoArray.push(
198
- `${item}: ${
199
- typeof callInfo[item] === "object" ? JSON.stringify(callInfo[item]) : callInfo[item]
200
- }`,
201
- );
202
- }
203
-
204
- // Compose the errors output
205
- const callInfoStr = callInfoArray.join("\n");
206
- const errorDetailsStr = `${message}\n${stack}`;
207
-
208
- // Print the error
209
- GriddoLog.warn(
210
- brush.red(`
211
- =============
212
-
213
- { Call info }
214
- ${callInfoStr}
215
-
216
- { Error details }
217
- ${errorDetailsStr}
218
-
219
- =============
220
- `),
221
- );
222
- }
223
-
224
- /**
225
- * Return a siteID from a response object if exist
226
- * @param response A response object
227
- */
228
- function getSafeSiteId(response: APIResponses) {
229
- if (typeof response !== "object" || response === null || Array.isArray(response)) {
230
- return undefined;
231
- }
232
-
233
- return "site" in response && response.site ? response.site : undefined;
234
- }
235
-
236
- /**
237
- * Custom delay using the "promise hack",
238
- *
239
- * @param ms Amount of miliseconds to be delayed
240
- */
241
- function delay(ms: number): Promise<void> {
242
- return new Promise((res) => setTimeout(res, ms));
243
- }
244
-
245
- /**
246
- * Converts milliseconds to seconds with a fixed number of decimals.
247
- *
248
- * @param ms The number in milliseconds.
249
- * @param fixed The amount of fixed decimals.
250
- * @returns The converted number in seconds with the fixed number of decimals.
251
- */
252
- function msToSec(ms: number, decimals = 3): number {
253
- return Number.parseFloat((ms / 1000).toFixed(decimals));
254
- }
255
-
256
- /**
257
- * Generate a filename with a hash using a Petition object
258
- * @param petition An object
259
- */
260
- async function generateFilenameWithHash(petition: Petition) {
261
- const { __root } = await getRenderPathsHydratedWithDomainFromDB();
262
- const apiCacheDir = path.join(__root, "apiCache");
263
-
264
- const hashSum = crypto.createHash("sha256");
265
- hashSum.update(JSON.stringify(petition));
266
-
267
- return `${apiCacheDir}/${hashSum.digest("hex")}`;
268
- }
269
-
270
- /**
271
- * Save a file using a hash name.
272
- *
273
- * @param petition An object.
274
- * @param content Content to be saved.
275
- */
276
- async function saveCache<T>(petition: Petition, content: T) {
277
- const stringContent = typeof content === "string" ? content : JSON.stringify(content);
278
- const filename = await generateFilenameWithHash(petition);
279
- const filepath = path.dirname(filename);
280
-
281
- if (!(await pathExists(filepath))) {
282
- await fsp.mkdir(filepath, { recursive: true });
283
- }
284
-
285
- await fsp.writeFile(filename, stringContent, "utf8");
286
- }
287
-
288
- /**
289
- * Search in the `apiCache` dir for a file using the petition as hash generator.
290
- * Return the file content if found or null if not.
291
- *
292
- * @param petition An object
293
- */
294
- async function searchCacheData<T>(petition: Petition) {
295
- try {
296
- const file = await generateFilenameWithHash(petition);
297
- const fileContent = await fsp.readFile(file, "utf8");
298
- const jsonData = JSON.parse(fileContent) as T;
299
-
300
- return jsonData;
301
- } catch {
302
- return null;
303
- }
304
- }
305
-
306
- export { getApi as get, postApi as post, putApi as put };
@@ -1,116 +0,0 @@
1
- import type { Site, SiteData } from "../shared/types/sites";
2
-
3
- import fsp from "node:fs/promises";
4
- import path from "node:path";
5
-
6
- import { getRenderPathsHydratedWithDomainFromDB } from "./render";
7
- import {
8
- endSiteRender,
9
- getAllSites,
10
- getSiteInfo,
11
- getSiteLanguages,
12
- getSiteSocials,
13
- startSiteRender,
14
- } from "./sites";
15
-
16
- /**
17
- * Check the instance sites and returns site prepared to be published and unpublished.
18
- */
19
- async function getSitesToRender(domain: string) {
20
- // Get all sites. An array of Site
21
- const allSites = await getAllSites(domain);
22
-
23
- // If there are valid sites...
24
- // En este paso se añade al objeto `Site` la información de los dominios
25
- // utilizando los idiomas.
26
- if (allSites.length) {
27
- for (const site of allSites) {
28
- const { items } = await getSiteLanguages(site.id);
29
-
30
- // Añadimos la prop site.domains con el dominio "cocinado" con
31
- // los idiomas y teniendo en cuenta solo el dominio actual.
32
- site.domains = items
33
- .filter(
34
- (item) =>
35
- item.domain && (item.domain.slug === domain || item.domain.slug === `/${domain}`),
36
- )
37
- .map((item) => ({ [item.id]: `${item.domain.slug}${item.path}` }));
38
- }
39
- }
40
-
41
- // Save sites object to publish
42
- const sitesToPublish = allSites.filter((site) => !!site.isPublished);
43
-
44
- // Save sites object to unpublish
45
- const sitesToUnpublish = allSites.filter((site) => !site.isPublished && site.shouldBeUpdated);
46
-
47
- return {
48
- sitesToPublish,
49
- sitesToUnpublish,
50
- };
51
- }
52
-
53
- /**
54
- * Unpublish an array of sites sending the information to the API.
55
- *
56
- * @param sites An array of sites
57
- */
58
- async function unpublishSites(sites: Site[]) {
59
- const { __root } = await getRenderPathsHydratedWithDomainFromDB();
60
-
61
- for (const site of sites) {
62
- // API
63
- const buildInfo = await startSiteRender(site.id);
64
- const { siteHash } = buildInfo;
65
- const body = {
66
- siteHash,
67
- publishHashes: [],
68
- unpublishHashes: [],
69
- publishPagesIds: [],
70
- };
71
-
72
- await endSiteRender(site.id, body);
73
-
74
- // STORE
75
- // Remove site directory from the Store to prevent rendering
76
- await fsp.rm(path.join(__root, "store", site.id.toString()), {
77
- force: true,
78
- recursive: true,
79
- });
80
- }
81
- }
82
-
83
- /**
84
- * Return a single site generic data.
85
- *
86
- * @param siteID The site id.
87
- * @see SiteData
88
- */
89
- async function getSiteData(siteID: number) {
90
- const buildData = await startSiteRender(siteID);
91
- const siteInfo = await getSiteInfo(siteID);
92
- const siteLangs = await getSiteLanguages(siteID);
93
- const socials = await getSiteSocials(siteID);
94
- const siteLangsInfo = siteLangs.items;
95
- const defaultLang = siteLangsInfo.find((lang) => lang.isDefault);
96
-
97
- const { siteHash, unpublishHashes, publishIds } = buildData;
98
- const { headers, footers } = siteInfo;
99
- const validPagesIds = publishIds;
100
-
101
- const siteData: SiteData = {
102
- siteInfo,
103
- validPagesIds,
104
- siteHash,
105
- unpublishHashes,
106
- siteLangs: siteLangsInfo,
107
- defaultLang,
108
- headers,
109
- footers,
110
- socials,
111
- };
112
-
113
- return siteData;
114
- }
115
-
116
- export { getSiteData, getSitesToRender, unpublishSites };
@@ -1,235 +0,0 @@
1
- import type { BuildMetaData } from "../shared/types/api";
2
- import type { RenderInfo } from "../shared/types/global";
3
- import type { GriddoPageObject } from "../shared/types/pages";
4
- import type { Site } from "../shared/types/sites";
5
-
6
- import fsp from "node:fs/promises";
7
- import path from "node:path";
8
-
9
- import { readDB, writeDB } from "../core/db";
10
- import { throwError } from "../core/errors";
11
- import { pathExists } from "../core/fs";
12
- import { GriddoLog } from "../core/GriddoLog";
13
- import { WriteToStoreError } from "../shared/errors";
14
- import { getRenderPathsHydratedWithDomainFromDB } from "./render";
15
-
16
- /**
17
- * Get the build metadata from the Store.
18
- */
19
- async function getBuildMetadata(domain: string): Promise<BuildMetaData> {
20
- const db = await readDB();
21
- const { sitesToPublish, createdPages, buildProcessData } = db.domains[domain].renderInfo || {};
22
-
23
- if (!sitesToPublish || !createdPages || !buildProcessData) {
24
- throw new Error("Build metadata not found");
25
- }
26
-
27
- return {
28
- buildProcessData,
29
- createdPages,
30
- sitesToPublish,
31
- };
32
- }
33
-
34
- /**
35
- * Write render info into a file.
36
- * @param renderInfo - Data that will be saved related to the render process.
37
- */
38
- async function saveRenderInfoInStore(renderInfo: RenderInfo, domain: string) {
39
- const db = await readDB();
40
- db.domains[domain] = db.domains[domain] || {};
41
- db.domains[domain].renderInfo = renderInfo;
42
- await writeDB(db);
43
- }
44
-
45
- /**
46
- * Return an array of paths only from `.json` files (no dirs) in the `basePath` dir based in the file name.
47
- * @param basePath - Absolute path of the dir from which files will be read.
48
- * @returns A number[] of pages ids in `basePath` dir.
49
- */
50
- async function getPageInStoreDir(basePath: string) {
51
- const filesInStore = await fsp.readdir(basePath);
52
-
53
- return filesInStore
54
- .filter(async (file) => {
55
- const fullPathFile = `${basePath}/${file}`;
56
- const stat = await fsp.stat(fullPathFile);
57
- // Si es un directorio, no lo incluimos.
58
- if (stat?.isDirectory()) {
59
- return false;
60
- }
61
-
62
- // Si es un archivo pero no tiene la extensión `.json`, no lo incluimos
63
- if (path.extname(file) !== ".json") {
64
- return false;
65
- }
66
-
67
- // no es dir, es json.
68
- return true;
69
- })
70
- .map((page) => {
71
- return path.join(basePath, page);
72
- });
73
- }
74
-
75
- /**
76
- * Save the pages into the file system.
77
- * @param pages - An array of Griddo page objects to be saved.
78
- */
79
- async function saveSitePagesInStore(siteDirName: string, pages: GriddoPageObject[]) {
80
- const { __root } = await getRenderPathsHydratedWithDomainFromDB();
81
-
82
- try {
83
- const propsToRemove = new Set(["editorID", "parentEditorID"]);
84
- for (const page of pages) {
85
- removeProperties(page, propsToRemove);
86
- const filename = `${page.context.page.id}.json`;
87
- const filePath = path.join(__root, "store", siteDirName, filename);
88
- // En los listados estáticos y multipage los ids de las páginas son iguales
89
- await writeUniqueFileSync(filePath, JSON.stringify(page));
90
- }
91
- } catch (error) {
92
- throwError(WriteToStoreError, error);
93
- }
94
- }
95
-
96
- /**
97
- * Removes JSON files from the specified site directory based on the provided arrays of page numbers.
98
- * For each number in the arrays, a corresponding file with the format `<number>.json` is removed if it exists.
99
- *
100
- * WARNING: This function may end up handling large arrays, so don't be tempted
101
- * to refactor it to use something cool like the spread operator and make a
102
- * single array, etc..
103
- *
104
- * @param siteDirName - The name of the site directory containing the pages.
105
- * @param pageIdsArray - A two-dimensional array where each inner array contains numbers representing page files to be removed.
106
- */
107
- async function removeSitePagesFromStore(siteDirName: string, pageIdsArray: number[][]) {
108
- const { __root } = await getRenderPathsHydratedWithDomainFromDB();
109
-
110
- const processPageIdsArray = async (pageIds: number[]) => {
111
- for (const filename of pageIds) {
112
- const filePath = path.join(__root, "store", siteDirName, `${filename}.json`);
113
- try {
114
- if (await pathExists(filePath)) {
115
- await fsp.unlink(filePath);
116
- GriddoLog.verbose(`Removed file: ${filePath}`);
117
- }
118
- } catch (_error) {
119
- throw new Error(`Error removing file ${filename}`);
120
- }
121
- }
122
- };
123
-
124
- for (const pageIds of pageIdsArray) {
125
- await processPageIdsArray(pageIds);
126
- }
127
- }
128
-
129
- /**
130
- * Removes sites that exist in the store that should no longer be there because
131
- * the domain has been changed. This is necessary because those sites will not
132
- * be marked as `sitesToUnpublish` so they must be removed manually.
133
- */
134
- async function removeOrphanSites(sitesToPublish: Site[], domain: string) {
135
- const { __root } = await getRenderPathsHydratedWithDomainFromDB({ domain });
136
- const storePath = path.join(__root, "store");
137
-
138
- if (!(await pathExists(storePath))) {
139
- return;
140
- }
141
-
142
- const currentSitesInStore = await fsp.readdir(storePath);
143
- const sitesFromAPI = sitesToPublish.map(({ id }) => `${id}`);
144
- const sitesToDelete = currentSitesInStore.filter((site) => !sitesFromAPI.includes(site));
145
-
146
- for (const site of sitesToDelete) {
147
- await fsp.rm(path.join(storePath, site), { recursive: true, force: true });
148
- GriddoLog.verbose(`Removed orphan site id: ${site}`);
149
- }
150
- }
151
-
152
- /**
153
- * Get pages that are not active anymore but are in the store.
154
- */
155
- async function getZombiePagesInStore(siteDir: string, activePages: number[]) {
156
- const { __root } = await getRenderPathsHydratedWithDomainFromDB();
157
- const storeDir = path.join(__root, "store", siteDir);
158
- const sitePages = await fsp.readdir(storeDir);
159
-
160
- const zombiePages: number[] = [];
161
- for (const pageFileName of sitePages) {
162
- const pageFileNameWithoutExtension = pageFileName.split(".")[0];
163
- const pageInStore = Number.parseInt(pageFileNameWithoutExtension);
164
-
165
- // What the hell is `pageIdInStore > 0` ??
166
- // Las páginas de listados estáticos y multipage tiene ids "basura", que
167
- // en este caso son ids negativos y siempre so borran al final del render.
168
- // En este caso hay que ignorarlas porque NUNCA van a estar en el
169
- // `activePages`, estaríamos borrándolas siempre antes de la fase de
170
- // SSG.
171
- if (!activePages.includes(pageInStore) && pageInStore > 0) {
172
- zombiePages.push(pageInStore);
173
- }
174
- }
175
-
176
- return zombiePages;
177
- }
178
-
179
- async function writeUniqueFileSync(filePath: string, content: string) {
180
- const dir = path.dirname(filePath);
181
- const ext = path.extname(filePath);
182
- const base = path.basename(filePath, ext);
183
-
184
- let uniquePath = filePath;
185
- let counter = 1;
186
-
187
- while (await pathExists(uniquePath)) {
188
- const newName = `${base}-${counter}${ext}`;
189
- uniquePath = path.join(dir, newName);
190
- counter++;
191
- }
192
-
193
- await fsp.writeFile(uniquePath, content);
194
- }
195
-
196
- /**
197
- * Remove props from an object
198
- *
199
- * @param obj The object
200
- * @param props An array of props to be removed
201
- */
202
- function removeProperties(obj: Record<string, unknown>, propsToRemove: Set<string>) {
203
- function remove(currentObj: Record<string, unknown>) {
204
- if (!currentObj || typeof currentObj !== "object" || Array.isArray(currentObj)) {
205
- return;
206
- }
207
-
208
- for (const key in currentObj) {
209
- if (Object.hasOwn(currentObj, key)) {
210
- if (propsToRemove.has(key)) {
211
- // Búsqueda O(1) en lugar de O(n)
212
- delete currentObj[key];
213
- } else {
214
- const value = currentObj[key];
215
- if (typeof value === "object" && value !== null && !Array.isArray(value)) {
216
- remove(value as Record<string, unknown>);
217
- }
218
- }
219
- }
220
- }
221
- }
222
-
223
- remove(obj);
224
- }
225
-
226
- export {
227
- getBuildMetadata,
228
- getPageInStoreDir,
229
- getZombiePagesInStore,
230
- removeOrphanSites,
231
- removeSitePagesFromStore,
232
- saveRenderInfoInStore,
233
- saveSitePagesInStore,
234
- writeUniqueFileSync,
235
- };
@@ -1,44 +0,0 @@
1
- import type { RenderArtifacts } from "../shared/types/global";
2
-
3
- import path from "node:path";
4
-
5
- import { getRenderPathsHydratedWithDomainFromDB } from "./render";
6
-
7
- /**
8
- * Returns the artifacts of CX.
9
- */
10
- async function getRenderArtifacts(domain: string): Promise<RenderArtifacts> {
11
- const { __exports, __cache, __root, __ssg } = await getRenderPathsHydratedWithDomainFromDB({
12
- domain,
13
- });
14
-
15
- return {
16
- initials: [
17
- __exports, // `<root>/exports/<domain>`
18
- __cache, // `<root>/.cx-cache/<domain>`
19
- path.join(__exports, "logs"),
20
- path.join(__root, "store"),
21
- path.join(__root, "apiCache"),
22
- ],
23
- disposables: [
24
- path.join(__root, "store"),
25
- path.join(__root, "apiCache"),
26
- path.join(__root, "dist"),
27
- path.join(__root, "dist-restored"),
28
- path.join(__root, "assets"),
29
- path.join(__root, "render-detail-log.txt"),
30
- path.join(__root, "current-dist"),
31
- path.join(__ssg, "domains.json"),
32
- path.join(__ssg, "render-metadata.json"),
33
- ],
34
- cacheables: [],
35
- archivables: [
36
- // dist ya se usa directamente en exports
37
- // "dist",
38
- "assets",
39
- ],
40
- restaurable: ["dist"],
41
- };
42
- }
43
-
44
- export { getRenderArtifacts };