@griddo/cx 11.9.17 → 11.10.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.
- package/README.md +13 -240
- package/build/commands/end-render.d.ts +0 -1
- package/build/commands/end-render.js +31 -0
- package/build/commands/end-render.js.map +7 -0
- package/build/commands/prepare-assets-directory.js +9 -0
- package/build/commands/prepare-assets-directory.js.map +7 -0
- package/build/commands/prepare-domains-render.js +40 -0
- package/build/commands/prepare-domains-render.js.map +7 -0
- package/build/commands/reset-render.d.ts +0 -1
- package/build/commands/reset-render.js +31 -0
- package/build/commands/reset-render.js.map +7 -0
- package/build/commands/single-domain-upload-search-content.d.ts +1 -0
- package/build/commands/start-render.d.ts +0 -1
- package/build/commands/start-render.js +66 -0
- package/build/commands/start-render.js.map +7 -0
- package/build/commands/upload-search-content.d.ts +0 -1
- package/build/commands/upload-search-content.js +32 -0
- package/build/commands/upload-search-content.js.map +7 -0
- package/build/core/GriddoLog.d.ts +16 -0
- package/build/{utils/health-checks.d.ts → core/check-env-health.d.ts} +4 -2
- package/build/core/db-class.d.ts +11 -0
- package/build/core/db.d.ts +4 -0
- package/build/core/dist-rollback.d.ts +11 -0
- package/build/core/errors.d.ts +26 -0
- package/build/core/fs.d.ts +69 -0
- package/build/core/life-cycle.d.ts +26 -0
- package/build/core/logger.d.ts +18 -0
- package/build/core/objects.d.ts +11 -0
- package/build/core/print-logos.d.ts +5 -0
- package/build/index.d.ts +10 -29
- package/build/index.js +404 -73
- package/build/react/DynamicScript/index.d.ts +4 -0
- package/build/react/GriddoFavicon/index.d.ts +4 -0
- package/build/react/GriddoIntegrations/index.d.ts +3 -4
- package/build/react/GriddoIntegrations/utils.d.ts +7 -6
- package/build/react/GriddoOpenGraph/index.d.ts +10 -0
- package/build/react/index.d.ts +3 -2
- package/build/react/index.js +1 -3
- package/build/{utils → services}/api.d.ts +1 -1
- package/build/services/auth.d.ts +2 -5
- package/build/services/domains.d.ts +3 -4
- package/build/services/manage-sites.d.ts +22 -0
- package/build/services/manage-store.d.ts +32 -0
- package/build/services/navigation.d.ts +16 -16
- package/build/{utils → services}/pages.d.ts +3 -3
- package/build/services/reference-fields.d.ts +3 -3
- package/build/services/render-artifacts.d.ts +6 -0
- package/build/services/render.d.ts +70 -0
- package/build/services/robots.d.ts +2 -19
- package/build/services/sitemaps.d.ts +5 -0
- package/build/services/sites.d.ts +8 -5
- package/build/services/store.d.ts +10 -1
- package/build/shared/context.d.ts +36 -0
- package/build/shared/envs.d.ts +17 -0
- package/build/{errors/errors-data.d.ts → shared/errors.d.ts} +5 -3
- package/build/shared/npm-modules/brush.d.ts +18 -0
- package/build/shared/npm-modules/find-up-simple.d.ts +34 -0
- package/build/shared/npm-modules/pkg-dir.d.ts +7 -0
- package/build/shared/npm-modules/xml-parser.d.ts +4 -0
- package/build/{types → shared/types}/api.d.ts +18 -18
- package/build/{types → shared/types}/global.d.ts +15 -16
- package/build/{types → shared/types}/navigation.d.ts +5 -5
- package/build/{types → shared/types}/pages.d.ts +9 -9
- package/build/shared/types/render.d.ts +56 -0
- package/build/{types → shared/types}/sites.d.ts +18 -19
- package/build/shared/types.d.ts +15 -0
- package/build/ssg-adapters/gatsby/actions/clean.d.ts +3 -0
- package/build/ssg-adapters/gatsby/actions/close.d.ts +3 -0
- package/build/ssg-adapters/gatsby/actions/data.d.ts +2 -0
- package/build/ssg-adapters/gatsby/actions/healthCheck.d.ts +2 -0
- package/build/ssg-adapters/gatsby/actions/init.d.ts +2 -0
- package/build/ssg-adapters/gatsby/actions/logs.d.ts +3 -0
- package/build/ssg-adapters/gatsby/actions/meta.d.ts +2 -0
- package/build/ssg-adapters/gatsby/actions/prepare.d.ts +2 -0
- package/build/ssg-adapters/gatsby/actions/relocation.d.ts +2 -0
- package/build/ssg-adapters/gatsby/actions/restore.d.ts +3 -0
- package/build/ssg-adapters/gatsby/actions/ssg.d.ts +3 -0
- package/build/ssg-adapters/gatsby/actions/sync.d.ts +3 -0
- package/build/ssg-adapters/gatsby/index.d.ts +9 -0
- package/build/ssg-adapters/gatsby/shared/artifacts.d.ts +4 -0
- package/build/ssg-adapters/gatsby/shared/diff-assets.d.ts +15 -0
- package/build/ssg-adapters/gatsby/shared/extract-assets.d.ts +7 -0
- package/build/ssg-adapters/gatsby/shared/gatsby-build.d.ts +7 -0
- package/build/ssg-adapters/gatsby/shared/render-rollback.d.ts +18 -0
- package/build/ssg-adapters/gatsby/shared/sync-render.d.ts +26 -0
- package/build/ssg-adapters/gatsby/shared/types.d.ts +34 -0
- package/cli.mjs +231 -0
- package/exporter/build-esbuild.noop +42 -0
- package/exporter/build.sh +16 -24
- package/exporter/commands/README.md +142 -0
- package/exporter/commands/end-render.ts +53 -87
- package/exporter/commands/prepare-assets-directory.ts +35 -0
- package/exporter/commands/prepare-domains-render.ts +150 -33
- package/exporter/commands/reset-render.ts +13 -8
- package/exporter/commands/single-domain-upload-search-content.ts +206 -0
- package/exporter/commands/start-render.ts +14 -65
- package/exporter/commands/upload-search-content.ts +204 -26
- package/exporter/core/GriddoLog.ts +45 -0
- package/exporter/core/check-env-health.ts +203 -0
- package/exporter/core/db-class.ts +54 -0
- package/exporter/core/db.ts +33 -0
- package/exporter/core/dist-rollback.ts +49 -0
- package/exporter/core/errors.ts +93 -0
- package/exporter/core/fs.ts +385 -0
- package/exporter/{utils → core}/images.ts +1 -6
- package/exporter/{utils → core}/instance.ts +9 -13
- package/exporter/core/life-cycle.ts +73 -0
- package/exporter/core/logger.ts +137 -0
- package/exporter/core/objects.ts +37 -0
- package/exporter/core/print-logos.ts +21 -0
- package/exporter/index.ts +14 -56
- package/exporter/react/DynamicScript/index.tsx +33 -0
- package/exporter/react/{Favicon → GriddoFavicon}/index.tsx +3 -9
- package/exporter/react/GriddoIntegrations/index.tsx +17 -23
- package/exporter/react/GriddoIntegrations/utils.ts +24 -12
- package/exporter/react/GriddoOpenGraph/index.tsx +39 -0
- package/exporter/react/index.tsx +3 -9
- package/exporter/services/api.ts +306 -0
- package/exporter/services/auth.ts +8 -10
- package/exporter/services/domains.ts +23 -8
- package/exporter/services/manage-sites.ts +116 -0
- package/exporter/services/manage-store.ts +173 -0
- package/exporter/services/navigation.ts +12 -18
- package/exporter/{utils → services}/pages.ts +27 -92
- package/exporter/services/reference-fields.ts +14 -32
- package/exporter/services/render-artifacts.ts +44 -0
- package/exporter/services/render.ts +229 -0
- package/exporter/services/robots.ts +33 -61
- package/exporter/services/sitemaps.ts +129 -0
- package/exporter/services/sites.ts +40 -28
- package/exporter/services/store.ts +354 -321
- package/exporter/shared/context.ts +49 -0
- package/exporter/{constants → shared}/endpoints.ts +12 -11
- package/exporter/shared/envs.ts +58 -0
- package/exporter/{errors/errors-data.ts → shared/errors.ts} +24 -14
- package/exporter/shared/npm-modules/README.md +36 -0
- package/exporter/shared/npm-modules/brush.ts +34 -0
- package/exporter/shared/npm-modules/find-up-simple.ts +100 -0
- package/exporter/shared/npm-modules/pkg-dir.ts +17 -0
- package/exporter/shared/npm-modules/xml-parser.ts +57 -0
- package/exporter/{types → shared/types}/api.ts +40 -41
- package/exporter/{types → shared/types}/global.ts +17 -21
- package/exporter/{types → shared/types}/navigation.ts +3 -3
- package/exporter/{types → shared/types}/pages.ts +10 -11
- package/exporter/shared/types/render.ts +65 -0
- package/exporter/{types → shared/types}/sites.ts +18 -19
- package/exporter/shared/types.ts +15 -0
- package/exporter/ssg-adapters/gatsby/actions/clean.ts +26 -0
- package/exporter/ssg-adapters/gatsby/actions/close.ts +17 -0
- package/exporter/ssg-adapters/gatsby/actions/data.ts +22 -0
- package/exporter/ssg-adapters/gatsby/actions/healthCheck.ts +10 -0
- package/exporter/ssg-adapters/gatsby/actions/init.ts +12 -0
- package/exporter/ssg-adapters/gatsby/actions/logs.ts +10 -0
- package/exporter/ssg-adapters/gatsby/actions/meta.ts +13 -0
- package/exporter/ssg-adapters/gatsby/actions/prepare.ts +9 -0
- package/exporter/ssg-adapters/gatsby/actions/relocation.ts +15 -0
- package/exporter/ssg-adapters/gatsby/actions/restore.ts +21 -0
- package/exporter/ssg-adapters/gatsby/actions/ssg.ts +12 -0
- package/exporter/ssg-adapters/gatsby/actions/sync.ts +65 -0
- package/exporter/ssg-adapters/gatsby/index.ts +117 -0
- package/exporter/ssg-adapters/gatsby/shared/artifacts.ts +17 -0
- package/exporter/ssg-adapters/gatsby/shared/diff-assets.ts +128 -0
- package/exporter/ssg-adapters/gatsby/shared/extract-assets.ts +75 -0
- package/exporter/ssg-adapters/gatsby/shared/gatsby-build.ts +58 -0
- package/exporter/ssg-adapters/gatsby/shared/render-rollback.ts +33 -0
- package/exporter/ssg-adapters/gatsby/shared/sync-render.ts +298 -0
- package/exporter/ssg-adapters/gatsby/shared/types.ts +35 -0
- package/gatsby-browser.tsx +41 -58
- package/gatsby-config.ts +10 -17
- package/gatsby-node.ts +20 -79
- package/gatsby-ssr.tsx +2 -1
- package/package.json +41 -78
- package/plugins/gatsby-plugin-svgr-loader/gatsby-node.js +55 -0
- package/plugins/gatsby-plugin-svgr-loader/package.json +8 -0
- package/src/components/Head.tsx +28 -73
- package/src/components/template.tsx +6 -29
- package/src/gatsby-node-utils.ts +81 -2
- package/src/html.tsx +2 -11
- package/src/types.ts +3 -3
- package/tsconfig.commands.json +36 -0
- package/tsconfig.exporter.json +21 -0
- package/tsconfig.json +5 -3
- package/build/adapters/gatsby/index.d.ts +0 -4
- package/build/adapters/gatsby/utils.d.ts +0 -26
- package/build/artifacts/index.d.ts +0 -6
- package/build/constants/envs.d.ts +0 -37
- package/build/constants/index.d.ts +0 -57
- package/build/end-render.js +0 -74
- package/build/end-render.js.map +0 -7
- package/build/errors/index.d.ts +0 -15
- package/build/index.js.map +0 -7
- package/build/prepare-domains-render.js +0 -73
- package/build/prepare-domains-render.js.map +0 -7
- package/build/react/Favicon/index.d.ts +0 -5
- package/build/registers/api.d.ts +0 -9
- package/build/registers/gatsby.d.ts +0 -9
- package/build/registers/index.d.ts +0 -3
- package/build/reset-render.js +0 -74
- package/build/reset-render.js.map +0 -7
- package/build/services/register.d.ts +0 -36
- package/build/services/settings.d.ts +0 -4
- package/build/start-render.js +0 -100
- package/build/start-render.js.map +0 -7
- package/build/upload-search-content.js +0 -74
- package/build/upload-search-content.js.map +0 -7
- package/build/utils/alerts.d.ts +0 -3
- package/build/utils/cache.d.ts +0 -35
- package/build/utils/core-utils.d.ts +0 -107
- package/build/utils/create-build-data.d.ts +0 -8
- package/build/utils/domains.d.ts +0 -13
- package/build/utils/folders.d.ts +0 -53
- package/build/utils/loggin.d.ts +0 -51
- package/build/utils/render.d.ts +0 -13
- package/build/utils/searches.d.ts +0 -15
- package/build/utils/sites.d.ts +0 -31
- package/build/utils/store.d.ts +0 -81
- package/cx.config.d.ts +0 -5
- package/cx.config.js +0 -36
- package/exporter/adapters/gatsby/index.ts +0 -182
- package/exporter/adapters/gatsby/utils.ts +0 -186
- package/exporter/artifacts/README.md +0 -34
- package/exporter/artifacts/index.ts +0 -33
- package/exporter/commands/move-assets.ts +0 -11
- package/exporter/constants/envs.ts +0 -94
- package/exporter/constants/index.ts +0 -129
- package/exporter/errors/index.ts +0 -40
- package/exporter/registers/api.ts +0 -14
- package/exporter/registers/gatsby.ts +0 -14
- package/exporter/registers/index.ts +0 -4
- package/exporter/services/register.ts +0 -113
- package/exporter/services/settings.ts +0 -17
- package/exporter/utils/alerts.ts +0 -29
- package/exporter/utils/api.ts +0 -243
- package/exporter/utils/cache.ts +0 -142
- package/exporter/utils/core-utils.ts +0 -458
- package/exporter/utils/create-build-data.ts +0 -17
- package/exporter/utils/domains.ts +0 -39
- package/exporter/utils/folders.ts +0 -320
- package/exporter/utils/health-checks.ts +0 -64
- package/exporter/utils/loggin.ts +0 -184
- package/exporter/utils/render.ts +0 -71
- package/exporter/utils/searches.ts +0 -156
- package/exporter/utils/sites.ts +0 -312
- package/exporter/utils/store.ts +0 -314
- package/src/README.md +0 -7
- package/start-render.js +0 -7
- /package/build/commands/{move-assets.d.ts → prepare-assets-directory.d.ts} +0 -0
- /package/build/{utils → core}/images.d.ts +0 -0
- /package/build/{utils → core}/instance.d.ts +0 -0
- /package/build/react/{Favicon → GriddoFavicon}/utils.d.ts +0 -0
- /package/build/{constants → shared}/endpoints.d.ts +0 -0
- /package/build/{types → shared/types}/templates.d.ts +0 -0
- /package/exporter/react/{Favicon → GriddoFavicon}/utils.ts +0 -0
- /package/exporter/{types → shared/types}/templates.ts +0 -0
|
@@ -1,39 +1,217 @@
|
|
|
1
|
-
|
|
1
|
+
import type { PostSearchInfoResponse } from "../shared/types/api";
|
|
2
|
+
import type { AIEmbeddingsResponse, PostSearchInfoProps } from "../shared/types/global";
|
|
3
|
+
import type { GatsbyPageData } from "../ssg-adapters/gatsby/shared/types";
|
|
2
4
|
|
|
3
|
-
import
|
|
5
|
+
import fsp from "node:fs/promises";
|
|
6
|
+
import path from "node:path";
|
|
4
7
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} from "../
|
|
8
|
+
import { throwError, withErrorHandler } from "../core/errors";
|
|
9
|
+
import { pathExists } from "../core/fs";
|
|
10
|
+
import { GriddoLog } from "../core/GriddoLog";
|
|
11
|
+
import { post } from "../services/api";
|
|
12
|
+
import { AuthService } from "../services/auth";
|
|
13
|
+
import { getInstanceDomains } from "../services/domains";
|
|
14
|
+
import { getRenderPathsHydratedWithDomainFromDB } from "../services/render";
|
|
15
|
+
import { AI_EMBEDDINGS, SEARCH } from "../shared/endpoints";
|
|
16
|
+
import { GRIDDO_AI_EMBEDDINGS, GRIDDO_SEARCH_FEATURE } from "../shared/envs";
|
|
17
|
+
import { ReadFromStoreError, UploadSearchError } from "../shared/errors";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Save in the BBDD the content of a page parsed without HTML tags.
|
|
21
|
+
*
|
|
22
|
+
* @param props Object with parts of the final page object to be saved in the BBDD.
|
|
23
|
+
*/
|
|
24
|
+
async function postSearchInfo(props: PostSearchInfoProps) {
|
|
25
|
+
const { title, description, image, pageId, languageId, siteId, url, content, template } = props;
|
|
26
|
+
|
|
27
|
+
const response = await post<PostSearchInfoResponse>({
|
|
28
|
+
endpoint: SEARCH,
|
|
29
|
+
body: {
|
|
30
|
+
title,
|
|
31
|
+
description,
|
|
32
|
+
image,
|
|
33
|
+
pageId,
|
|
34
|
+
languageId,
|
|
35
|
+
siteId,
|
|
36
|
+
url,
|
|
37
|
+
template,
|
|
38
|
+
content,
|
|
39
|
+
},
|
|
40
|
+
useApiCacheDir: false,
|
|
41
|
+
logToFile: false,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return response;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function prepareHTMLContentForSearch(content: string): string {
|
|
48
|
+
// 1. Remove script, style, and other unwanted block tags and their content.
|
|
49
|
+
// The regex looks for <tag...>...</tag> where tag is one of the specified ones.
|
|
50
|
+
const tagsToRemove = ["meta", "link", "style", "script", "noscript", "nav", "header", "footer"];
|
|
51
|
+
const removeTagsRegex = new RegExp(`<(${tagsToRemove.join("|")})\\b[^>]*>.*?<\\/\\1>`, "gis");
|
|
52
|
+
let processedContent = content.replace(removeTagsRegex, "");
|
|
53
|
+
|
|
54
|
+
// 2. Strip all remaining HTML tags.
|
|
55
|
+
processedContent = processedContent.replace(/<[^>]+>/g, " ");
|
|
56
|
+
|
|
57
|
+
// 3. Normalize whitespace: replace multiple spaces/newlines with a single space and trim.
|
|
58
|
+
processedContent = processedContent.replace(/\s+/g, " ").trim();
|
|
59
|
+
|
|
60
|
+
return processedContent;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Function that search in the `/public` dir the content info of the pages and
|
|
65
|
+
* send it to the search table in the ddbb using the API.
|
|
66
|
+
* @todo Utilizar la carpeta page-data en lugar de la carpeta store puesto que
|
|
67
|
+
* esta ya no es persistente.
|
|
68
|
+
*/
|
|
69
|
+
async function uploadRenderedSearchContentToAPI(options: {
|
|
70
|
+
htmlContentDir: string;
|
|
71
|
+
jsonContentDir: string;
|
|
72
|
+
}) {
|
|
73
|
+
const { htmlContentDir, jsonContentDir } = options;
|
|
74
|
+
|
|
75
|
+
if (!(await pathExists(jsonContentDir)) || !(await pathExists(htmlContentDir))) {
|
|
76
|
+
GriddoLog.info(
|
|
77
|
+
`Skipping uploading content to the search endpoint because it has not exported sites.`,
|
|
78
|
+
);
|
|
12
79
|
|
|
13
|
-
async function main() {
|
|
14
|
-
if (!envs.GRIDDO_SEARCH_FEATURE) {
|
|
15
80
|
return;
|
|
16
81
|
}
|
|
17
82
|
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
83
|
+
// Get pages from gatsby page-data dir
|
|
84
|
+
const gatsbyPageDataPages = getPageDataPagesFromExports(jsonContentDir);
|
|
85
|
+
|
|
86
|
+
let pagesUploadedCounter = 0;
|
|
87
|
+
for await (const pageData of gatsbyPageDataPages) {
|
|
88
|
+
const { result } = pageData;
|
|
89
|
+
const { pageContext } = result;
|
|
90
|
+
const { page, openGraph, pageMetadata } = pageContext;
|
|
91
|
+
|
|
92
|
+
const { compose } = page.fullPath;
|
|
93
|
+
|
|
94
|
+
const htmlPath = path.resolve(`${htmlContentDir}/${compose}/index.html`);
|
|
95
|
+
const htmlContent = await fsp.readFile(htmlPath, "utf-8");
|
|
96
|
+
|
|
97
|
+
const pageObject: PostSearchInfoProps = {
|
|
98
|
+
siteId: page.site,
|
|
99
|
+
pageId: page.id,
|
|
100
|
+
// `pageMetadata.title` has already a fallback `metatitle ||
|
|
101
|
+
// pageTitle` so probably `title` never will be take the
|
|
102
|
+
// `openGraph?.title` value. Only when the `metatitle` and
|
|
103
|
+
// `pageTitle` are empty.
|
|
104
|
+
title: pageMetadata?.title || openGraph?.title,
|
|
105
|
+
languageId: page.language,
|
|
106
|
+
url: page.fullUrl,
|
|
107
|
+
template: page.template.templateType || page.templateId,
|
|
108
|
+
description: pageMetadata?.description || openGraph?.description,
|
|
109
|
+
image: openGraph.image,
|
|
110
|
+
content: prepareHTMLContentForSearch(htmlContent),
|
|
111
|
+
};
|
|
22
112
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
113
|
+
try {
|
|
114
|
+
await postSearchInfo(pageObject);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
throwError(UploadSearchError, error);
|
|
27
117
|
}
|
|
118
|
+
|
|
119
|
+
GriddoLog.verbose(`Uploaded content of: ${page.fullUrl}`);
|
|
120
|
+
pagesUploadedCounter++;
|
|
28
121
|
}
|
|
29
122
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
123
|
+
GriddoLog.info(`Uploaded ${pagesUploadedCounter} pages.\n`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Walk recursively in a basePath and return an array of pages with json
|
|
128
|
+
* extension with the full absolute path and the path includes "page-data".
|
|
129
|
+
*
|
|
130
|
+
* @param basePath The path to walk recursively.
|
|
131
|
+
* @returns An array of pages with json extension with the full absolute path
|
|
132
|
+
* and the path includes "page-data".
|
|
133
|
+
*/
|
|
134
|
+
async function* walkRecursively(basePath: string): AsyncGenerator<string> {
|
|
135
|
+
const filesHandle = await fsp.opendir(basePath);
|
|
136
|
+
|
|
137
|
+
for await (const fileDirent of filesHandle) {
|
|
138
|
+
if (fileDirent.isDirectory()) {
|
|
139
|
+
yield* walkRecursively(path.join(basePath, fileDirent.name));
|
|
140
|
+
} else if (
|
|
141
|
+
fileDirent.isFile() &&
|
|
142
|
+
path.extname(fileDirent.name) === ".json" &&
|
|
143
|
+
fileDirent.name.includes("page-data")
|
|
144
|
+
) {
|
|
145
|
+
yield path.join(basePath, fileDirent.name);
|
|
146
|
+
}
|
|
33
147
|
}
|
|
34
148
|
}
|
|
35
149
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
150
|
+
/**
|
|
151
|
+
* Walk recursively in a basePath and return an array of pages with json
|
|
152
|
+
* extension with the full absolute path and the path includes "page-data".
|
|
153
|
+
*
|
|
154
|
+
* @param basePath The path to walk recursively.
|
|
155
|
+
* @returns An array of pages with json extension with the full absolute path
|
|
156
|
+
* and the path includes "page-data".
|
|
157
|
+
*/
|
|
158
|
+
async function* getPageDataPagesFromExports<PageType extends GatsbyPageData>(
|
|
159
|
+
basePath: string,
|
|
160
|
+
): AsyncGenerator<PageType> {
|
|
161
|
+
const jsonFiles = walkRecursively(basePath);
|
|
162
|
+
|
|
163
|
+
for await (const filePath of jsonFiles) {
|
|
164
|
+
try {
|
|
165
|
+
const fileContent = await fsp.readFile(filePath, "utf8");
|
|
166
|
+
const page = JSON.parse(fileContent) as PageType;
|
|
167
|
+
|
|
168
|
+
if (page.path) {
|
|
169
|
+
yield page;
|
|
170
|
+
}
|
|
171
|
+
} catch (error) {
|
|
172
|
+
throwError(ReadFromStoreError, error);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async function getContentDirectories(domain: string) {
|
|
178
|
+
const { __exports } = await getRenderPathsHydratedWithDomainFromDB({ domain });
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
htmlContentDir: path.join(__exports, "dist"),
|
|
182
|
+
jsonContentDir: path.join(__exports, "dist", "page-data"),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async function uploadSearchContent() {
|
|
187
|
+
if (GRIDDO_SEARCH_FEATURE) {
|
|
188
|
+
const domains = await getInstanceDomains();
|
|
189
|
+
for (const domain of domains) {
|
|
190
|
+
const { htmlContentDir, jsonContentDir } = await getContentDirectories(domain);
|
|
191
|
+
|
|
192
|
+
GriddoLog.info(`Uploading search content for ${domain}`);
|
|
193
|
+
await uploadRenderedSearchContentToAPI({
|
|
194
|
+
htmlContentDir,
|
|
195
|
+
jsonContentDir,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async function aiEmbeddings() {
|
|
202
|
+
if (GRIDDO_SEARCH_FEATURE && GRIDDO_AI_EMBEDDINGS) {
|
|
203
|
+
GriddoLog.info(`Triggering AI embeddings...`);
|
|
204
|
+
await post<AIEmbeddingsResponse>({
|
|
205
|
+
endpoint: AI_EMBEDDINGS,
|
|
206
|
+
useApiCacheDir: false,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async function main() {
|
|
212
|
+
await AuthService.login();
|
|
213
|
+
await uploadSearchContent();
|
|
214
|
+
await aiEmbeddings();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
withErrorHandler(main);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { GRIDDO_BUILD_LOGS, GRIDDO_VERBOSE_LOGS } from "../shared/envs";
|
|
2
|
+
import { brush } from "../shared/npm-modules/brush";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Clase estática para gestionar los logs de la aplicación.
|
|
6
|
+
* No se puede instanciar, se usa directamente: GriddoLogs.info("mensaje").
|
|
7
|
+
*/
|
|
8
|
+
class GriddoLog {
|
|
9
|
+
/** El constructor es privado para prevenir la instanciación de la clase. */
|
|
10
|
+
private constructor() {}
|
|
11
|
+
|
|
12
|
+
public static verbose(...str: unknown[]): void {
|
|
13
|
+
if (GRIDDO_VERBOSE_LOGS) {
|
|
14
|
+
console.log(brush.yellow("verbose"), brush.dim(str.join(" ")));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public static build(...str: unknown[]): void {
|
|
19
|
+
if (GRIDDO_BUILD_LOGS) {
|
|
20
|
+
GriddoLog.log(...str);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public static info(...str: unknown[]): void {
|
|
25
|
+
console.log(`${brush.blue("info")} ${str.join(" ")}`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public static success(...str: unknown[]): void {
|
|
29
|
+
console.log(`${brush.green("success")} ${str.join(" ")}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public static error(...str: unknown[]): void {
|
|
33
|
+
console.error(`${brush.red("error")} ${str.join(" ")}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public static warn(...str: unknown[]): void {
|
|
37
|
+
console.warn(`${brush.yellow("warn")} ${str.join(" ")}`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public static log(...args: Parameters<typeof console.log>): void {
|
|
41
|
+
console.log(...args);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { GriddoLog };
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { CheckHealthError } from "../shared/errors";
|
|
2
|
+
import { brush } from "../shared/npm-modules/brush";
|
|
3
|
+
import { throwError } from "./errors";
|
|
4
|
+
import { GriddoLog } from "./GriddoLog";
|
|
5
|
+
|
|
6
|
+
// Environment variables that must be present (but value doesn't matter)
|
|
7
|
+
const REQUIRED_ENV_VARS: readonly string[] = [];
|
|
8
|
+
|
|
9
|
+
// Environment variables that must have specific values
|
|
10
|
+
const REQUIRED_ENV_VALUES: readonly {
|
|
11
|
+
key: string;
|
|
12
|
+
expected: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
}[] = [];
|
|
15
|
+
|
|
16
|
+
// Environment variables that are recommended but not required
|
|
17
|
+
// These will show warnings if missing but won't fail the health check
|
|
18
|
+
const RECOMMENDED_ENV_VARS: readonly { key: string; description?: string }[] = [
|
|
19
|
+
{
|
|
20
|
+
key: "GRIDDO_BUILD_LOGS",
|
|
21
|
+
description: "Recommended for detailed render logs",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
key: "GRIDDO_API_CONCURRENCY_COUNT",
|
|
25
|
+
description: "Recommended for better performance and memory management",
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
// Environment variables that must be present (but value doesn't matter)
|
|
30
|
+
const DEPRECATED_ENV_VARS: readonly { key: string; description?: string }[] = [
|
|
31
|
+
{
|
|
32
|
+
key: "GRIDDO_RENDER_SITE",
|
|
33
|
+
description:
|
|
34
|
+
"This environment variable no longer has any effect because it is incompatible with incremental rendering.",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
key: "GRIDDO_RENDER_PAGES",
|
|
38
|
+
description:
|
|
39
|
+
"This environment variable no longer has any effect because it is incompatible with incremental rendering.",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
key: "REACT_APP_API_ENDPOINT",
|
|
43
|
+
description: "Use GRIDDO_API_URL",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
key: "REACT_APP_PUBLIC_API_ENDPOINT",
|
|
47
|
+
description: "Use GRIDDO_PUBLIC_API_URL",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
key: "GRIDDO_RENDER_ALL_SITES",
|
|
51
|
+
description: "This environment variable is deprecated, it has not effect anymore, remove it",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
key: "GRIDDO_RENDER_BY_DOMAINS",
|
|
55
|
+
description: "This environment variable is deprecated, it has not effect anymore, remove it",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
key: "GRIDDO_EXPERIMENTAL_DO_NOT_USE_MATCH_PATH",
|
|
59
|
+
description: "This environment variable is deprecated, it has not effect anymore, remove it",
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Check if required environment variables exist with any value.
|
|
65
|
+
*
|
|
66
|
+
* @returns An object containing:
|
|
67
|
+
* - isValid: boolean indicating if all required environment variables are present.
|
|
68
|
+
* - missing: an array of missing environment variable names.
|
|
69
|
+
*/
|
|
70
|
+
function checkRequiredEnvVars(): { isValid: boolean; missing: string[] } {
|
|
71
|
+
const missing = REQUIRED_ENV_VARS.filter((envName) => !process.env[envName]);
|
|
72
|
+
|
|
73
|
+
if (missing.length > 0) {
|
|
74
|
+
GriddoLog.error(`Missing required environment variables: ${missing.join(", ")}`);
|
|
75
|
+
return { isValid: false, missing };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return { isValid: true, missing: [] };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Check if environment variables have the expected values.
|
|
83
|
+
*
|
|
84
|
+
* @returns An object containing:
|
|
85
|
+
* - isValid: boolean indicating if all required environment variables have the expected values.
|
|
86
|
+
* - mismatches: an array of mismatched environment variable names and their expected and actual values.
|
|
87
|
+
*/
|
|
88
|
+
function checkEnvVarValues(): {
|
|
89
|
+
isValid: boolean;
|
|
90
|
+
mismatches: { key: string; expected: string; actual: string }[];
|
|
91
|
+
} {
|
|
92
|
+
const mismatches: { key: string; expected: string; actual: string }[] = [];
|
|
93
|
+
|
|
94
|
+
for (const { key, expected } of REQUIRED_ENV_VALUES) {
|
|
95
|
+
const actual = process.env[key];
|
|
96
|
+
|
|
97
|
+
if (actual !== expected) {
|
|
98
|
+
mismatches.push({ key, expected, actual: actual || "(undefined)" });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (mismatches.length > 0) {
|
|
103
|
+
return { isValid: false, mismatches };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return { isValid: true, mismatches: [] };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Check recommended environment variables and show warnings for missing ones.
|
|
111
|
+
*
|
|
112
|
+
* @returns An object containing:
|
|
113
|
+
* - isValid: boolean indicating if all recommended environment variables are set.
|
|
114
|
+
* - missing: an array of missing recommended environment variable names.
|
|
115
|
+
*/
|
|
116
|
+
function checkRecommendedEnvVars() {
|
|
117
|
+
const missing = RECOMMENDED_ENV_VARS.filter(({ key }) => !process.env[key]);
|
|
118
|
+
|
|
119
|
+
if (missing.length > 0) {
|
|
120
|
+
GriddoLog.warn("Recommended environment variables not set:");
|
|
121
|
+
|
|
122
|
+
for (const { key, description } of missing) {
|
|
123
|
+
const desc = description ? ` # ${description}` : "";
|
|
124
|
+
GriddoLog.log(`\t${brush.green(key)}${brush.dim(desc)}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Check if set enviroment variables have been deprecated
|
|
131
|
+
*
|
|
132
|
+
* @returns An object containing:
|
|
133
|
+
* - deprecated: an array of deprecated environment variable names.
|
|
134
|
+
*/
|
|
135
|
+
function checkDeprecatedEnvVars() {
|
|
136
|
+
const deprecated = DEPRECATED_ENV_VARS.filter(({ key }) => process.env[key]);
|
|
137
|
+
|
|
138
|
+
if (deprecated.length > 0) {
|
|
139
|
+
const deprecatedMessages = deprecated.map(({ key, description }) => {
|
|
140
|
+
const desc = description ? ` # ${description}` : "";
|
|
141
|
+
return `${brush.red(key)}${brush.dim(desc)}`;
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
GriddoLog.warn("Deprecated environment variables set:");
|
|
145
|
+
GriddoLog.log(`${deprecatedMessages.map((str) => `\t${str}`).join("\n")}\n`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return { deprecated: deprecated.map((key) => key) };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Check if the environment is secure to launch a render.
|
|
153
|
+
* If something fails then log an error message and exit from the process.
|
|
154
|
+
* Otherwise just return true.
|
|
155
|
+
*
|
|
156
|
+
* @returns A boolean indicating if the environment is secure to launch a render.
|
|
157
|
+
*/
|
|
158
|
+
function checkEnvironmentHealth() {
|
|
159
|
+
// Check required environment variables
|
|
160
|
+
const envVarsCheck = checkRequiredEnvVars();
|
|
161
|
+
const envValuesCheck = checkEnvVarValues();
|
|
162
|
+
|
|
163
|
+
// (warnings only)
|
|
164
|
+
checkRecommendedEnvVars();
|
|
165
|
+
checkDeprecatedEnvVars();
|
|
166
|
+
|
|
167
|
+
// Render is safe if all required checks pass
|
|
168
|
+
const isSafeToRender = envVarsCheck.isValid && envValuesCheck.isValid;
|
|
169
|
+
|
|
170
|
+
if (isSafeToRender) {
|
|
171
|
+
GriddoLog.info("Build health check passed");
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Generate consolidated error message
|
|
176
|
+
const allIssues: string[] = [];
|
|
177
|
+
|
|
178
|
+
if (!envVarsCheck.isValid) {
|
|
179
|
+
allIssues.push(`Missing:\n${envVarsCheck.missing.map((str) => `\t${str}`).join("\n")}`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (!envValuesCheck.isValid) {
|
|
183
|
+
const mismatchMessages = envValuesCheck.mismatches.map(
|
|
184
|
+
({ key, expected, actual }) => `${key}="${actual || "undefined"}" (expected "${expected}")`,
|
|
185
|
+
);
|
|
186
|
+
allIssues.push(`Incorrect values:\n${mismatchMessages.map((str) => `\t${str}`).join("\n")}`);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Show what needs to be set
|
|
190
|
+
const requiredVarsMessage = REQUIRED_ENV_VALUES.map(({ key, expected, description }) => {
|
|
191
|
+
const desc = description ? ` # ${description}` : "";
|
|
192
|
+
return ` ${key}="${expected}"${desc}`;
|
|
193
|
+
}).join("\n");
|
|
194
|
+
|
|
195
|
+
GriddoLog.error(`Environment health check failed:`);
|
|
196
|
+
GriddoLog.log(`${allIssues.join("\n")}`);
|
|
197
|
+
GriddoLog.warn("\nRequired environment variables:");
|
|
198
|
+
GriddoLog.error(requiredVarsMessage);
|
|
199
|
+
|
|
200
|
+
throwError(CheckHealthError);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export { checkEnvironmentHealth };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { RenderDB } from "../shared/types/render";
|
|
2
|
+
|
|
3
|
+
import fsp from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
import { pkgDirSync } from "../shared/npm-modules/pkg-dir";
|
|
7
|
+
import { GriddoLog } from "./GriddoLog";
|
|
8
|
+
|
|
9
|
+
// Interfaz para abstraer la DB
|
|
10
|
+
export interface Database {
|
|
11
|
+
read(): Promise<RenderDB>;
|
|
12
|
+
write(renderDB: RenderDB): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class JsonDatabase implements Database {
|
|
16
|
+
private readonly dbFilePath: string;
|
|
17
|
+
|
|
18
|
+
constructor(customDBPath?: string) {
|
|
19
|
+
this.dbFilePath =
|
|
20
|
+
customDBPath ??
|
|
21
|
+
path.join(
|
|
22
|
+
pkgDirSync({ cwd: path.resolve(__dirname, "../../..") }) ?? "",
|
|
23
|
+
".griddo/cache/db.json",
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async read(customDBFilePath?: string): Promise<RenderDB> {
|
|
28
|
+
try {
|
|
29
|
+
const raw = await fsp.readFile(customDBFilePath || this.dbFilePath, "utf-8");
|
|
30
|
+
return JSON.parse(raw) as RenderDB;
|
|
31
|
+
} catch (error) {
|
|
32
|
+
if (error instanceof Error) {
|
|
33
|
+
GriddoLog.error(`Error reading DB file at ${this.dbFilePath}:`, error.message);
|
|
34
|
+
} else {
|
|
35
|
+
GriddoLog.error(`Unknown error reading DB file at ${this.dbFilePath}:`, error);
|
|
36
|
+
}
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async write(renderDB: RenderDB): Promise<void> {
|
|
42
|
+
try {
|
|
43
|
+
await fsp.mkdir(path.dirname(this.dbFilePath), { recursive: true });
|
|
44
|
+
await fsp.writeFile(this.dbFilePath, JSON.stringify(renderDB, null, "\t"));
|
|
45
|
+
} catch (error) {
|
|
46
|
+
if (error instanceof Error) {
|
|
47
|
+
GriddoLog.error(`Error writing to DB file at ${this.dbFilePath}:`, error.message);
|
|
48
|
+
} else {
|
|
49
|
+
GriddoLog.error(`Unknown error writing to DB file at ${this.dbFilePath}:`, error);
|
|
50
|
+
}
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { RenderDB } from "../shared/types/render";
|
|
2
|
+
|
|
3
|
+
import fsp from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
import { pkgDirSync } from "../shared/npm-modules/pkg-dir";
|
|
7
|
+
import { GriddoLog } from "./GriddoLog";
|
|
8
|
+
|
|
9
|
+
const root = pkgDirSync({ cwd: path.resolve(__dirname, "../../..") }) || "";
|
|
10
|
+
const cache = path.join(root, ".griddo/cache");
|
|
11
|
+
const dbFilePath = path.join(cache, "db.json");
|
|
12
|
+
|
|
13
|
+
async function readDB(customDBPath = "") {
|
|
14
|
+
const file = customDBPath || dbFilePath;
|
|
15
|
+
try {
|
|
16
|
+
return JSON.parse(await fsp.readFile(file, "utf-8")) as RenderDB;
|
|
17
|
+
} catch (error) {
|
|
18
|
+
GriddoLog.error(`Failed to read DB file at ${file}:`, error);
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function writeDB(renderDB: RenderDB, customDBPath = "") {
|
|
24
|
+
const file = customDBPath || dbFilePath;
|
|
25
|
+
try {
|
|
26
|
+
await fsp.writeFile(file, JSON.stringify(renderDB, null, "\t"));
|
|
27
|
+
} catch (error) {
|
|
28
|
+
GriddoLog.error(`Failed to write DB file at ${file}:`, error);
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { readDB, writeDB };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import fsp from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
import { readDB } from "./db";
|
|
5
|
+
import { pathExists } from "./fs";
|
|
6
|
+
import { GriddoLog } from "./GriddoLog";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Rolls back the exports directory for the given domain.
|
|
10
|
+
*
|
|
11
|
+
* - Deletes the potentially corrupt exports directory for the domain.
|
|
12
|
+
* - If a backup exists, it restores the directory from the backup location.
|
|
13
|
+
* - If no backup is found, it informs that a fresh exports directory will be created on the next render.
|
|
14
|
+
*
|
|
15
|
+
* @param domain The domain for which to rollback the exports directory.
|
|
16
|
+
*/
|
|
17
|
+
async function distRollback(domain: string): Promise<void> {
|
|
18
|
+
const data = await readDB();
|
|
19
|
+
const { exportsDir, exportsDirBackup } = data.paths;
|
|
20
|
+
|
|
21
|
+
GriddoLog.info(`Cleaning exports dir for the domain ${domain}`);
|
|
22
|
+
GriddoLog.verbose(`Deleting ${path.join(exportsDir, domain)}...`);
|
|
23
|
+
|
|
24
|
+
// TODO: Probar rsync en lugar de borrar y copiar
|
|
25
|
+
|
|
26
|
+
// 1 - Borrar dist corrupto
|
|
27
|
+
await fsp.rm(path.join(exportsDir, domain), {
|
|
28
|
+
recursive: true,
|
|
29
|
+
force: true,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// 2 - Si hay backup, restaurar
|
|
33
|
+
if (await pathExists(path.join(exportsDirBackup, domain))) {
|
|
34
|
+
await fsp.cp(path.join(exportsDirBackup, domain), path.join(exportsDir, domain), {
|
|
35
|
+
recursive: true,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
GriddoLog.info(`export-backup dir for the domain ${domain} found. Restoring before exit...`);
|
|
39
|
+
GriddoLog.verbose(
|
|
40
|
+
`Copying ${path.join(exportsDirBackup, domain)} -> ${path.join(exportsDir, domain)}...`,
|
|
41
|
+
);
|
|
42
|
+
} else {
|
|
43
|
+
GriddoLog.info(
|
|
44
|
+
"No export-backup found, skipping rollback. Next render will create a new exports dir from scratch...",
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export { distRollback };
|