@websolutespa/bom-mixer-models 2.0.2 → 3.0.1
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/CHANGELOG.md +5 -10
- package/dist/exports/proxy.d.ts +12 -0
- package/dist/exports/proxy.d.ts.map +1 -0
- package/dist/exports/proxy.js +172 -0
- package/dist/exports/proxy.js.map +1 -0
- package/dist/exports/server.d.ts +184 -0
- package/dist/exports/server.d.ts.map +1 -0
- package/dist/exports/server.js +960 -0
- package/dist/exports/server.js.map +1 -0
- package/dist/index.d.ts +254 -424
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -1450
- package/dist/index.js.map +1 -0
- package/dist/lazy-JamSYYoh.d.ts +84 -0
- package/dist/lazy-JamSYYoh.d.ts.map +1 -0
- package/dist/page-BLbZbnWg.js +12 -0
- package/dist/page-BLbZbnWg.js.map +1 -0
- package/dist/route-k0W3AKyo.js +53 -0
- package/dist/route-k0W3AKyo.js.map +1 -0
- package/package.json +75 -27
- package/src/app/app.service.ts +1 -1
- package/src/captions/captions.handler.ts +1 -1
- package/src/category/category.service.ts +3 -3
- package/src/consent_preference/consent_preference.service.ts +4 -4
- package/src/consent_preference/consent_preference.ts +1 -1
- package/src/country/country.service.ts +4 -4
- package/src/exports/proxy.ts +2 -0
- package/src/exports/server.ts +22 -0
- package/src/index.ts +3 -20
- package/src/label/label.service.ts +3 -3
- package/src/lazy/lazy.service.ts +28 -0
- package/src/lazy/lazy.ts +0 -26
- package/src/locale/locale.service.ts +3 -13
- package/src/locale/locale.ts +9 -0
- package/src/market/market.service.ts +3 -3
- package/src/menu/menu.service.ts +3 -3
- package/src/page/page.service.ts +47 -7
- package/src/page/page.ts +9 -0
- package/src/province/province.service.ts +4 -4
- package/src/redirect/redirect.service.ts +4 -4
- package/src/region/region.service.ts +4 -4
- package/src/route/route-revalidate.handler.ts +54 -43
- package/src/route/route.interceptor.ts +18 -3
- package/src/route/route.service.ts +11 -49
- package/src/route/route.ts +64 -0
- package/src/session/session.service.ts +12 -4
- package/src/sitemap/sitemap.service.ts +5 -5
- package/dist/index.mjs +0 -1363
|
@@ -0,0 +1,960 @@
|
|
|
1
|
+
import { newRouteLink, resolveRoute, routeToRouteLink } from "../route-k0W3AKyo.js";
|
|
2
|
+
import { asCategoryId, asServerProps, defaultLocale, defaultMarket, eachMarketLocale, findRouteOfCategory, getCategorySegments, getOrigin, getRootCategory, isDevelopment } from "@websolutespa/bom-core";
|
|
3
|
+
import { BuildStrategy, StoreStrategy, buildStrategy, storeStrategy } from "@websolutespa/bom-mixer-store";
|
|
4
|
+
import { apiHandler, getStore } from "@websolutespa/bom-mixer-store/server";
|
|
5
|
+
import { getIronSession } from "iron-session";
|
|
6
|
+
|
|
7
|
+
//#region src/country/country.service.ts
|
|
8
|
+
async function getCountries(locale) {
|
|
9
|
+
const store = await getStore();
|
|
10
|
+
const items = await store.i18n_country.findMany({ locale });
|
|
11
|
+
return items;
|
|
12
|
+
}
|
|
13
|
+
async function getCountry(id, params = {}) {
|
|
14
|
+
const store = await getStore();
|
|
15
|
+
const item = await store.i18n_country.findOne(id, params);
|
|
16
|
+
return item;
|
|
17
|
+
}
|
|
18
|
+
async function getCountriesPagination(params = {}) {
|
|
19
|
+
const store = await getStore();
|
|
20
|
+
const pagination = await store.i18n_country.findPaged(params);
|
|
21
|
+
return pagination;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/province/province.service.ts
|
|
26
|
+
async function getProvinces(locale) {
|
|
27
|
+
const store = await getStore();
|
|
28
|
+
const items = await store.i18n_province.findMany({ locale });
|
|
29
|
+
return items;
|
|
30
|
+
}
|
|
31
|
+
async function getProvince(id, params = {}) {
|
|
32
|
+
const store = await getStore();
|
|
33
|
+
const item = await store.i18n_province.findOne(id, params);
|
|
34
|
+
return item;
|
|
35
|
+
}
|
|
36
|
+
async function getProvincesPagination(params = {}) {
|
|
37
|
+
const store = await getStore();
|
|
38
|
+
const pagination = await store.i18n_province.findPaged(params);
|
|
39
|
+
return pagination;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/region/region.service.ts
|
|
44
|
+
async function getRegions(locale) {
|
|
45
|
+
const store = await getStore();
|
|
46
|
+
const items = await store.i18n_region.findMany({ locale });
|
|
47
|
+
return items;
|
|
48
|
+
}
|
|
49
|
+
async function getRegion(id, params = {}) {
|
|
50
|
+
const store = await getStore();
|
|
51
|
+
const item = await store.i18n_region.findOne(id, params);
|
|
52
|
+
return item;
|
|
53
|
+
}
|
|
54
|
+
async function getRegionsPagination(params = {}) {
|
|
55
|
+
const store = await getStore();
|
|
56
|
+
const pagination = await store.i18n_region.findPaged(params);
|
|
57
|
+
return pagination;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/address/address.service.ts
|
|
62
|
+
async function getAddressOptions(locale) {
|
|
63
|
+
const countries = await getCountries(locale);
|
|
64
|
+
const provinces = await getProvinces(locale);
|
|
65
|
+
const regions = await getRegions(locale);
|
|
66
|
+
return {
|
|
67
|
+
countries,
|
|
68
|
+
regions,
|
|
69
|
+
provinces
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region src/app/app.service.ts
|
|
75
|
+
async function getApp(params = {}) {
|
|
76
|
+
const store = await getStore();
|
|
77
|
+
const item = await store.app.findGlobal(params);
|
|
78
|
+
return item;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/captions/captions.handler.ts
|
|
83
|
+
const getCaptionsVttProps = async (context) => {
|
|
84
|
+
const { req, res, params, query } = context;
|
|
85
|
+
query?.locale;
|
|
86
|
+
const title = query?.title;
|
|
87
|
+
const captions = `WEBVTT
|
|
88
|
+
|
|
89
|
+
00:00:01.000 --> 00:00:03.000
|
|
90
|
+
- This video has no audio.
|
|
91
|
+
|
|
92
|
+
${title ? `
|
|
93
|
+
00:00:04.000 --> 00:00:06.000
|
|
94
|
+
- The title of the video is "${title}".
|
|
95
|
+
` : ""}`;
|
|
96
|
+
res.setHeader("Content-Type", "text/plain; charset=UTF-8");
|
|
97
|
+
res.setHeader("X-Frame-Options", "SAMEORIGIN");
|
|
98
|
+
res.setHeader("X-Robots-Tag", "noindex, follow");
|
|
99
|
+
res.write(captions);
|
|
100
|
+
res.end();
|
|
101
|
+
return { props: {} };
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/category/category.service.ts
|
|
106
|
+
async function getCategories(params = {}) {
|
|
107
|
+
const store = await getStore();
|
|
108
|
+
const categories = await store.category.findMany(params);
|
|
109
|
+
return categories;
|
|
110
|
+
}
|
|
111
|
+
async function getCategory(id, params = {}) {
|
|
112
|
+
const store = await getStore();
|
|
113
|
+
const item = await store.category.findOne(id, params);
|
|
114
|
+
return item;
|
|
115
|
+
}
|
|
116
|
+
async function getSegments(item, params = {}) {
|
|
117
|
+
const categories = await getCategories(params);
|
|
118
|
+
return getCategorySegments(categories, item);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
//#endregion
|
|
122
|
+
//#region src/consent_preference/consent_preference.service.ts
|
|
123
|
+
async function getConsentPreference(id, params = {}) {
|
|
124
|
+
const store = await getStore();
|
|
125
|
+
const item = await store.consent_preference.findOne(id, params);
|
|
126
|
+
return item;
|
|
127
|
+
}
|
|
128
|
+
async function getConsentPreferences(params = {}) {
|
|
129
|
+
const store = await getStore();
|
|
130
|
+
const items = await store.consent_preference.findMany(params);
|
|
131
|
+
return items;
|
|
132
|
+
}
|
|
133
|
+
async function getConsentPreferencesPagination(params = {}) {
|
|
134
|
+
const store = await getStore();
|
|
135
|
+
const pagination = await store.consent_preference.findPaged(params);
|
|
136
|
+
return pagination;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region src/label/label.service.ts
|
|
141
|
+
async function getLabels(params = {}) {
|
|
142
|
+
const store = await getStore();
|
|
143
|
+
const items = await store.label.findMany(params);
|
|
144
|
+
return items;
|
|
145
|
+
}
|
|
146
|
+
async function getLabel(id, params = {}) {
|
|
147
|
+
const store = await getStore();
|
|
148
|
+
const item = await store.label.findOne(id, params);
|
|
149
|
+
return item;
|
|
150
|
+
}
|
|
151
|
+
function resolveLabel(labels, id) {
|
|
152
|
+
const label = labels.find((x) => x.id === id);
|
|
153
|
+
return label && label.text ? label.text.toString() : id;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
//#endregion
|
|
157
|
+
//#region src/locale/locale.service.ts
|
|
158
|
+
async function getLocales(params = {}) {
|
|
159
|
+
const store = await getStore();
|
|
160
|
+
const items = await store.locale.findMany(params);
|
|
161
|
+
return items;
|
|
162
|
+
}
|
|
163
|
+
async function getLocale(id, params = {}) {
|
|
164
|
+
const store = await getStore();
|
|
165
|
+
const item = await store.locale.findOne(id, params);
|
|
166
|
+
return item;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
//#endregion
|
|
170
|
+
//#region src/market/market.service.ts
|
|
171
|
+
async function getMarkets(params = {}) {
|
|
172
|
+
const store = await getStore();
|
|
173
|
+
const items = await store.market.findMany(params);
|
|
174
|
+
return items;
|
|
175
|
+
}
|
|
176
|
+
async function getMarket(id, params = {}) {
|
|
177
|
+
const store = await getStore();
|
|
178
|
+
const item = await store.market.findOne(id, params);
|
|
179
|
+
return item;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
//#endregion
|
|
183
|
+
//#region src/menu/menu.service.ts
|
|
184
|
+
async function getMenus(params = {}) {
|
|
185
|
+
const store = await getStore();
|
|
186
|
+
const items = await store.menu.findMany(params);
|
|
187
|
+
return items;
|
|
188
|
+
}
|
|
189
|
+
async function getMenu(id, params = {}) {
|
|
190
|
+
const store = await getStore();
|
|
191
|
+
const item = await store.menu.findOne(id, params);
|
|
192
|
+
return item;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
//#endregion
|
|
196
|
+
//#region src/route/route.service.ts
|
|
197
|
+
async function getRoutes(params = {}) {
|
|
198
|
+
const store = await getStore();
|
|
199
|
+
const routes = await store.route.findMany(params);
|
|
200
|
+
return routes;
|
|
201
|
+
}
|
|
202
|
+
async function getRoute(id) {
|
|
203
|
+
const store = await getStore();
|
|
204
|
+
const route = await store.route.findOne(id);
|
|
205
|
+
return route;
|
|
206
|
+
}
|
|
207
|
+
async function getRoutesForSchemas(schemas, market, locale) {
|
|
208
|
+
const store = await getStore();
|
|
209
|
+
const routes = await store.route.findMany({ where: {
|
|
210
|
+
schema: { in: schemas },
|
|
211
|
+
market: { equals: market },
|
|
212
|
+
locale: { equals: locale }
|
|
213
|
+
} });
|
|
214
|
+
const items = {};
|
|
215
|
+
routes.forEach((route) => {
|
|
216
|
+
items[route.schema] = route.id;
|
|
217
|
+
});
|
|
218
|
+
return items;
|
|
219
|
+
}
|
|
220
|
+
async function getRoutesForTemplates(templates, market, locale) {
|
|
221
|
+
const store = await getStore();
|
|
222
|
+
const routes = await store.route.findMany({ where: {
|
|
223
|
+
template: { in: templates },
|
|
224
|
+
market: { equals: market },
|
|
225
|
+
locale: { equals: locale }
|
|
226
|
+
} });
|
|
227
|
+
const items = {};
|
|
228
|
+
routes.forEach((route) => {
|
|
229
|
+
if (route.template) items[route.template] = route.id;
|
|
230
|
+
});
|
|
231
|
+
return items;
|
|
232
|
+
}
|
|
233
|
+
async function getStaticPathsForSchema(schema, template) {
|
|
234
|
+
if (buildStrategy === BuildStrategy.Runtime) return [];
|
|
235
|
+
const store = await getStore();
|
|
236
|
+
const routes = await store.route.findMany({ where: template ? { and: [{ template: { equals: template } }, { schema: { equals: schema } }] } : { schema: { equals: schema } } });
|
|
237
|
+
return routes.map((x) => ({ params: {
|
|
238
|
+
id: x.page.toString(),
|
|
239
|
+
market: x.market,
|
|
240
|
+
locale: x.locale
|
|
241
|
+
} }));
|
|
242
|
+
}
|
|
243
|
+
async function getStaticPathsForSchemaAndFallback(schema, fallback = "blocking", template) {
|
|
244
|
+
if (buildStrategy === BuildStrategy.Runtime || fallback === "blocking" && storeStrategy !== StoreStrategy.Mock) return {
|
|
245
|
+
paths: [],
|
|
246
|
+
fallback
|
|
247
|
+
};
|
|
248
|
+
const paths = await getStaticPathsForSchema(schema, template);
|
|
249
|
+
return {
|
|
250
|
+
paths,
|
|
251
|
+
fallback
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
async function getBreadcrumbFromSegments(segments, route) {
|
|
255
|
+
const market = route.market || defaultMarket;
|
|
256
|
+
const locale = route.locale || defaultLocale;
|
|
257
|
+
const routes = await getRoutes({ where: {
|
|
258
|
+
market: { equals: market },
|
|
259
|
+
locale: { equals: locale }
|
|
260
|
+
} });
|
|
261
|
+
const tree = segments.map((segment) => {
|
|
262
|
+
const route$1 = findRouteOfCategory(routes, segment.id);
|
|
263
|
+
return {
|
|
264
|
+
segment,
|
|
265
|
+
route: route$1
|
|
266
|
+
};
|
|
267
|
+
}).filter((x) => Boolean(x.route)).map((x) => {
|
|
268
|
+
const category = x.segment;
|
|
269
|
+
const route$1 = x.route;
|
|
270
|
+
const routeLink = newRouteLink(category, route$1, locale);
|
|
271
|
+
return routeLink;
|
|
272
|
+
});
|
|
273
|
+
if (!route.isDefault) tree.push(routeToRouteLink(route));
|
|
274
|
+
return tree;
|
|
275
|
+
}
|
|
276
|
+
async function getRouteLinkTree(market, locale) {
|
|
277
|
+
const store = await getStore();
|
|
278
|
+
const routes = await store.route.findMany({ where: {
|
|
279
|
+
market: { equals: market },
|
|
280
|
+
locale: { equals: locale }
|
|
281
|
+
} });
|
|
282
|
+
const categories = await store.category.findMany({
|
|
283
|
+
market,
|
|
284
|
+
locale
|
|
285
|
+
});
|
|
286
|
+
const rootCategory = getRootCategory(categories);
|
|
287
|
+
if (rootCategory) {
|
|
288
|
+
const root = getRouteLinkCategory(locale, routes, categories, rootCategory, rootCategory);
|
|
289
|
+
return root;
|
|
290
|
+
}
|
|
291
|
+
return void 0;
|
|
292
|
+
}
|
|
293
|
+
function getRouteLinkCategory(locale, routes, categories, rootCategory, category) {
|
|
294
|
+
const route = findRouteOfCategory(routes, category.id);
|
|
295
|
+
const otherCategories = categories.filter((x) => x.id !== category.id);
|
|
296
|
+
const childCategories = otherCategories.filter((x) => asCategoryId(x.category) === category.id);
|
|
297
|
+
const routeLink = newRouteLink(category, route, locale);
|
|
298
|
+
const items = [];
|
|
299
|
+
for (const childCategory of childCategories) {
|
|
300
|
+
const itemOrItems = getRouteLinkCategory(locale, routes, otherCategories, rootCategory, childCategory);
|
|
301
|
+
if (Array.isArray(itemOrItems)) items.push(...itemOrItems);
|
|
302
|
+
else if (itemOrItems) items.push(itemOrItems);
|
|
303
|
+
}
|
|
304
|
+
if (!route || category.isHidden && category.id !== rootCategory.id) return items;
|
|
305
|
+
routeLink.items = items;
|
|
306
|
+
return routeLink;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
//#endregion
|
|
310
|
+
//#region src/layout/layout.service.ts
|
|
311
|
+
async function getLayout(market, locale) {
|
|
312
|
+
const markets = await getMarkets({ locale });
|
|
313
|
+
const locales = await getLocales({ locale });
|
|
314
|
+
const labels = await getLabels({ locale });
|
|
315
|
+
const app = await getApp({ locale }) || {};
|
|
316
|
+
const tree = await getRouteLinkTree(market, locale);
|
|
317
|
+
const firstLevelRoutes = tree?.items || [];
|
|
318
|
+
const flatTopLevelRoutes = tree ? [tree, ...firstLevelRoutes] : [];
|
|
319
|
+
const topLevelRoutes = flatTopLevelRoutes.reduce((object, routeLink) => {
|
|
320
|
+
if (!object[routeLink.schema] || routeLink.schema === routeLink.category) object[routeLink.schema] = routeLink;
|
|
321
|
+
return object;
|
|
322
|
+
}, {});
|
|
323
|
+
const topLevelHrefs = flatTopLevelRoutes.reduce((object, routeLink) => {
|
|
324
|
+
if (routeLink.href && (!object[routeLink.schema] || routeLink.schema === routeLink.category)) object[routeLink.schema] = routeLink.href;
|
|
325
|
+
return object;
|
|
326
|
+
}, {});
|
|
327
|
+
const menu = {};
|
|
328
|
+
const menus = await getMenus({
|
|
329
|
+
market,
|
|
330
|
+
locale
|
|
331
|
+
});
|
|
332
|
+
menus.forEach((x) => {
|
|
333
|
+
menu[x.id] = x;
|
|
334
|
+
});
|
|
335
|
+
return {
|
|
336
|
+
labels,
|
|
337
|
+
locale,
|
|
338
|
+
locales,
|
|
339
|
+
market,
|
|
340
|
+
markets,
|
|
341
|
+
app,
|
|
342
|
+
menu,
|
|
343
|
+
topLevelHrefs,
|
|
344
|
+
topLevelRoutes,
|
|
345
|
+
tree
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
//#endregion
|
|
350
|
+
//#region src/lazy/lazy.service.ts
|
|
351
|
+
const LAZY_PROPS = {};
|
|
352
|
+
async function withLazyProps(key, getComponentProps) {
|
|
353
|
+
LAZY_PROPS[key] = getComponentProps;
|
|
354
|
+
}
|
|
355
|
+
async function getDecoratedComponents(props, extraComponents) {
|
|
356
|
+
const page = props.page;
|
|
357
|
+
const components = [...page.components || [], ...extraComponents || []];
|
|
358
|
+
const decoratedComponents = [];
|
|
359
|
+
for (const component of components) {
|
|
360
|
+
const key = component.blockType || component.schema || "unkown_type";
|
|
361
|
+
const getComponentProps = LAZY_PROPS[key];
|
|
362
|
+
if (typeof getComponentProps === "function") {
|
|
363
|
+
const decoratedComponent = await getComponentProps({
|
|
364
|
+
...props,
|
|
365
|
+
component
|
|
366
|
+
});
|
|
367
|
+
decoratedComponents.push(decoratedComponent);
|
|
368
|
+
} else decoratedComponents.push(component);
|
|
369
|
+
}
|
|
370
|
+
page.components = decoratedComponents;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
//#endregion
|
|
374
|
+
//#region src/page/page.service.ts
|
|
375
|
+
async function findOnePage(schema, id, params) {
|
|
376
|
+
const store = await getStore();
|
|
377
|
+
const collection = store[schema];
|
|
378
|
+
if (!collection) throw `PageService.findOnePage: Collection not found [${schema}]`;
|
|
379
|
+
const page = await collection.findOne(id, params);
|
|
380
|
+
if (page) return page;
|
|
381
|
+
else {
|
|
382
|
+
console.log("PageService.findOnePage.notfound", schema, params);
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
async function findManyPages(schema, params) {
|
|
387
|
+
const store = await getStore();
|
|
388
|
+
const collection = store[schema];
|
|
389
|
+
if (!collection) throw `PageService.findManyPages: Collection not found [${schema}]`;
|
|
390
|
+
const pages = await collection.findMany(params);
|
|
391
|
+
return pages;
|
|
392
|
+
}
|
|
393
|
+
async function getPage(schema, id, market, locale, options) {
|
|
394
|
+
const { depth = 3, draftMode = false, previewData } = options || {};
|
|
395
|
+
const draft = draftMode === true;
|
|
396
|
+
const page = await findOnePage(schema, id, {
|
|
397
|
+
market,
|
|
398
|
+
locale,
|
|
399
|
+
depth,
|
|
400
|
+
draft
|
|
401
|
+
});
|
|
402
|
+
if (page) {
|
|
403
|
+
const routes = await getPageRoutes(schema, id);
|
|
404
|
+
const currentRoute = routes.find((x) => x.market === market && x.locale === locale);
|
|
405
|
+
const alternates = routes;
|
|
406
|
+
const segments = await getSegments(page, {
|
|
407
|
+
market,
|
|
408
|
+
locale
|
|
409
|
+
});
|
|
410
|
+
const breadcrumb = currentRoute ? await getBreadcrumbFromSegments(segments, currentRoute) : [];
|
|
411
|
+
const parentRoute = breadcrumb.length > 1 ? breadcrumb[breadcrumb.length - 2] : void 0;
|
|
412
|
+
const pageResult = {
|
|
413
|
+
...page,
|
|
414
|
+
href: currentRoute?.id,
|
|
415
|
+
alternates,
|
|
416
|
+
breadcrumb,
|
|
417
|
+
parentRoute
|
|
418
|
+
};
|
|
419
|
+
return pageResult;
|
|
420
|
+
} else {
|
|
421
|
+
console.log("PageService.getPage.notfound", schema, id, locale);
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
async function getSchemaRoutes(schema, market, locale) {
|
|
426
|
+
const routes = await getRoutes({ where: {
|
|
427
|
+
market: { equals: market },
|
|
428
|
+
locale: { equals: locale },
|
|
429
|
+
schema: { equals: schema }
|
|
430
|
+
} });
|
|
431
|
+
return routes;
|
|
432
|
+
}
|
|
433
|
+
async function getNotFoundRoute(market, locale) {
|
|
434
|
+
const routes = await getRoutes({ where: {
|
|
435
|
+
market: { equals: market },
|
|
436
|
+
locale: { equals: locale },
|
|
437
|
+
schema: { equals: "notfound" }
|
|
438
|
+
} });
|
|
439
|
+
if (routes.length > 0) return routes[0];
|
|
440
|
+
}
|
|
441
|
+
async function NotFound(market, locale) {
|
|
442
|
+
const routes = await getRoutes({ where: {
|
|
443
|
+
market: { equals: market },
|
|
444
|
+
locale: { equals: locale },
|
|
445
|
+
schema: { equals: "notfound" }
|
|
446
|
+
} });
|
|
447
|
+
if (routes.length > 0) return { redirect: {
|
|
448
|
+
destination: routes[0].id,
|
|
449
|
+
permanent: false
|
|
450
|
+
} };
|
|
451
|
+
}
|
|
452
|
+
async function getPageRoutes(schema, id) {
|
|
453
|
+
const store = await getStore();
|
|
454
|
+
let routes = [];
|
|
455
|
+
try {
|
|
456
|
+
routes = await store.route.findMany({ where: {
|
|
457
|
+
page: { equals: id },
|
|
458
|
+
schema: { equals: schema }
|
|
459
|
+
} });
|
|
460
|
+
} catch (error) {
|
|
461
|
+
console.error("No routes found for page " + schema + ":" + id);
|
|
462
|
+
}
|
|
463
|
+
return routes;
|
|
464
|
+
}
|
|
465
|
+
async function getPageCategory(schema, page, market, locale) {
|
|
466
|
+
if (!page) return;
|
|
467
|
+
const store = await getStore();
|
|
468
|
+
const pages = await findManyPages(schema, {
|
|
469
|
+
where: { category: { equals: asCategoryId(page.category) } },
|
|
470
|
+
market,
|
|
471
|
+
locale
|
|
472
|
+
});
|
|
473
|
+
const category = pages.length ? pages[0] : null;
|
|
474
|
+
if (category) {
|
|
475
|
+
const routes = await store.route.findMany({ where: {
|
|
476
|
+
schema: { equals: schema },
|
|
477
|
+
page: { equals: category.id }
|
|
478
|
+
} });
|
|
479
|
+
const currentRoute = routes.find((x) => x.market === market && x.locale === locale);
|
|
480
|
+
if (!currentRoute) throw "No route found for page " + schema + ":" + category.id + " in market " + market + " and locale " + locale;
|
|
481
|
+
return {
|
|
482
|
+
...category,
|
|
483
|
+
href: currentRoute.id
|
|
484
|
+
};
|
|
485
|
+
} else {
|
|
486
|
+
console.log("PageService.getPageCategory.notfound", schema, locale);
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
async function getErrorPageLayout() {
|
|
491
|
+
const layout = await getLayout(defaultMarket, defaultLocale);
|
|
492
|
+
const title = resolveLabel(layout.labels, "notfound.title");
|
|
493
|
+
const abstract = resolveLabel(layout.labels, "notfound.abstract");
|
|
494
|
+
const category = layout.tree ? {
|
|
495
|
+
id: layout.tree.category,
|
|
496
|
+
title: layout.tree.title,
|
|
497
|
+
href: layout.tree.href,
|
|
498
|
+
slug: ""
|
|
499
|
+
} : {
|
|
500
|
+
id: "homepage",
|
|
501
|
+
title: "Homepage",
|
|
502
|
+
slug: "",
|
|
503
|
+
href: "/"
|
|
504
|
+
};
|
|
505
|
+
const page = {
|
|
506
|
+
abstract,
|
|
507
|
+
alternates: [],
|
|
508
|
+
breadcrumb: [],
|
|
509
|
+
category,
|
|
510
|
+
slug: "",
|
|
511
|
+
href: "",
|
|
512
|
+
id: "notfound",
|
|
513
|
+
locale: layout.locale,
|
|
514
|
+
market: layout.market,
|
|
515
|
+
markets: [],
|
|
516
|
+
meta: {
|
|
517
|
+
title,
|
|
518
|
+
description: abstract,
|
|
519
|
+
keywords: "",
|
|
520
|
+
robots: "all"
|
|
521
|
+
},
|
|
522
|
+
schema: "notfound",
|
|
523
|
+
title
|
|
524
|
+
};
|
|
525
|
+
return {
|
|
526
|
+
layout,
|
|
527
|
+
page
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
async function getPageProps(props, extraComponents) {
|
|
531
|
+
if (props.page) await getDecoratedComponents(props, extraComponents);
|
|
532
|
+
return asServerProps(props);
|
|
533
|
+
}
|
|
534
|
+
function getPublicUrl() {
|
|
535
|
+
const publicUrl = process.env && process.env.NEXT_PUBLIC_URL ? process.env.NEXT_PUBLIC_URL : "";
|
|
536
|
+
return publicUrl;
|
|
537
|
+
}
|
|
538
|
+
function resolveHref(href) {
|
|
539
|
+
href = href || "";
|
|
540
|
+
return href.startsWith("http") ? href : `${getPublicUrl()}${href}`;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
//#endregion
|
|
544
|
+
//#region src/redirect/redirect.service.ts
|
|
545
|
+
async function getRedirects(locale) {
|
|
546
|
+
const store = await getStore();
|
|
547
|
+
const items = await store.redirect.findMany({ locale });
|
|
548
|
+
return items;
|
|
549
|
+
}
|
|
550
|
+
async function getRedirect(id, params = {}) {
|
|
551
|
+
const store = await getStore();
|
|
552
|
+
const item = await store.redirect.findOne(id, params);
|
|
553
|
+
return item;
|
|
554
|
+
}
|
|
555
|
+
async function getRedirectsPagination(params = {}) {
|
|
556
|
+
const store = await getStore();
|
|
557
|
+
const pagination = await store.redirect.findPaged(params);
|
|
558
|
+
return pagination;
|
|
559
|
+
}
|
|
560
|
+
function redirectTo(layout, key = "not_found") {
|
|
561
|
+
return { redirect: {
|
|
562
|
+
permanent: false,
|
|
563
|
+
destination: layout.topLevelHrefs[key] || "/"
|
|
564
|
+
} };
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
//#endregion
|
|
568
|
+
//#region src/route/route-revalidate.handler.ts
|
|
569
|
+
function routeRevalidateHandler() {
|
|
570
|
+
return apiHandler({ post: async (request, response) => {
|
|
571
|
+
const authorization = request.headers.authorization;
|
|
572
|
+
const bearer = authorization && authorization.replace("Bearer ", "");
|
|
573
|
+
if (bearer !== process.env.MIXER_SECRET) return response.status(401).json({ message: "Invalid token" });
|
|
574
|
+
try {
|
|
575
|
+
const { href, schema, page } = request.body || {};
|
|
576
|
+
let where;
|
|
577
|
+
if (href) where = { id: { equals: href } };
|
|
578
|
+
else if (schema && page) where = {
|
|
579
|
+
schema: { equals: schema },
|
|
580
|
+
page: { equals: page }
|
|
581
|
+
};
|
|
582
|
+
else return response.status(400).send("Missing href or schema and page");
|
|
583
|
+
const routes = await getRoutes({ where });
|
|
584
|
+
if (routes.length === 0) {
|
|
585
|
+
const notFoundTarget = href || `${schema}:${page}`;
|
|
586
|
+
return response.status(404).send(`routeRevalidateHandler.notFound ${notFoundTarget}`);
|
|
587
|
+
}
|
|
588
|
+
for (const route of routes) {
|
|
589
|
+
const resolvedRoute = resolveRoute(route);
|
|
590
|
+
await response.revalidate(resolvedRoute);
|
|
591
|
+
}
|
|
592
|
+
return response.json({ revalidated: true });
|
|
593
|
+
} catch (error) {
|
|
594
|
+
return response.status(500).send("Error revalidating");
|
|
595
|
+
}
|
|
596
|
+
} });
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
//#endregion
|
|
600
|
+
//#region src/session/session.service.ts
|
|
601
|
+
function getSessionSecret() {
|
|
602
|
+
const secret = process.env.MIXER_SECRET || "";
|
|
603
|
+
if (!secret) throw "getSessionSecret MIXER_SECRET not defined";
|
|
604
|
+
return secret;
|
|
605
|
+
}
|
|
606
|
+
async function getSession(request, response) {
|
|
607
|
+
const cookieName = "websolutespa-next-js";
|
|
608
|
+
const password = getSessionSecret();
|
|
609
|
+
const sessionOptions = {
|
|
610
|
+
cookieName,
|
|
611
|
+
password,
|
|
612
|
+
cookieOptions: { secure: !isDevelopment }
|
|
613
|
+
};
|
|
614
|
+
const session = await getIronSession(request, response, sessionOptions);
|
|
615
|
+
return session;
|
|
616
|
+
}
|
|
617
|
+
async function getSessionToken(request, response) {
|
|
618
|
+
const session = await getSession(request, response);
|
|
619
|
+
if (session.token && session.exp && session.exp > Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3)) return session.token;
|
|
620
|
+
else {
|
|
621
|
+
session.token = void 0;
|
|
622
|
+
session.exp = void 0;
|
|
623
|
+
await session.save();
|
|
624
|
+
session.destroy();
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
//#endregion
|
|
630
|
+
//#region src/sitemap/sitemap.service.ts
|
|
631
|
+
async function getSiteMapIndex(origin) {
|
|
632
|
+
let markets = await getMarkets();
|
|
633
|
+
let locales = await getLocales();
|
|
634
|
+
markets = markets.filter((x) => x.isActive !== false);
|
|
635
|
+
locales = locales.filter((x) => x.isActive !== false);
|
|
636
|
+
const routes = await getRoutes();
|
|
637
|
+
const sitemaps = [];
|
|
638
|
+
const getTime = (date) => {
|
|
639
|
+
return typeof date !== "undefined" ? (typeof date === "string" ? new Date(date) : date).getTime() : 0;
|
|
640
|
+
};
|
|
641
|
+
eachMarketLocale(markets, locales, (market, locale, markets$1, locales$1) => {
|
|
642
|
+
const sitemapRoutes = routes.filter((x) => x.market === market.id && x.locale === locale.id);
|
|
643
|
+
sitemapRoutes.sort((a, b) => getTime(a.updatedAt) - getTime(b.updatedAt));
|
|
644
|
+
sitemaps.push({
|
|
645
|
+
id: `/${market.id}/${locale.id}/sitemap.xml`,
|
|
646
|
+
updatedAt: sitemapRoutes.length > 0 ? sitemapRoutes[sitemapRoutes.length - 1].updatedAt : void 0
|
|
647
|
+
});
|
|
648
|
+
});
|
|
649
|
+
return `<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="${origin}/sitemap.xsl"?>
|
|
650
|
+
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
651
|
+
${sitemaps.map((sitemap) => `
|
|
652
|
+
<sitemap>
|
|
653
|
+
<loc>${escapeHtml(encodeURI(`${origin}${sitemap.id}`))}</loc>${sitemap.updatedAt ? `
|
|
654
|
+
<lastmod>${escapeHtml(String(sitemap.updatedAt))}</lastmod>` : ""}
|
|
655
|
+
</sitemap>
|
|
656
|
+
`).join("")}
|
|
657
|
+
</sitemapindex>`;
|
|
658
|
+
}
|
|
659
|
+
function getSiteMapXMLLastMod(canonical) {
|
|
660
|
+
return canonical.updatedAt ? `
|
|
661
|
+
<lastmod>${escapeHtml(String(canonical.updatedAt))}</lastmod>` : "";
|
|
662
|
+
}
|
|
663
|
+
function getSiteMapXMLImage(canonical) {
|
|
664
|
+
return canonical.media ? `
|
|
665
|
+
<image:image>
|
|
666
|
+
<image:loc>${escapeHtml(encodeURI(`${canonical.media.src || canonical.media.url}`))}</image:loc>
|
|
667
|
+
</image:image>` : "";
|
|
668
|
+
}
|
|
669
|
+
function getSiteMapXMLAlternates(origin, canonical) {
|
|
670
|
+
return canonical.alternates.map((alternate) => `
|
|
671
|
+
<xhtml:link href="${escapeHtml(encodeURI(`${origin}${alternate.id}`))}" hreflang="${alternate.locale}-${alternate.market}" rel="alternate" />`).join("");
|
|
672
|
+
}
|
|
673
|
+
function getSiteMapXMLUrl(origin, canonical) {
|
|
674
|
+
return `
|
|
675
|
+
<url>
|
|
676
|
+
<loc>${escapeHtml(encodeURI(`${origin}${canonical.id}`))}</loc>${getSiteMapXMLLastMod(canonical)}${getSiteMapXMLAlternates(origin, canonical)}${getSiteMapXMLImage(canonical)}
|
|
677
|
+
</url>`;
|
|
678
|
+
}
|
|
679
|
+
function escapeHtml(string) {
|
|
680
|
+
const matchHtmlRegExp = /["'&<>]/;
|
|
681
|
+
const str = "" + string;
|
|
682
|
+
const match = matchHtmlRegExp.exec(str);
|
|
683
|
+
if (!match) return str;
|
|
684
|
+
let escape;
|
|
685
|
+
let html = "";
|
|
686
|
+
let index = 0;
|
|
687
|
+
let lastIndex = 0;
|
|
688
|
+
for (index = match.index; index < str.length; index++) {
|
|
689
|
+
switch (str.charCodeAt(index)) {
|
|
690
|
+
case 34:
|
|
691
|
+
escape = """;
|
|
692
|
+
break;
|
|
693
|
+
case 38:
|
|
694
|
+
escape = "&";
|
|
695
|
+
break;
|
|
696
|
+
case 39:
|
|
697
|
+
escape = "'";
|
|
698
|
+
break;
|
|
699
|
+
case 60:
|
|
700
|
+
escape = "<";
|
|
701
|
+
break;
|
|
702
|
+
case 62:
|
|
703
|
+
escape = ">";
|
|
704
|
+
break;
|
|
705
|
+
default: continue;
|
|
706
|
+
}
|
|
707
|
+
if (lastIndex !== index) html += str.substring(lastIndex, index);
|
|
708
|
+
lastIndex = index + 1;
|
|
709
|
+
html += escape;
|
|
710
|
+
}
|
|
711
|
+
return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
|
|
712
|
+
}
|
|
713
|
+
function getSiteMapXMLUrls(origin, canonicalRoutes) {
|
|
714
|
+
return canonicalRoutes.map((canonicalRoute) => getSiteMapXMLUrl(origin, canonicalRoute)).join("");
|
|
715
|
+
}
|
|
716
|
+
async function getSiteMapXML(origin, marketId, localeId) {
|
|
717
|
+
let markets = await getMarkets();
|
|
718
|
+
let locales = await getLocales();
|
|
719
|
+
markets = markets.filter((x) => x.isActive !== false);
|
|
720
|
+
locales = locales.filter((x) => x.isActive !== false);
|
|
721
|
+
const defaultMarket$1 = markets.find((x) => marketId ? x.id === marketId : x.isDefault) || markets[0];
|
|
722
|
+
const defaultLocale$1 = locales.find((x) => localeId ? x.id === localeId : x.isDefault) || locales[0];
|
|
723
|
+
const defaultMarketLocale = defaultMarket$1 && defaultMarket$1.defaultLanguage ? defaultMarket$1.defaultLanguage : defaultLocale$1.id;
|
|
724
|
+
const routes = await getRoutes();
|
|
725
|
+
const isCanonicalRoute = marketId && localeId ? (route) => {
|
|
726
|
+
return route.noindex !== true && route.market === defaultMarket$1.id && route.locale === defaultLocale$1.id;
|
|
727
|
+
} : (route) => {
|
|
728
|
+
return route.noindex !== true && route.market === defaultMarket$1.id && route.locale === defaultMarketLocale;
|
|
729
|
+
};
|
|
730
|
+
const getCanonicalAlternates = marketId && localeId ? (canonical) => {
|
|
731
|
+
return [];
|
|
732
|
+
} : (canonical) => {
|
|
733
|
+
return routes.filter((alternate) => {
|
|
734
|
+
return alternate !== canonical && alternate.schema === canonical.schema && alternate.page === canonical.page;
|
|
735
|
+
});
|
|
736
|
+
};
|
|
737
|
+
const routeToRouteCanonical = (canonical) => {
|
|
738
|
+
const alternates = getCanonicalAlternates(canonical);
|
|
739
|
+
return {
|
|
740
|
+
...canonical,
|
|
741
|
+
alternates
|
|
742
|
+
};
|
|
743
|
+
};
|
|
744
|
+
const canonicalRoutes = routes.filter(isCanonicalRoute).map(routeToRouteCanonical);
|
|
745
|
+
return `<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="${origin}/sitemap.xsl"?>
|
|
746
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
|
747
|
+
xmlns:xhtml="http://www.w3.org/1999/xhtml"
|
|
748
|
+
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
|
|
749
|
+
${getSiteMapXMLUrls(origin, canonicalRoutes)}
|
|
750
|
+
</urlset>
|
|
751
|
+
`;
|
|
752
|
+
}
|
|
753
|
+
async function getSiteMapXSL(localeId) {
|
|
754
|
+
let locales = await getLocales();
|
|
755
|
+
locales = locales.filter((x) => x.isActive !== false);
|
|
756
|
+
const locale = locales.find((x) => localeId ? x.id === localeId : x.isDefault) || locales[0];
|
|
757
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
758
|
+
<xsl:stylesheet version="2.0"
|
|
759
|
+
xmlns:html="http://www.w3.org/TR/REC-html40"
|
|
760
|
+
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
|
|
761
|
+
xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9"
|
|
762
|
+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
|
763
|
+
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
|
|
764
|
+
<xsl:template match="/">
|
|
765
|
+
<html lang="${locale.id}" xmlns="http://www.w3.org/1999/xhtml">
|
|
766
|
+
<head>
|
|
767
|
+
<title>XML Sitemap</title>
|
|
768
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
769
|
+
<style type="text/css">
|
|
770
|
+
html {
|
|
771
|
+
padding: 0;
|
|
772
|
+
background: #09090A;
|
|
773
|
+
color: #fefefe;
|
|
774
|
+
}
|
|
775
|
+
body {
|
|
776
|
+
padding: 15px;
|
|
777
|
+
font-family: Inter,-apple-system,'Helvetica Neue','Segoe UI',Roboto,Arial,'Noto Sans',sans-serif;
|
|
778
|
+
font-size: 13px;
|
|
779
|
+
background: #09090A;
|
|
780
|
+
color: #fefefe;
|
|
781
|
+
}
|
|
782
|
+
.container {
|
|
783
|
+
margin: 0 auto;
|
|
784
|
+
max-width: 1280px;
|
|
785
|
+
}
|
|
786
|
+
a {
|
|
787
|
+
color: #fefefe;
|
|
788
|
+
text-decoration: none;
|
|
789
|
+
}
|
|
790
|
+
a:visited {
|
|
791
|
+
color: #9e9e9e;
|
|
792
|
+
}
|
|
793
|
+
a:hover {
|
|
794
|
+
text-decoration: underline;
|
|
795
|
+
}
|
|
796
|
+
table {
|
|
797
|
+
width: 100%;
|
|
798
|
+
margin: 10px 0;
|
|
799
|
+
border: none;
|
|
800
|
+
border-collapse: collapse;
|
|
801
|
+
}
|
|
802
|
+
td,
|
|
803
|
+
th {
|
|
804
|
+
text-align: left;
|
|
805
|
+
font-size: 12px;
|
|
806
|
+
padding: 3px;
|
|
807
|
+
}
|
|
808
|
+
th:not(:last-child),
|
|
809
|
+
td:not(:last-child) {
|
|
810
|
+
padding-right: 30px;
|
|
811
|
+
}
|
|
812
|
+
thead th {
|
|
813
|
+
border-bottom: 1px solid #0e0e0f;
|
|
814
|
+
}
|
|
815
|
+
#sitemap tr:nth-child(odd) td {
|
|
816
|
+
background-color: #0e0e0f;
|
|
817
|
+
}
|
|
818
|
+
#sitemap tbody tr:hover td {
|
|
819
|
+
background-color: #1A1A1B;
|
|
820
|
+
}
|
|
821
|
+
#sitemap tbody tr:hover td,
|
|
822
|
+
#sitemap tbody tr:hover td a {
|
|
823
|
+
color: #fefefe;
|
|
824
|
+
}
|
|
825
|
+
.wysiwyg {
|
|
826
|
+
margin: 0;
|
|
827
|
+
padding: 0 0 10px 0;
|
|
828
|
+
line-height: 1.2em;
|
|
829
|
+
}
|
|
830
|
+
.wysiwyg a {
|
|
831
|
+
color: #00ea4e;
|
|
832
|
+
font-weight: 600;
|
|
833
|
+
}
|
|
834
|
+
.wysiwyg a:visited {
|
|
835
|
+
color: #00ea4e;
|
|
836
|
+
}
|
|
837
|
+
</style>
|
|
838
|
+
</head>
|
|
839
|
+
<body>
|
|
840
|
+
<div class="container">
|
|
841
|
+
<h1>XML Sitemap</h1>
|
|
842
|
+
<p class="wysiwyg">
|
|
843
|
+
This is an XML Sitemap meant for consumption by search engines, generated by <a href="https://github.com/websolutespa/bom" target="_blank" rel="noopener">Mixer</a>.
|
|
844
|
+
</p>
|
|
845
|
+
<p class="wysiwyg">
|
|
846
|
+
You can find more information about XML sitemaps on <a href="https://sitemaps.org" target="_blank" rel="noopener">sitemaps.org</a>.
|
|
847
|
+
</p>
|
|
848
|
+
<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) > 0">
|
|
849
|
+
<p class="wysiwyg">
|
|
850
|
+
This sitemap index file contains <xsl:value-of select="count(sitemap:sitemapindex/sitemap:sitemap)"/> sitemaps.
|
|
851
|
+
</p>
|
|
852
|
+
<table id="sitemap" cellpadding="3">
|
|
853
|
+
<thead>
|
|
854
|
+
<tr>
|
|
855
|
+
<th width="75%">Sitemap</th>
|
|
856
|
+
<th width="25%" title="Last Modification Time">Updated At</th>
|
|
857
|
+
</tr>
|
|
858
|
+
</thead>
|
|
859
|
+
<tbody>
|
|
860
|
+
<xsl:for-each select="sitemap:sitemapindex/sitemap:sitemap">
|
|
861
|
+
<xsl:variable name="sitemapURL">
|
|
862
|
+
<xsl:value-of select="sitemap:loc"/>
|
|
863
|
+
</xsl:variable>
|
|
864
|
+
<tr>
|
|
865
|
+
<td>
|
|
866
|
+
<a href="{$sitemapURL}"><xsl:value-of select="sitemap:loc"/></a>
|
|
867
|
+
</td>
|
|
868
|
+
<td>
|
|
869
|
+
<xsl:value-of select="concat(substring(sitemap:lastmod,0,11),concat(' ', substring(sitemap:lastmod,12,5)),concat(' ', substring(sitemap:lastmod,20,6)))"/>
|
|
870
|
+
</td>
|
|
871
|
+
</tr>
|
|
872
|
+
</xsl:for-each>
|
|
873
|
+
</tbody>
|
|
874
|
+
</table>
|
|
875
|
+
</xsl:if>
|
|
876
|
+
<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) < 1">
|
|
877
|
+
<p class="wysiwyg">
|
|
878
|
+
This sitemap contains <xsl:value-of select="count(sitemap:urlset/sitemap:url)"/> URLs.
|
|
879
|
+
</p>
|
|
880
|
+
<table id="sitemap" cellpadding="3">
|
|
881
|
+
<thead>
|
|
882
|
+
<tr>
|
|
883
|
+
<th width="75%">URL</th>
|
|
884
|
+
<th width="15%" title="Last Modification Time">Updated At</th>
|
|
885
|
+
<th width="10%">Images</th>
|
|
886
|
+
</tr>
|
|
887
|
+
</thead>
|
|
888
|
+
<tbody>
|
|
889
|
+
<xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/>
|
|
890
|
+
<xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
|
|
891
|
+
<xsl:for-each select="sitemap:urlset/sitemap:url">
|
|
892
|
+
<tr>
|
|
893
|
+
<td>
|
|
894
|
+
<xsl:variable name="itemURL">
|
|
895
|
+
<xsl:value-of select="sitemap:loc"/>
|
|
896
|
+
</xsl:variable>
|
|
897
|
+
<a href="{$itemURL}">
|
|
898
|
+
<xsl:value-of select="sitemap:loc"/>
|
|
899
|
+
</a>
|
|
900
|
+
</td>
|
|
901
|
+
<td>
|
|
902
|
+
<xsl:value-of select="concat(substring(sitemap:lastmod,0,11),concat(' ', substring(sitemap:lastmod,12,5)),concat(' ', substring(sitemap:lastmod,20,6)))"/>
|
|
903
|
+
</td>
|
|
904
|
+
<td>
|
|
905
|
+
<xsl:value-of select="count(image:image)"/>
|
|
906
|
+
</td>
|
|
907
|
+
</tr>
|
|
908
|
+
</xsl:for-each>
|
|
909
|
+
</tbody>
|
|
910
|
+
</table>
|
|
911
|
+
</xsl:if>
|
|
912
|
+
</div>
|
|
913
|
+
</body>
|
|
914
|
+
</html>
|
|
915
|
+
</xsl:template>
|
|
916
|
+
</xsl:stylesheet>`;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
//#endregion
|
|
920
|
+
//#region src/sitemap/sitemap.handler.ts
|
|
921
|
+
const getSiteMapIndexProps = async (context) => {
|
|
922
|
+
const { req, res } = context;
|
|
923
|
+
const sitemap = await getSiteMapIndex(getOrigin(req.headers));
|
|
924
|
+
res.setHeader("Content-Type", "application/xml; charset=UTF-8");
|
|
925
|
+
res.setHeader("X-Frame-Options", "SAMEORIGIN");
|
|
926
|
+
res.setHeader("X-Robots-Tag", "noindex, follow");
|
|
927
|
+
res.write(sitemap);
|
|
928
|
+
res.end();
|
|
929
|
+
return { props: {} };
|
|
930
|
+
};
|
|
931
|
+
const getSiteMapXMLProps = async (context) => {
|
|
932
|
+
const { req, res } = context;
|
|
933
|
+
const params = context.params;
|
|
934
|
+
const market = params?.market;
|
|
935
|
+
const locale = params?.locale;
|
|
936
|
+
const sitemap = await getSiteMapXML(getOrigin(req.headers), market, locale);
|
|
937
|
+
res.setHeader("Content-Type", "application/xml; charset=UTF-8");
|
|
938
|
+
res.setHeader("X-Frame-Options", "SAMEORIGIN");
|
|
939
|
+
res.setHeader("X-Robots-Tag", "noindex, follow");
|
|
940
|
+
res.write(sitemap);
|
|
941
|
+
res.end();
|
|
942
|
+
return { props: {} };
|
|
943
|
+
};
|
|
944
|
+
const getSiteMapXSLProps = async (context) => {
|
|
945
|
+
const { req, res } = context;
|
|
946
|
+
const params = context.params;
|
|
947
|
+
params?.market;
|
|
948
|
+
const locale = params?.locale;
|
|
949
|
+
const sitemap = await getSiteMapXSL(locale);
|
|
950
|
+
res.setHeader("Content-Type", "application/xml; charset=UTF-8");
|
|
951
|
+
res.setHeader("X-Frame-Options", "SAMEORIGIN");
|
|
952
|
+
res.setHeader("X-Robots-Tag", "noindex, follow");
|
|
953
|
+
res.write(sitemap);
|
|
954
|
+
res.end();
|
|
955
|
+
return { props: {} };
|
|
956
|
+
};
|
|
957
|
+
|
|
958
|
+
//#endregion
|
|
959
|
+
export { LAZY_PROPS, NotFound, escapeHtml, findManyPages, findOnePage, getAddressOptions, getApp, getBreadcrumbFromSegments, getCaptionsVttProps, getCategories, getCategory, getConsentPreference, getConsentPreferences, getConsentPreferencesPagination, getCountries, getCountriesPagination, getCountry, getDecoratedComponents, getErrorPageLayout, getLabel, getLabels, getLayout, getLocale, getLocales, getMarket, getMarkets, getMenu, getMenus, getNotFoundRoute, getPage, getPageCategory, getPageProps, getPageRoutes, getProvince, getProvinces, getProvincesPagination, getPublicUrl, getRedirect, getRedirects, getRedirectsPagination, getRegion, getRegions, getRegionsPagination, getRoute, getRouteLinkCategory, getRouteLinkTree, getRoutes, getRoutesForSchemas, getRoutesForTemplates, getSchemaRoutes, getSegments, getSession, getSessionToken, getSiteMapIndex, getSiteMapIndexProps, getSiteMapXML, getSiteMapXMLProps, getSiteMapXSL, getSiteMapXSLProps, getStaticPathsForSchema, getStaticPathsForSchemaAndFallback, redirectTo, resolveHref, resolveLabel, routeRevalidateHandler, withLazyProps };
|
|
960
|
+
//# sourceMappingURL=server.js.map
|