@griddo/cx 1.75.178 → 1.75.180
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 +22 -14
- package/build/index.js +49 -0
- package/gatsby-browser.tsx +140 -0
- package/gatsby-config.ts +40 -0
- package/gatsby-node.ts +130 -0
- package/gatsby-ssr.tsx +63 -0
- package/index.js +4 -0
- package/package.json +119 -100
- package/scripts/build-reset.ts +9 -0
- package/scripts/griddo-exporter.ts +302 -0
- package/src/components/Head.tsx +207 -0
- package/src/components/template.tsx +90 -0
- package/src/components/types.ts +35 -0
- package/src/components/utils.ts +138 -0
- package/src/html.tsx +31 -0
- package/src/services/auth.ts +64 -0
- package/src/services/distributors.ts +153 -0
- package/src/services/domains.ts +27 -0
- package/src/services/navigation.ts +169 -0
- package/src/services/robots.ts +64 -0
- package/src/services/settings.ts +52 -0
- package/src/services/sites.ts +199 -0
- package/src/services/store-with-for-loop.ts +513 -0
- package/src/services/store-with-promise-all.ts +515 -0
- package/src/services/store.ts +513 -0
- package/src/types/api.ts +155 -0
- package/src/types/global.ts +72 -0
- package/src/types/navigation.ts +25 -0
- package/src/types/pages.ts +145 -0
- package/src/types/sites.ts +64 -0
- package/src/types/templates.ts +11 -0
- package/src/utils/api.ts +326 -0
- package/src/utils/cache.ts +114 -0
- package/src/utils/domains.ts +32 -0
- package/src/utils/folders.ts +147 -0
- package/src/utils/instance.ts +71 -0
- package/src/utils/pages.ts +534 -0
- package/src/utils/searches.ts +102 -0
- package/src/utils/shared.ts +131 -0
- package/src/utils/sites.ts +280 -0
- package/.babelrc +0 -7
- package/LICENSE +0 -1
- package/gatsby-browser.js +0 -115
- package/gatsby-config.js +0 -38
- package/gatsby-node.js +0 -273
- package/gatsby-ssr.js +0 -43
- package/scripts/griddo-exporter.js +0 -133
- package/src/api/index.js +0 -172
- package/src/components/template.js +0 -261
- package/src/html.js +0 -30
- package/src/images/readme.md +0 -1
- package/src/scripts/build-reset.js +0 -12
- package/src/services/auth.js +0 -44
- package/src/services/distributors.js +0 -85
- package/src/services/domains.js +0 -16
- package/src/services/navigation.js +0 -104
- package/src/services/robots.js +0 -37
- package/src/services/settings.js +0 -25
- package/src/services/sites.js +0 -110
- package/src/utils/cache.js +0 -70
- package/src/utils/component-lib-helpers.js +0 -56
- package/src/utils/dataLayer.js +0 -47
- package/src/utils/delay.js +0 -5
- package/src/utils/domains.js +0 -24
- package/src/utils/folders.js +0 -123
- package/src/utils/helpers.js +0 -144
- package/src/utils/index.js +0 -44
- package/src/utils/package.js +0 -20
- package/src/utils/pages.js +0 -236
- package/src/utils/searches.js +0 -62
- package/src/utils/sites.js +0 -207
- package/static/griddo-full-logo.png +0 -0
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
// //
|
|
2
|
+
// ┌───────────────────┐ //
|
|
3
|
+
// │ Page from API │ ∞ loop //
|
|
4
|
+
// └─────────┬─────────┘ //
|
|
5
|
+
// ┌─┼─┐ //
|
|
6
|
+
// navigations //
|
|
7
|
+
// distributors //
|
|
8
|
+
// etc.. //
|
|
9
|
+
// └─┼─┘ //
|
|
10
|
+
// ┌──────────────┼─────────────┐ //
|
|
11
|
+
// ▼ ▼ ▼ //
|
|
12
|
+
// ┌─────────────┐ ┌───────────┐ ┌───────────┐ //
|
|
13
|
+
// │ Single page │ │ Multipage │ │ Listpages │ //
|
|
14
|
+
// └─────────────┘ └───────────┘ └───────────┘ //
|
|
15
|
+
// ▼ ▼ ▼ //
|
|
16
|
+
// └──────┐ | ┌─────┘ //
|
|
17
|
+
// ▼ ▼ ▼ //
|
|
18
|
+
// ┌─────── S T O R E ─────┐ //
|
|
19
|
+
// │ Array of page objects │ //
|
|
20
|
+
// ├─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┤ //
|
|
21
|
+
// │ Build metadata │ //
|
|
22
|
+
// └─────────────────────────┘ //
|
|
23
|
+
|
|
24
|
+
// Types
|
|
25
|
+
import type { BuildProcessData, StoreMode } from "../types/global";
|
|
26
|
+
import type { GatsbyPageObject, PageAdditionalInfo } from "../types/pages";
|
|
27
|
+
import type { Site } from "../types/sites";
|
|
28
|
+
|
|
29
|
+
// External libraries
|
|
30
|
+
import chalk from "chalk";
|
|
31
|
+
import dotenv from "dotenv";
|
|
32
|
+
import fs from "fs";
|
|
33
|
+
import fsp from "fs/promises";
|
|
34
|
+
import pLimit from "p-limit";
|
|
35
|
+
import path from "path";
|
|
36
|
+
import v8 from "v8";
|
|
37
|
+
|
|
38
|
+
// Services
|
|
39
|
+
import { DistributorService } from "./distributors";
|
|
40
|
+
import { NavigationService } from "./navigation";
|
|
41
|
+
import { RobotsService } from "./robots";
|
|
42
|
+
import { SettingsService } from "./settings";
|
|
43
|
+
import { SitesService } from "./sites";
|
|
44
|
+
|
|
45
|
+
// Utils
|
|
46
|
+
import { version as griddoVersion } from "../../package.json";
|
|
47
|
+
import { createSha256, updatedSiteHash } from "../utils/cache";
|
|
48
|
+
import { deleteSites } from "../utils/folders";
|
|
49
|
+
import {
|
|
50
|
+
createGriddoListPages,
|
|
51
|
+
createGriddoMultiPages,
|
|
52
|
+
createGriddoSinglePage,
|
|
53
|
+
getMultiPageElements,
|
|
54
|
+
getPaginatedPages,
|
|
55
|
+
} from "../utils/pages";
|
|
56
|
+
import { logInfo, walk } from "../utils/shared";
|
|
57
|
+
import { checkSites, getSiteData, unpublishSites } from "../utils/sites";
|
|
58
|
+
|
|
59
|
+
dotenv.config();
|
|
60
|
+
|
|
61
|
+
// Envs
|
|
62
|
+
const API_URL = process.env.API_URL as string;
|
|
63
|
+
const CXBRANCH = process.env.CXBRANCH;
|
|
64
|
+
const REACT_APP_INSTANCE = process.env.GRIDDO_REACT_APP_INSTANCE;
|
|
65
|
+
const GRIDDO_API_CONCURRENCY_COUNT = process.env.GRIDDO_API_CONCURRENCY_COUNT;
|
|
66
|
+
const PUBLIC_API_URL = process.env.PUBLIC_API_URL as string;
|
|
67
|
+
const RENDER_ID = process.env.RENDERID || new Date().valueOf().toString();
|
|
68
|
+
|
|
69
|
+
// Constants shared between Gatsby phases.
|
|
70
|
+
const CREATED_PAGES: Array<number> = [];
|
|
71
|
+
const BUILD_PROCESS_DATA: BuildProcessData = {};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Store service to fetch, process and save temporarily final pages and site
|
|
75
|
+
* data to be consumed by external services (Griddo itself, Gatsby, etc.)
|
|
76
|
+
*
|
|
77
|
+
* Modes:
|
|
78
|
+
* - File mode will save the final page objects in individual files in the file system.
|
|
79
|
+
* - Memory mode will save the final page objects in an array of objects in memory.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* import { StoreService } from "./store"
|
|
83
|
+
*
|
|
84
|
+
* // Init the store service.
|
|
85
|
+
* StoreService.init("foo/pages", { mode: "file" })
|
|
86
|
+
* // Save the data into files.
|
|
87
|
+
* await StoreService.saveBuildData()
|
|
88
|
+
* // Consume the pages as an interator.
|
|
89
|
+
* const pages = StoreService.getPages()
|
|
90
|
+
*/
|
|
91
|
+
class StoreService {
|
|
92
|
+
static basePath: string;
|
|
93
|
+
static mode: "file" | "memory";
|
|
94
|
+
static pages: Array<GatsbyPageObject> = [];
|
|
95
|
+
static sitesToPublish: Array<Site>;
|
|
96
|
+
static buildProcessData: BuildProcessData;
|
|
97
|
+
static createdPages: Array<number>;
|
|
98
|
+
|
|
99
|
+
// Public methods
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Initialize the Store with a path to store the files in file mode and an option object to set the mode.
|
|
103
|
+
*
|
|
104
|
+
* @param basePath The path to store the page files.
|
|
105
|
+
* @param options An object configuration
|
|
106
|
+
* @param options.mode Store mode
|
|
107
|
+
* @todo Avoid initialize the Store with a `basePath` in memory mode.
|
|
108
|
+
*/
|
|
109
|
+
public static init(basePath: string, options: { mode: StoreMode }) {
|
|
110
|
+
const { mode } = options;
|
|
111
|
+
const griddoCxThreads = parseInt(GRIDDO_API_CONCURRENCY_COUNT || "10");
|
|
112
|
+
const modeString = mode === "file" ? "File mode" : "Memory mode";
|
|
113
|
+
|
|
114
|
+
console.log(`🧶 Processing API page calls with ${griddoCxThreads} threads`);
|
|
115
|
+
console.log(`📦 Griddo Store initialized - ${chalk.italic(modeString)}`);
|
|
116
|
+
|
|
117
|
+
if (mode === "file") {
|
|
118
|
+
this.basePath = basePath;
|
|
119
|
+
this.mode = mode;
|
|
120
|
+
|
|
121
|
+
if (fs.existsSync(basePath)) {
|
|
122
|
+
fs.rmSync(basePath, { recursive: true });
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (!fs.existsSync(basePath)) {
|
|
126
|
+
fs.mkdirSync(basePath);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (!fs.existsSync(path.resolve(basePath, "pages"))) {
|
|
130
|
+
fs.mkdirSync(path.resolve(basePath, "pages"));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Save the build data to the Store.
|
|
137
|
+
*/
|
|
138
|
+
public static async saveBuildData() {
|
|
139
|
+
try {
|
|
140
|
+
// Get sites objects to publish and unpublish.
|
|
141
|
+
const { sitesToPublish, sitesToUnpublish } = await checkSites();
|
|
142
|
+
|
|
143
|
+
// The settings will be extracted below in this process.
|
|
144
|
+
await SettingsService.getAll();
|
|
145
|
+
|
|
146
|
+
// If no activity in sites, exit
|
|
147
|
+
if (!(sitesToPublish.length || sitesToUnpublish.length)) {
|
|
148
|
+
console.warn("There are no sites to update");
|
|
149
|
+
|
|
150
|
+
process.exit(0);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Publish and unpublis sites
|
|
154
|
+
console.log(
|
|
155
|
+
chalk.green(
|
|
156
|
+
"\n⬆️ ",
|
|
157
|
+
`(${sitesToPublish.length}) Sites to publish:`,
|
|
158
|
+
sitesToPublish.map(({ name }) => name).join(", "),
|
|
159
|
+
"\n"
|
|
160
|
+
)
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
console.log(
|
|
164
|
+
chalk.red(
|
|
165
|
+
"⬇️ ",
|
|
166
|
+
`(${sitesToUnpublish.length}) Sites to unpublish:`,
|
|
167
|
+
sitesToUnpublish.map(({ name }) => name).join(", "),
|
|
168
|
+
"\n"
|
|
169
|
+
)
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
// Unpublish (API) and delete sites
|
|
173
|
+
await unpublishSites(sitesToUnpublish);
|
|
174
|
+
|
|
175
|
+
// Delete (clean) sites to publish
|
|
176
|
+
await deleteSites([...sitesToPublish]);
|
|
177
|
+
|
|
178
|
+
// Set robots information to use later in the `onPostBuild` phase.
|
|
179
|
+
await RobotsService.loadRobots();
|
|
180
|
+
|
|
181
|
+
// Array of sites (Promises)
|
|
182
|
+
const promisesOfSitesToPublish = sitesToPublish.map(async (site) => {
|
|
183
|
+
// Gets
|
|
184
|
+
const { id: siteId, slug: siteSlug, theme, favicon } = site;
|
|
185
|
+
|
|
186
|
+
const {
|
|
187
|
+
siteInfo,
|
|
188
|
+
validPagesIds,
|
|
189
|
+
siteHash,
|
|
190
|
+
unpublishHashes,
|
|
191
|
+
siteLangs,
|
|
192
|
+
defaultLang,
|
|
193
|
+
headers,
|
|
194
|
+
footers,
|
|
195
|
+
socials,
|
|
196
|
+
// TODO: Check the false here...
|
|
197
|
+
} = await getSiteData(siteId, false);
|
|
198
|
+
|
|
199
|
+
const {
|
|
200
|
+
cloudinaryName,
|
|
201
|
+
useMetaTitle,
|
|
202
|
+
showBasicMetaRobots,
|
|
203
|
+
avoidHrefLangsOnCanonicals,
|
|
204
|
+
avoidSelfReferenceCanonicals,
|
|
205
|
+
avoidHrefLangXDefault,
|
|
206
|
+
avoidDebugMetas,
|
|
207
|
+
} = SettingsService.settings;
|
|
208
|
+
|
|
209
|
+
// Sets
|
|
210
|
+
|
|
211
|
+
BUILD_PROCESS_DATA[siteId] = {
|
|
212
|
+
siteHash,
|
|
213
|
+
unpublishHashes,
|
|
214
|
+
publishHashes: [],
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const NavService = new NavigationService();
|
|
218
|
+
|
|
219
|
+
// Set `headers` and `footers` to the NavService to use later in this process.
|
|
220
|
+
NavService.navigations = { headers, footers };
|
|
221
|
+
|
|
222
|
+
site.languages = siteLangs;
|
|
223
|
+
|
|
224
|
+
const shouldUpdateSite = updatedSiteHash(siteId, siteHash);
|
|
225
|
+
|
|
226
|
+
const siteScript = siteInfo.siteScript;
|
|
227
|
+
|
|
228
|
+
const siteMetadata = {
|
|
229
|
+
siteUrl: siteInfo.slug,
|
|
230
|
+
title: siteInfo.name,
|
|
231
|
+
favicon,
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
const additionalInfo = {
|
|
235
|
+
baseUrl: API_URL,
|
|
236
|
+
publicBaseUrl: PUBLIC_API_URL,
|
|
237
|
+
instance: REACT_APP_INSTANCE,
|
|
238
|
+
siteSlug,
|
|
239
|
+
theme,
|
|
240
|
+
siteMetadata,
|
|
241
|
+
socials,
|
|
242
|
+
siteLangs,
|
|
243
|
+
cloudinaryName,
|
|
244
|
+
griddoVersion,
|
|
245
|
+
siteOptions: {
|
|
246
|
+
useMetaTitle,
|
|
247
|
+
showBasicMetaRobots,
|
|
248
|
+
avoidHrefLangsOnCanonicals,
|
|
249
|
+
avoidSelfReferenceCanonicals,
|
|
250
|
+
avoidHrefLangXDefault,
|
|
251
|
+
avoidDebugMetas,
|
|
252
|
+
},
|
|
253
|
+
BUILD_MODE: CXBRANCH,
|
|
254
|
+
siteScript,
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
logInfo(`${validPagesIds.length} valid pages`);
|
|
258
|
+
|
|
259
|
+
// -------------------------------------------------------------------------
|
|
260
|
+
// Pages loop promise creation
|
|
261
|
+
// -------------------------------------------------------------------------
|
|
262
|
+
// Async function that process every page for one site to use later in the
|
|
263
|
+
// `Promise.all` with pLimit.
|
|
264
|
+
const fetchPageAndSaveToStore = async (pageId: number) => {
|
|
265
|
+
// Here will be store every page returned by the API and processed by
|
|
266
|
+
// Griddo CX.
|
|
267
|
+
let gatsbyPageObjects: Array<GatsbyPageObject> = [];
|
|
268
|
+
|
|
269
|
+
// Get page data
|
|
270
|
+
const page = await SitesService.getPage(pageId, shouldUpdateSite);
|
|
271
|
+
|
|
272
|
+
if (!page) return;
|
|
273
|
+
|
|
274
|
+
// Update Array of page ids
|
|
275
|
+
CREATED_PAGES.push(pageId);
|
|
276
|
+
|
|
277
|
+
// TODO: Use structuredClone() when node 18 is available.
|
|
278
|
+
const pageAdditionalInfo = JSON.parse(
|
|
279
|
+
JSON.stringify(additionalInfo)
|
|
280
|
+
) as PageAdditionalInfo;
|
|
281
|
+
|
|
282
|
+
// Updated with navigations (header & footer)
|
|
283
|
+
// NavService.getPageNavigations returns { header, footer }
|
|
284
|
+
pageAdditionalInfo.navigations = NavService.getPageNavigations(page);
|
|
285
|
+
|
|
286
|
+
// Content Type Data Query
|
|
287
|
+
// Where the pair `hasDistributorData:true` and `data` prop exists, this
|
|
288
|
+
// function will attach a `queriedItems` prop with the result of the fetch
|
|
289
|
+
// for the data.
|
|
290
|
+
const template = await DistributorService.getDistributorData({
|
|
291
|
+
page,
|
|
292
|
+
cached: !!RENDER_ID,
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// MultiPage Query
|
|
296
|
+
// Where the pair `hasGriddoMultiPage:true` prop exists, this function
|
|
297
|
+
// will process the schema and return a multiPageElemtens array to use
|
|
298
|
+
// in `createGriddoMultipages()`
|
|
299
|
+
const multiPageElements = await getMultiPageElements(template);
|
|
300
|
+
|
|
301
|
+
// -----------------------------------------------------------------------
|
|
302
|
+
// Build page objects
|
|
303
|
+
// -----------------------------------------------------------------------
|
|
304
|
+
// Three types of pages
|
|
305
|
+
// - List with pagination (n pages)
|
|
306
|
+
// - Multi-page module (n pages)
|
|
307
|
+
// - Single (1 page)
|
|
308
|
+
|
|
309
|
+
// List
|
|
310
|
+
if (page?.mode === "list") {
|
|
311
|
+
// of data items and the `itemsPerPage` prop.
|
|
312
|
+
gatsbyPageObjects = await createGriddoListPages(
|
|
313
|
+
{
|
|
314
|
+
...page, // Revisar la inclusión de este ...page.
|
|
315
|
+
// The first page, the one without the `/2, /3, /4, etc..` slug
|
|
316
|
+
page,
|
|
317
|
+
// The other pages
|
|
318
|
+
// In this case `getPaginatedPages` doesn't require the whole page object, just the `template` part.
|
|
319
|
+
// This is because only the `template` prop will be different for each page.
|
|
320
|
+
pages: getPaginatedPages(template),
|
|
321
|
+
// The `template` key with the (maybe) distributor data items queried
|
|
322
|
+
template,
|
|
323
|
+
// Pass all data items
|
|
324
|
+
totalQueriedItems: template.queriedItems,
|
|
325
|
+
// Default site language
|
|
326
|
+
defaultLang,
|
|
327
|
+
},
|
|
328
|
+
pageAdditionalInfo
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// >> Multi-page
|
|
333
|
+
if (multiPageElements) {
|
|
334
|
+
gatsbyPageObjects = await createGriddoMultiPages(
|
|
335
|
+
{
|
|
336
|
+
// The whole page object
|
|
337
|
+
...page,
|
|
338
|
+
// The `template` key with the (maybe) distributor data items queried
|
|
339
|
+
template,
|
|
340
|
+
// Array of object of every element of the MultiPage
|
|
341
|
+
multiPageElements,
|
|
342
|
+
// Default site language
|
|
343
|
+
defaultLang,
|
|
344
|
+
},
|
|
345
|
+
pageAdditionalInfo
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// >> Single template
|
|
350
|
+
if (!multiPageElements && page.mode !== "list") {
|
|
351
|
+
gatsbyPageObjects = [
|
|
352
|
+
await createGriddoSinglePage(
|
|
353
|
+
{
|
|
354
|
+
// The whole page object
|
|
355
|
+
...page,
|
|
356
|
+
// The `template` key with the (maybe) distributor data items queried
|
|
357
|
+
template,
|
|
358
|
+
// Default site language
|
|
359
|
+
defaultLang,
|
|
360
|
+
},
|
|
361
|
+
pageAdditionalInfo
|
|
362
|
+
),
|
|
363
|
+
];
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Update hashes
|
|
367
|
+
BUILD_PROCESS_DATA[siteId].publishHashes.push(page.hash);
|
|
368
|
+
|
|
369
|
+
// Save build data to store
|
|
370
|
+
await this.savePages(gatsbyPageObjects); // gatsbyPageObjects is always an array regardless of whether it's just one page
|
|
371
|
+
this.saveSitesToPublish(sitesToPublish);
|
|
372
|
+
this.saveBuildProcessData(BUILD_PROCESS_DATA);
|
|
373
|
+
this.saveCreatedPages(CREATED_PAGES);
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
const griddoCxThreads = parseInt(GRIDDO_API_CONCURRENCY_COUNT || "10");
|
|
377
|
+
|
|
378
|
+
// Create the pLimit array of promises
|
|
379
|
+
const limit = pLimit(griddoCxThreads);
|
|
380
|
+
const pagesToRender = validPagesIds.map((id: number) =>
|
|
381
|
+
limit(() => fetchPageAndSaveToStore(id))
|
|
382
|
+
);
|
|
383
|
+
|
|
384
|
+
await Promise.all(pagesToRender);
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
await Promise.all(promisesOfSitesToPublish);
|
|
388
|
+
} catch (e) {
|
|
389
|
+
const error = e as { message: string };
|
|
390
|
+
|
|
391
|
+
console.error(error.message);
|
|
392
|
+
|
|
393
|
+
process.exit(1);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Get the pages saved previously from the Store.
|
|
399
|
+
*/
|
|
400
|
+
public static getPages() {
|
|
401
|
+
if (this.mode === "file") {
|
|
402
|
+
return this.getPagesFromFiles();
|
|
403
|
+
} else {
|
|
404
|
+
return this.getPagesFromMemory();
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Save the pages into the Store.
|
|
410
|
+
*
|
|
411
|
+
* @param pages An array of pages to save in the store.
|
|
412
|
+
*/
|
|
413
|
+
public static async savePages(pages: Array<GatsbyPageObject>) {
|
|
414
|
+
if (this.mode === "file") {
|
|
415
|
+
await this.savePagesToFiles(pages);
|
|
416
|
+
} else {
|
|
417
|
+
this.savePagesToMemory(pages);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Save site to publish data in the Store.
|
|
423
|
+
*
|
|
424
|
+
* @param sites An array of sites to be published.
|
|
425
|
+
*/
|
|
426
|
+
public static saveSitesToPublish(sites: Array<Site>) {
|
|
427
|
+
this.sitesToPublish = sites;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Save the build process data in the Store.
|
|
432
|
+
*
|
|
433
|
+
* @param buildProcessData An object that represents a build process data.
|
|
434
|
+
*/
|
|
435
|
+
public static saveBuildProcessData(buildProcessData: BuildProcessData) {
|
|
436
|
+
this.buildProcessData = buildProcessData;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Save the created pages in the Store.
|
|
441
|
+
*
|
|
442
|
+
* @param pages An array of pages ids.
|
|
443
|
+
*/
|
|
444
|
+
public static saveCreatedPages(pages: Array<number>) {
|
|
445
|
+
this.createdPages = pages;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Get the build metadata from the Store.
|
|
450
|
+
*/
|
|
451
|
+
public static getMetadata() {
|
|
452
|
+
return {
|
|
453
|
+
buildProcessData: this.buildProcessData,
|
|
454
|
+
createdPages: this.createdPages,
|
|
455
|
+
sitesToPublish: this.sitesToPublish,
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Return an iterator with pages read from the file system.
|
|
461
|
+
*/
|
|
462
|
+
private static *getPagesFromFiles() {
|
|
463
|
+
const pagesDirPath = path.resolve(this.basePath, "pages");
|
|
464
|
+
const jsonFilePaths = walk(pagesDirPath).filter(
|
|
465
|
+
(file) => path.extname(file) === ".json"
|
|
466
|
+
);
|
|
467
|
+
|
|
468
|
+
for (const filePath of jsonFilePaths) {
|
|
469
|
+
const page = require(filePath) as GatsbyPageObject;
|
|
470
|
+
page.size = fs.statSync(filePath).size / 1024;
|
|
471
|
+
yield { ...page };
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Get the pages from the Store from the memory.
|
|
477
|
+
*/
|
|
478
|
+
private static getPagesFromMemory() {
|
|
479
|
+
return this.pages;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Save pages to the file system.
|
|
484
|
+
*
|
|
485
|
+
* @param pages An array of final pages to save into the file system.
|
|
486
|
+
*/
|
|
487
|
+
private static async savePagesToFiles(pages: Array<GatsbyPageObject>) {
|
|
488
|
+
const promises = pages.map(async (pageObject) => {
|
|
489
|
+
const filename = `${createSha256(pageObject.path)}.json`;
|
|
490
|
+
const fileContent = JSON.stringify(pageObject);
|
|
491
|
+
const filePath = path.resolve(this.basePath, "pages", filename);
|
|
492
|
+
await fsp.writeFile(filePath, fileContent);
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
await Promise.all(promises);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Save pages to the memory.
|
|
500
|
+
*
|
|
501
|
+
* @param pages An array of final pages to save into the memory
|
|
502
|
+
*/
|
|
503
|
+
private static savePagesToMemory(pages: Array<GatsbyPageObject>) {
|
|
504
|
+
const pagesWithSize = pages.map((page) => {
|
|
505
|
+
const size = v8.serialize(page).byteLength / 1024;
|
|
506
|
+
|
|
507
|
+
return { ...page, size };
|
|
508
|
+
});
|
|
509
|
+
this.pages.push(...pagesWithSize);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
export { StoreService };
|
package/src/types/api.ts
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// Types
|
|
2
|
+
import type { Core, Fields } from "@griddo/core";
|
|
3
|
+
import { Domains, Robots, Settings } from "./global";
|
|
4
|
+
import type { APIPageObject } from "./pages";
|
|
5
|
+
import type { Site } from "./sites";
|
|
6
|
+
|
|
7
|
+
/** Describes the props of the body object for the API */
|
|
8
|
+
interface Body {
|
|
9
|
+
/** The title of the page. */
|
|
10
|
+
title?: string;
|
|
11
|
+
/** The description of the page. */
|
|
12
|
+
description?: string;
|
|
13
|
+
/** The URL of the page's image. */
|
|
14
|
+
image?: string;
|
|
15
|
+
/** The ID of the page. */
|
|
16
|
+
pageId?: number;
|
|
17
|
+
/** The ID of the page's language. */
|
|
18
|
+
languageId?: number;
|
|
19
|
+
/** The ID of the page's site. */
|
|
20
|
+
siteId?: number;
|
|
21
|
+
/** The URL of the page. */
|
|
22
|
+
url?: string;
|
|
23
|
+
/** The template of the page. */
|
|
24
|
+
template?: string | null | number;
|
|
25
|
+
/** The content of the page. */
|
|
26
|
+
content?: string;
|
|
27
|
+
/** Additional properties. */
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Describes an item in a sitemap. */
|
|
32
|
+
interface SitemapItem {
|
|
33
|
+
/** The URL of the page. */
|
|
34
|
+
loc: string;
|
|
35
|
+
/** The date the page was last modified. */
|
|
36
|
+
lastmod: string;
|
|
37
|
+
/** The priority of the page. */
|
|
38
|
+
priority: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Describes a URL. */
|
|
42
|
+
interface URL {
|
|
43
|
+
/** The path of the URL. */
|
|
44
|
+
path: string;
|
|
45
|
+
/** The domain of the URL. */
|
|
46
|
+
domain: string;
|
|
47
|
+
/** The home of the URL. */
|
|
48
|
+
home: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Describes the items returned by a sitemap response. */
|
|
52
|
+
export type SitemapItems = Record<string, Array<SitemapItem>>;
|
|
53
|
+
|
|
54
|
+
/** Describes the response object returned by a Griddo distributor. */
|
|
55
|
+
export type DistributorResponse = Fields.QueriedData<unknown>;
|
|
56
|
+
|
|
57
|
+
/** Describes the response object returned by socials from Griddo. */
|
|
58
|
+
export type SocialsResponse = Record<Core.SocialName, string>;
|
|
59
|
+
|
|
60
|
+
/** Describes the response object returned by a sitemap. */
|
|
61
|
+
export interface SitemapAPIResponse {
|
|
62
|
+
/** Number of items */
|
|
63
|
+
totalItems: number;
|
|
64
|
+
/** Page id */
|
|
65
|
+
page: number;
|
|
66
|
+
/** Item response by API */
|
|
67
|
+
items: SitemapItems;
|
|
68
|
+
/** Url */
|
|
69
|
+
url: URL;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Descripbes Language responses from Griddo API. */
|
|
73
|
+
export interface LanguagesResponse {
|
|
74
|
+
/** Total of languages */
|
|
75
|
+
totalItems: number;
|
|
76
|
+
/** Array of languages objects */
|
|
77
|
+
items: Array<Core.SiteLanguage>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Describes common props for api responses. */
|
|
81
|
+
interface APIRequest {
|
|
82
|
+
/** The URL of the API endpoint. */
|
|
83
|
+
endpoint: string;
|
|
84
|
+
/** The parameters to be sent in the request body. */
|
|
85
|
+
body?: Body;
|
|
86
|
+
/** Indicates whether to use the cache to get the response from the API. */
|
|
87
|
+
cached?: unknown;
|
|
88
|
+
/** Number of connection attempts (in case it fails on the first attempt). */
|
|
89
|
+
attempt?: number;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Type with the POST request properties. */
|
|
93
|
+
export interface PostAPI extends APIRequest {
|
|
94
|
+
headers?: { lang?: number } & Record<string, unknown>;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Type with the GET request properties. */
|
|
98
|
+
export type GetAPI = APIRequest;
|
|
99
|
+
|
|
100
|
+
/** Type with the PUT request properties. */
|
|
101
|
+
export type PutAPI = APIRequest;
|
|
102
|
+
|
|
103
|
+
/** Response type for the start render API call */
|
|
104
|
+
export interface StartPageRenderResponse {
|
|
105
|
+
/** Site hashes to publish */
|
|
106
|
+
publishIds: Array<number>;
|
|
107
|
+
/** Current site hash */
|
|
108
|
+
siteHash: string | null;
|
|
109
|
+
/** Site hashes to unpublish */
|
|
110
|
+
unpublishHashes: Array<string>;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Response type for the end render API call */
|
|
114
|
+
export interface EndPageInfoResponse {
|
|
115
|
+
/** Response code */
|
|
116
|
+
code: number;
|
|
117
|
+
/** Response message */
|
|
118
|
+
message: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Describes a response type for GET all sites */
|
|
122
|
+
export type AllSitesReponse = Array<Site>;
|
|
123
|
+
|
|
124
|
+
/** Describes a response type for GET all pages */
|
|
125
|
+
export type AllPagesResponse = Array<APIPageObject>;
|
|
126
|
+
|
|
127
|
+
/** Describes a response type for GET one page */
|
|
128
|
+
export type PageResponse = APIPageObject;
|
|
129
|
+
|
|
130
|
+
/** Error type for try/catch */
|
|
131
|
+
export interface Error {
|
|
132
|
+
response: {
|
|
133
|
+
status: number;
|
|
134
|
+
statusText: string;
|
|
135
|
+
data: Record<string, unknown>;
|
|
136
|
+
};
|
|
137
|
+
message: string;
|
|
138
|
+
stack: string;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** All types for the API response used in the api functions get, put, post */
|
|
142
|
+
export type APIResponses =
|
|
143
|
+
| Domains
|
|
144
|
+
| Robots
|
|
145
|
+
| Settings
|
|
146
|
+
| AllSitesReponse
|
|
147
|
+
| Site
|
|
148
|
+
| LanguagesResponse
|
|
149
|
+
| StartPageRenderResponse
|
|
150
|
+
| SitemapAPIResponse
|
|
151
|
+
| SocialsResponse
|
|
152
|
+
| PageResponse
|
|
153
|
+
| EndPageInfoResponse
|
|
154
|
+
| DistributorResponse
|
|
155
|
+
| AllPagesResponse;
|