@griddo/cx 10.3.26 → 10.4.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.
@@ -6,14 +6,8 @@ import type {
6
6
  GriddoSinglePage,
7
7
  PageAdditionalInfo,
8
8
  } from "../types/pages";
9
- import type { Site } from "../types/sites";
10
-
11
- import fs from "node:fs";
12
- import fsp from "node:fs/promises";
13
- import path from "node:path";
14
9
 
15
10
  import dotenv from "dotenv";
16
- import fsx from "fs-extra";
17
11
  import pLimit from "p-limit";
18
12
 
19
13
  import { DistributorService } from "./distributors";
@@ -21,8 +15,7 @@ import { NavigationService } from "./navigation";
21
15
  import { SettingsService } from "./settings";
22
16
  import { SitesService } from "./sites";
23
17
  import { version as griddoVersion } from "../../package.json";
24
- import { createSha256, updatedSiteHash } from "../utils/cache";
25
- import { deleteSites } from "../utils/folders";
18
+ import { updatedSiteHash } from "../utils/cache";
26
19
  import {
27
20
  createGriddoListPages,
28
21
  createGriddoMultiPages,
@@ -30,25 +23,27 @@ import {
30
23
  getMultiPageElements,
31
24
  getPaginatedPages,
32
25
  } from "../utils/pages";
33
- import { logInfo, removeProperties, siteList } from "../utils/shared";
26
+ import { logBox, logInfo, siteList } from "../utils/shared";
34
27
  import { checkSites, getSiteData, unpublishSites } from "../utils/sites";
28
+ import {
29
+ getPagesToCreateOrDelete,
30
+ removePagesFromStore,
31
+ savePagesInStore,
32
+ saveRenderInfoInStore,
33
+ } from "../utils/store";
35
34
 
36
35
  dotenv.config();
37
36
 
38
37
  // Envs
39
- const API_URL = process.env.API_URL as string;
40
- const CXBRANCH = process.env.CXBRANCH;
41
- // prettier-ignore
42
- const REACT_APP_INSTANCE = process.env.GRIDDO_REACT_APP_INSTANCE || process.env.REACT_APP_INSTANCE;
43
- // prettier-ignore
44
- const API_CONCURRENCY_COUNT = parseInt(process.env.GRIDDO_API_CONCURRENCY_COUNT || "") || 10;
45
- const PUBLIC_API_URL = process.env.PUBLIC_API_URL as string;
46
- // prettier-ignore
47
- const RENDER_ID = process.env.GRIDDO_RENDERID || new Date().valueOf().toString();
38
+ /* prettier-ignore */ const API_URL = process.env.API_URL as string;
39
+ /* prettier-ignore */ const REACT_APP_INSTANCE = process.env.GRIDDO_REACT_APP_INSTANCE || process.env.REACT_APP_INSTANCE;
40
+ /* prettier-ignore */ const API_CONCURRENCY_COUNT = parseInt(process.env.GRIDDO_API_CONCURRENCY_COUNT || "10");
41
+ /* prettier-ignore */ const PUBLIC_API_URL = process.env.PUBLIC_API_URL as string;
42
+ /* prettier-ignore */ const RENDER_ID = process.env.GRIDDO_RENDERID || new Date().valueOf().toString();
48
43
 
49
44
  // Consts
50
- const CREATED_PAGES: Array<number> = [];
51
- const BUILD_PROCESS_DATA: BuildProcessData = {};
45
+ const createdPages: Array<number> = [];
46
+ const buildProcessData: BuildProcessData = {};
52
47
 
53
48
  /**
54
49
  * Fetch, process and save object pages and sites data into the file system to
@@ -57,20 +52,10 @@ const BUILD_PROCESS_DATA: BuildProcessData = {};
57
52
  async function createStore(storeFolder: string, domain: string) {
58
53
  console.info(`API calls with ${API_CONCURRENCY_COUNT} threads`);
59
54
 
60
- // Remove old store
61
- if (fs.existsSync(storeFolder)) {
62
- fs.rmSync(storeFolder, { recursive: true });
63
- }
64
-
65
- // Create fresh folders for store and store/metadata
66
- fs.mkdirSync(storeFolder);
67
- fs.mkdirSync(path.resolve(storeFolder, "metadata"));
68
-
69
55
  try {
70
56
  // Get sites objects to publish and unpublish.
71
57
  const { sitesToPublish, sitesToUnpublish } = await checkSites(domain);
72
58
 
73
- // The settings will be extracted below in this process.
74
59
  await SettingsService.getAll();
75
60
 
76
61
  // If no activity in sites, exit
@@ -82,16 +67,19 @@ async function createStore(storeFolder: string, domain: string) {
82
67
  console.info(`Sites to publish: ${siteList(sitesToPublish)}`);
83
68
  console.info(`Sites to unpublish: ${siteList(sitesToUnpublish)}`);
84
69
 
85
- // Unpublish (API) and delete sites
86
- // TODO: Manage this to save end data to the __report-build__ file ???
70
+ // Send unpublished sites to API.
71
+ // @todo ¿mover esta llamada al final del proceso de render?
87
72
  await unpublishSites(sitesToUnpublish);
88
73
 
89
- // Delete (clean) sites to publish
90
- // SPREAD: await deleteSites(sitesToPublish);
91
- await deleteSites([...sitesToPublish]);
92
-
93
74
  for (const site of sitesToPublish) {
94
- const { id: siteId, slug: siteSlug, theme, favicon } = site;
75
+ const {
76
+ id: siteId,
77
+ slug: siteSlug,
78
+ theme,
79
+ favicon,
80
+ changedPages = [],
81
+ pages = [],
82
+ } = site;
95
83
 
96
84
  const {
97
85
  siteInfo,
@@ -116,15 +104,13 @@ async function createStore(storeFolder: string, domain: string) {
116
104
  avoidDebugMetas,
117
105
  } = SettingsService.settings;
118
106
 
119
- BUILD_PROCESS_DATA[siteId] = {
107
+ buildProcessData[siteId] = {
120
108
  siteHash,
121
109
  unpublishHashes,
122
110
  publishHashes: [],
123
111
  };
124
112
 
125
113
  const NavService = new NavigationService();
126
-
127
- // Set `headers` and `footers` to the NavService to use later in this process.
128
114
  NavService.navigations = { headers, footers };
129
115
 
130
116
  site.languages = siteLangs;
@@ -159,7 +145,6 @@ async function createStore(storeFolder: string, domain: string) {
159
145
  avoidHrefLangXDefault,
160
146
  avoidDebugMetas,
161
147
  },
162
- BUILD_MODE: CXBRANCH,
163
148
  siteScript,
164
149
  };
165
150
 
@@ -170,9 +155,8 @@ async function createStore(storeFolder: string, domain: string) {
170
155
  // -------------------------------------------------------------------------
171
156
  // Async function that process every page for one site to use later in the
172
157
  // `Promise.all` with pLimit.
173
- const fetchPageAndSaveToStore = async (pageId: number) => {
174
- // Here will be store every page returned by the API and processed by
175
- // Griddo CX.
158
+ const fetchPageAndSaveInStore = async (pageId: number) => {
159
+ // Here will be store every page returned by the API and processed
176
160
  let griddoPageObjects: Array<GriddoPageObject> = [];
177
161
 
178
162
  // Get page data
@@ -182,7 +166,7 @@ async function createStore(storeFolder: string, domain: string) {
182
166
  if (!page) return;
183
167
 
184
168
  // Update Array of page ids
185
- CREATED_PAGES.push(pageId);
169
+ createdPages.push(pageId);
186
170
 
187
171
  // TODO: Use structuredClone() when node 18 is available.
188
172
  // SHAME: This new pageAdditionalInfo needs to be a copy because
@@ -269,24 +253,60 @@ async function createStore(storeFolder: string, domain: string) {
269
253
  ];
270
254
  }
271
255
 
272
- // Update hashes
273
- BUILD_PROCESS_DATA[siteId].publishHashes.push(page.hash);
256
+ // Upload only the valid pages hashes of pages that has been changed or created
257
+ if (page.hash !== null) {
258
+ buildProcessData[siteId].publishHashes.push(page.hash);
259
+ }
274
260
 
275
261
  // Save build data to store
276
- await savePagesInStore(storeFolder, griddoPageObjects); // gatsbyPageObjects is always an array regardless of whether it's just one page
277
- setSitesToPublish(storeFolder, sitesToPublish);
278
- setBuildProcessData(storeFolder, BUILD_PROCESS_DATA);
279
- setCreatedPages(storeFolder, CREATED_PAGES);
262
+ savePagesInStore(storeFolder, griddoPageObjects);
280
263
  };
281
264
 
282
- // Create the pLimit array of promises
265
+ // Pages to be created or deleted in the store
266
+ const {
267
+ pagesInStore,
268
+ pagesMissingInStore,
269
+ pagesToDeleteFromStore,
270
+ pagesToWriteToStore,
271
+ } = await getPagesToCreateOrDelete(storeFolder, {
272
+ sitesToPublish,
273
+ pages,
274
+ validPagesIds,
275
+ changedPages,
276
+ });
277
+
278
+ // Delete pages from published, unpublished and deleted sites.
279
+ removePagesFromStore(storeFolder, pagesToDeleteFromStore);
280
+
281
+ // Debug time
282
+ const changedPageLogs = `Store: ${pagesInStore.length} -> ${pagesInStore}
283
+ ValidPages: ${validPagesIds.length} -> ${validPagesIds}
284
+ Changed: ${changedPages.length} -> ${changedPages}
285
+ Deleted/Unpublished: ${pagesToDeleteFromStore.length} -> ${pagesToDeleteFromStore}
286
+ Missing in store: ${pagesMissingInStore.length} -> ${pagesMissingInStore}
287
+ Finally to store: ${pagesToWriteToStore.length} -> ${pagesToWriteToStore}`;
288
+
289
+ if (JSON.parse(process.env.GRIDDO_DEBUG_LOGS || "false")) {
290
+ logBox(changedPageLogs, `Site store: ${site.name}`, 1, 0);
291
+ }
292
+
293
+ // Create (async)
283
294
  const limit = pLimit(API_CONCURRENCY_COUNT);
284
- const pagesToRender = validPagesIds.map((id: number) =>
285
- limit(() => fetchPageAndSaveToStore(id))
295
+ const pagesToStore = pagesToWriteToStore.map((id: number) =>
296
+ limit(() => fetchPageAndSaveInStore(id))
286
297
  );
287
298
 
288
- await Promise.all(pagesToRender);
299
+ await Promise.all(pagesToStore);
289
300
  }
301
+
302
+ // Después de renderizar todos los sites y sus páginas (las que sean que
303
+ // hayan cambiado etc.) guardamos un archivo con la información del
304
+ // render para usos posteriores.
305
+ saveRenderInfoInStore(storeFolder, {
306
+ buildProcessData,
307
+ createdPages,
308
+ sitesToPublish,
309
+ });
290
310
  } catch (e) {
291
311
  const error = e as { message: string };
292
312
  console.error(error.message);
@@ -294,58 +314,4 @@ async function createStore(storeFolder: string, domain: string) {
294
314
  }
295
315
  }
296
316
 
297
- /**
298
- * Set the build process data in the Store.
299
- */
300
- function setBuildProcessData(
301
- basePath: string,
302
- buildProcessData: BuildProcessData
303
- ) {
304
- fsx.writeJSONSync(
305
- path.resolve(basePath, "metadata", "buildProcessData.json"),
306
- buildProcessData
307
- );
308
- }
309
-
310
- /**
311
- * Set the created pages in the Store.
312
- */
313
- function setCreatedPages(basePath: string, pages: Array<number>) {
314
- fsx.writeJSONSync(
315
- path.resolve(basePath, "metadata", "createdPages.json"),
316
- pages
317
- );
318
- }
319
-
320
- /**
321
- * Set site to publish data in the Store.
322
- */
323
- function setSitesToPublish(basePath: string, sites: Array<Site>) {
324
- fsx.writeJSONSync(
325
- path.resolve(basePath, "metadata", "sitesToPublish.json"),
326
- sites
327
- );
328
- }
329
-
330
- /**
331
- * Save the pages into the file system.
332
- */
333
- async function savePagesInStore(
334
- basePath: string,
335
- pages: Array<GriddoPageObject>
336
- ) {
337
- pages.forEach((page) =>
338
- removeProperties(page, ["editorID", "parentEditorID"])
339
- );
340
-
341
- const promises = pages.map(async (pageObject) => {
342
- const filename = `${createSha256(pageObject.path)}.json`;
343
- const fileContent = JSON.stringify(pageObject);
344
- const filePath = path.resolve(basePath, filename);
345
- await fsp.writeFile(filePath, fileContent);
346
- });
347
-
348
- await Promise.all(promises);
349
- }
350
-
351
317
  export { createStore };
@@ -1,8 +1,10 @@
1
1
  import type { EndSiteRenderBody } from "./api";
2
2
  import type { Core, Fields } from "@griddo/core";
3
3
 
4
+ import { Site } from "./sites";
5
+
4
6
  // TODO: JSDoc
5
- export interface Settings {
7
+ interface Settings {
6
8
  apiVersion?: string;
7
9
  avoidCanonicalsOnSitemaps?: boolean;
8
10
  avoidDebugMetas?: boolean;
@@ -27,10 +29,10 @@ export interface Settings {
27
29
  }
28
30
 
29
31
  // TODO: JSDoc
30
- export type Petition = Record<string, unknown>;
32
+ type Petition = Record<string, unknown>;
31
33
 
32
34
  // TODO: JSDoc
33
- export interface PostSearchInfoProps {
35
+ interface PostSearchInfoProps {
34
36
  title?: string;
35
37
  description: string | null | undefined;
36
38
  image: string | null | undefined;
@@ -43,7 +45,7 @@ export interface PostSearchInfoProps {
43
45
  }
44
46
 
45
47
  // TODO: JSDoc
46
- export interface FetchDataProps {
48
+ interface FetchDataProps {
47
49
  page: Core.Page;
48
50
  component: {
49
51
  data?: Fields.Reference<unknown>;
@@ -53,17 +55,45 @@ export interface FetchDataProps {
53
55
  }
54
56
 
55
57
  // TODO: JSDoc
56
- export type Domains = Array<{
58
+ type Domains = Array<{
57
59
  id: number;
58
60
  slug: string;
59
61
  url: string;
60
62
  }>;
61
63
 
62
64
  /** Describes the type of build process data object. */
63
- export type BuildProcessData = Record<string, EndSiteRenderBody>;
65
+ type BuildProcessData = Record<string, EndSiteRenderBody>;
64
66
 
65
67
  // TODO: JSDoc
66
- export type Robot = { path: string; content: string };
68
+ type Robot = { path: string; content: string };
67
69
 
68
70
  // TODO: JSDoc
69
- export type Robots = Array<Robot>;
71
+ type Robots = Array<Robot>;
72
+
73
+ interface RenderInfo {
74
+ buildProcessData: BuildProcessData;
75
+ createdPages: Array<number>;
76
+ sitesToPublish: Array<Site>;
77
+ }
78
+
79
+ type LifeCycles = {
80
+ doRestore?: boolean;
81
+ doData?: boolean;
82
+ doSSG?: boolean;
83
+ doRelocation?: boolean;
84
+ doMeta?: boolean;
85
+ doArchive?: boolean;
86
+ };
87
+
88
+ export {
89
+ BuildProcessData,
90
+ Domains,
91
+ FetchDataProps,
92
+ LifeCycles,
93
+ Petition,
94
+ PostSearchInfoProps,
95
+ RenderInfo,
96
+ Robot,
97
+ Robots,
98
+ Settings,
99
+ };
@@ -64,7 +64,6 @@ export type GriddoMultiPage = Core.Page & {
64
64
  // TODO: JSDoc
65
65
  export interface AdditionalInfo {
66
66
  baseUrl: string;
67
- BUILD_MODE?: string;
68
67
  cloudinaryName?: string;
69
68
  griddoVersion: string;
70
69
  instance?: string;
@@ -118,7 +117,6 @@ export type GriddoPageObject = {
118
117
  /** Page size in bytes */
119
118
  size?: number;
120
119
  context: {
121
- BUILD_MODE?: string;
122
120
  cloudinaryName?: string;
123
121
  footer: Record<string, unknown> | null;
124
122
  fullPath: Core.Page["fullPath"];
@@ -36,6 +36,7 @@ export interface Site
36
36
  languageSites: Array<number>;
37
37
  navigationModules: { header?: string; footer?: string } | null;
38
38
  pages: Array<number>;
39
+ changedPages: Array<number>;
39
40
  published: string;
40
41
  rendering: boolean;
41
42
  renderingHours: number;
@@ -2,6 +2,7 @@ import path from "node:path";
2
2
 
3
3
  import { createAPICacheFolder } from "./cache";
4
4
  import { sanitizeAPICacheFolder } from "./shared";
5
+ import { createStoreFolder } from "./store";
5
6
  import { createStore } from "../services/store";
6
7
 
7
8
  const storeFolder = path.resolve(__dirname, "../store/");
@@ -13,10 +14,11 @@ const apiCacheFolder = path.resolve(__dirname, "../apiCache");
13
14
  * `getBuildMetadata()` to get build and sites metadata as objects. Both from
14
15
  * exporter utils sites folder.
15
16
  */
16
- async function downloadBuildData(domain: string) {
17
+ async function createBuildData(domain: string) {
17
18
  createAPICacheFolder();
19
+ createStoreFolder(storeFolder);
18
20
  await createStore(storeFolder, domain);
19
21
  sanitizeAPICacheFolder(apiCacheFolder);
20
22
  }
21
23
 
22
- export { downloadBuildData };
24
+ export { createBuildData };
@@ -4,41 +4,47 @@ import path from "node:path";
4
4
 
5
5
  import fs from "fs-extra";
6
6
 
7
- import { logInfo } from "./shared";
7
+ import { CXRootFolder, logInfo } from "./shared";
8
8
 
9
9
  /**
10
10
  * Delete sites folders that will be updated from de file system.
11
11
  *
12
12
  * @param updateSites An array of sites to be updated.
13
13
  */
14
- async function deleteSites(updatedSites: Array<Site>) {
14
+ async function deleteSites(updatedSites: Array<Site>, DOMAIN: string) {
15
15
  for await (const site of updatedSites) {
16
16
  for (const domain of site.domains) {
17
- const mappedDomain = Object.values(domain)[0];
18
- const dir = path.resolve(__dirname, `../../dist${mappedDomain}`);
19
- const pageDataDir = path.resolve(
17
+ const domainFromSite = Object.values(domain)[0];
18
+ const domainPath = JSON.parse(
19
+ process.env.GRIDDO_EXPORT_STRIP_DOMAIN_FROM_PATH || "false"
20
+ )
21
+ ? domainFromSite.split(DOMAIN).join("")
22
+ : domainFromSite;
23
+
24
+ const siteFolder = path.resolve(__dirname, `../public${domainPath}`);
25
+ const pageDataFolder = path.resolve(
20
26
  __dirname,
21
- `../../assets/page-data${mappedDomain}`
27
+ `../public/page-data${domainPath}`
22
28
  );
23
29
 
24
- logInfo(`Site dir ${dir}`);
25
- logInfo(`Page data dir ${pageDataDir}`);
30
+ logInfo(`Site dir ${siteFolder}`);
31
+ logInfo(`Page data dir ${pageDataFolder}`);
26
32
 
27
33
  // delete directory recursively
28
- if (!fs.existsSync(dir)) return;
34
+ if (!fs.existsSync(siteFolder)) continue;
29
35
 
30
36
  try {
31
- await fs.rm(dir, { recursive: true });
32
- logInfo(`${dir} is deleted!`);
37
+ await fs.rm(siteFolder, { recursive: true });
38
+ logInfo(`${siteFolder} was deleted!`);
33
39
  } catch (err) {
34
40
  console.log(err);
35
41
  }
36
42
 
37
- if (!fs.existsSync(pageDataDir)) return;
43
+ if (!fs.existsSync(pageDataFolder)) continue;
38
44
 
39
45
  try {
40
- await fs.rm(pageDataDir, { recursive: true });
41
- console.info(`${pageDataDir} is deleted!`);
46
+ await fs.rm(pageDataFolder, { recursive: true });
47
+ console.info(`${pageDataFolder} was deleted!`);
42
48
  } catch (err) {
43
49
  console.log(err);
44
50
  }
@@ -46,4 +52,83 @@ async function deleteSites(updatedSites: Array<Site>) {
46
52
  }
47
53
  }
48
54
 
49
- export { deleteSites };
55
+ /**
56
+ * Remove empty site dirst (with or without sitemaps xmls)
57
+ */
58
+ const clearEmptyDirs = (baseFolder?: string) => {
59
+ const folder = baseFolder || path.resolve(CXRootFolder, "dist");
60
+
61
+ const isDir = fs.statSync(folder).isDirectory();
62
+ if (!isDir) {
63
+ return;
64
+ }
65
+
66
+ // archivos o direvtorios dentro de `folder`
67
+ let children = fs.readdirSync(folder);
68
+ // let children = childrenRaw.filter((file) => {
69
+ // return path.extname(file).toLowerCase() !== ".xml";
70
+ // });
71
+ const folderHasChildren = children.length > 0;
72
+
73
+ // Por cada uno de ellos miramos si tiene hijos, enviamos cada uno de ellos
74
+ // a `clearEmptyDirsWithXML`
75
+ if (folderHasChildren) {
76
+ const childrenCount = children.length;
77
+ const xmlCount = children.filter((file) => {
78
+ return path.extname(file).toLowerCase() === ".xml";
79
+ }).length;
80
+
81
+ // Todos los hijos son archivos .xml
82
+ // Podemos borrarlos y dejar el folder vacío.
83
+ if (childrenCount === xmlCount) {
84
+ children.forEach(function (xmlFile) {
85
+ const fullPath = path.join(folder, xmlFile);
86
+ fs.rmSync(fullPath);
87
+ });
88
+ children = fs.readdirSync(folder);
89
+ }
90
+
91
+ children.forEach(function (file) {
92
+ const fullPath = path.join(folder, file);
93
+ clearEmptyDirs(fullPath);
94
+ });
95
+
96
+ // re-evaluate files; after deleting subfolder we may have parent folder
97
+ // empty now...
98
+ children = fs.readdirSync(folder);
99
+ }
100
+
101
+ // Si no tiene hijos, lo borramos
102
+ if (children.length === 0) {
103
+ fs.rmdirSync(folder);
104
+ return;
105
+ }
106
+ };
107
+
108
+ const _clearEmptyDirs = (baseFolder?: string) => {
109
+ const folder = baseFolder || path.resolve(CXRootFolder, "dist");
110
+
111
+ const isDir = fs.statSync(folder).isDirectory();
112
+ if (!isDir) {
113
+ return;
114
+ }
115
+
116
+ let files = fs.readdirSync(folder);
117
+ if (files.length > 0) {
118
+ files.forEach(function (file) {
119
+ const fullPath = path.join(folder, file);
120
+ _clearEmptyDirs(fullPath);
121
+ });
122
+
123
+ // re-evaluate files; after deleting subfolder
124
+ // we may have parent folder empty now
125
+ files = fs.readdirSync(folder);
126
+ }
127
+
128
+ if (files.length === 0) {
129
+ fs.rmdirSync(folder);
130
+ return;
131
+ }
132
+ };
133
+
134
+ export { clearEmptyDirs, _clearEmptyDirs, deleteSites };
@@ -30,7 +30,10 @@ function checkRenderHealthOrExit() {
30
30
  }
31
31
 
32
32
  // Error
33
- logBox(`Error. The environment is not suitable for a build.`);
33
+ logBox(
34
+ `Error. The environment is not suitable for a build.`,
35
+ "Not valid environment"
36
+ );
34
37
  process.exit(1);
35
38
  }
36
39
 
@@ -46,7 +46,11 @@ function getComponentsLibAliases() {
46
46
  return Object.keys(xsConfig?.compilerOptions?.paths).reduce(
47
47
  (currentAlias, pathKey) => {
48
48
  const [aliasKey] = pathKey.split("/");
49
- const [pathAtJsConfig] = xsConfig?.compilerOptions?.paths[pathKey];
49
+ const [pathAtJsConfig] =
50
+ xsConfig &&
51
+ xsConfig.compilerOptions &&
52
+ xsConfig.compilerOptions.paths &&
53
+ xsConfig.compilerOptions.paths[pathKey];
50
54
 
51
55
  const [relativePathToDir] = pathAtJsConfig.split("/*");
52
56
 
@@ -0,0 +1,31 @@
1
+ import chalk from "chalk";
2
+
3
+ export const printWarningMessage = (message: string, location: string, expected: string) => {
4
+ const heading = " > PRINT WARNING MESSAGE";
5
+ const longestLineLength = Math.max(message.length, location.length, heading.length, expected.length);
6
+ const line = '+'.padEnd(longestLineLength + 15, '-') + '+';
7
+
8
+ console.log(line);
9
+ console.log(chalk.keyword('orange').bold('|' + heading.padEnd(longestLineLength + 5)));
10
+ console.log('|');
11
+ console.log('|' + ` Location: "${location}"`.padEnd(longestLineLength + 5));
12
+ console.log('|' + ` Message: ${message}`.padEnd(longestLineLength + 5));
13
+ console.log('|' + ` Expected: ${expected}`.padEnd(longestLineLength + 5));
14
+ console.log('|');
15
+ console.log(line + '\n');
16
+ };
17
+
18
+ export const printErrorMessage = (message: string, location: string, expected: string) => {
19
+ const heading = " > PRINT ERROR MESSAGE";
20
+ const longestLineLength = Math.max(message.length, location.length, heading.length, expected.length);
21
+ const line = '+'.padEnd(longestLineLength + 15, '-') + '+';
22
+
23
+ console.log(line);
24
+ console.log(chalk.keyword('red').bold('|' + heading.padEnd(longestLineLength + 5)));
25
+ console.log('|');
26
+ console.log('|' + ` Location: "${location}"`.padEnd(longestLineLength + 5));
27
+ console.log('|' + ` Message: ${message}`.padEnd(longestLineLength + 5));
28
+ console.log('|' + ` Expected: ${expected}`.padEnd(longestLineLength + 5));
29
+ console.log('|');
30
+ console.log(line + '\n');
31
+ }
@@ -110,8 +110,7 @@ function getPageMetaData(params: Core.Page): Core.Page["pageMetaData"] {
110
110
  */
111
111
  async function createGriddoPageObject(
112
112
  page: GriddoSinglePage | GriddoListPage | GriddoMultiPage,
113
- additionalInfo: PageAdditionalInfo,
114
- excludeFromSearch = false
113
+ additionalInfo: PageAdditionalInfo
115
114
  ): Promise<GriddoPageObject> {
116
115
  // Extract some props from page
117
116
  const {
@@ -128,7 +127,6 @@ async function createGriddoPageObject(
128
127
  // Extract some props from additionalInfo
129
128
  const {
130
129
  baseUrl,
131
- BUILD_MODE,
132
130
  cloudinaryName,
133
131
  griddoVersion,
134
132
  siteLangs,
@@ -187,7 +185,6 @@ async function createGriddoPageObject(
187
185
  siteLangs,
188
186
  cloudinaryName,
189
187
  siteOptions,
190
- BUILD_MODE,
191
188
  griddoVersion,
192
189
  renderDate,
193
190
  siteScript,