@lastbrain/app 2.0.31 → 2.0.35
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/dist/analytics/registry.d.ts +7 -0
- package/dist/analytics/registry.d.ts.map +1 -0
- package/dist/analytics/registry.js +11 -0
- package/dist/auth/useAuthSession.d.ts.map +1 -1
- package/dist/auth/useAuthSession.js +85 -1
- package/dist/cli.js +19 -3
- package/dist/components/LanguageSwitcher.d.ts.map +1 -1
- package/dist/components/LanguageSwitcher.js +89 -5
- package/dist/config/version.d.ts.map +1 -1
- package/dist/config/version.js +30 -19
- package/dist/i18n/useLink.d.ts.map +1 -1
- package/dist/i18n/useLink.js +15 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/layouts/AdminLayoutWithSidebar.d.ts +3 -1
- package/dist/layouts/AdminLayoutWithSidebar.d.ts.map +1 -1
- package/dist/layouts/AdminLayoutWithSidebar.js +2 -2
- package/dist/layouts/AppProviders.d.ts +7 -1
- package/dist/layouts/AppProviders.d.ts.map +1 -1
- package/dist/layouts/AppProviders.js +24 -3
- package/dist/layouts/AuthLayout.js +1 -1
- package/dist/layouts/PublicLayout.js +1 -1
- package/dist/layouts/RootLayout.d.ts.map +1 -1
- package/dist/scripts/init-app.d.ts.map +1 -1
- package/dist/scripts/init-app.js +301 -138
- package/dist/scripts/module-build.d.ts.map +1 -1
- package/dist/scripts/module-build.js +402 -67
- package/dist/scripts/module-create.d.ts.map +1 -1
- package/dist/scripts/module-create.js +227 -10
- package/dist/scripts/sitemap-flat-generator.d.ts +39 -0
- package/dist/scripts/sitemap-flat-generator.d.ts.map +1 -0
- package/dist/scripts/sitemap-flat-generator.js +231 -0
- package/dist/scripts/sitemap-manifest-generator.d.ts +59 -0
- package/dist/scripts/sitemap-manifest-generator.d.ts.map +1 -0
- package/dist/scripts/sitemap-manifest-generator.js +290 -0
- package/dist/sitemap/manifest.d.ts +8 -0
- package/dist/sitemap/manifest.d.ts.map +1 -0
- package/dist/sitemap/manifest.js +6 -0
- package/dist/styles.css +2 -2
- package/dist/templates/AuthGuidePage.js +2 -0
- package/dist/templates/DefaultDoc.d.ts.map +1 -1
- package/dist/templates/DefaultDoc.js +9 -5
- package/dist/templates/DocPage.d.ts.map +1 -1
- package/dist/templates/DocPage.js +40 -0
- package/dist/templates/MigrationsGuidePage.js +2 -0
- package/dist/templates/ModuleGuidePage.d.ts.map +1 -1
- package/dist/templates/ModuleGuidePage.js +4 -1
- package/dist/templates/SimpleHomePage.js +2 -0
- package/package.json +11 -4
- package/src/analytics/registry.ts +14 -0
- package/src/auth/useAuthSession.ts +91 -1
- package/src/cli.ts +19 -3
- package/src/components/LanguageSwitcher.tsx +113 -23
- package/src/config/version.ts +30 -19
- package/src/i18n/useLink.ts +15 -0
- package/src/index.ts +17 -0
- package/src/layouts/AdminLayoutWithSidebar.tsx +4 -0
- package/src/layouts/AppProviders.tsx +66 -8
- package/src/layouts/AuthLayout.tsx +1 -1
- package/src/layouts/PublicLayout.tsx +1 -1
- package/src/layouts/RootLayout.tsx +0 -1
- package/src/scripts/init-app.ts +360 -149
- package/src/scripts/module-build.ts +458 -72
- package/src/scripts/module-create.ts +260 -10
- package/src/scripts/sitemap-flat-generator.ts +313 -0
- package/src/scripts/sitemap-manifest-generator.ts +476 -0
- package/src/sitemap/manifest.ts +17 -0
- package/src/templates/AuthGuidePage.tsx +1 -1
- package/src/templates/DefaultDoc.tsx +397 -6
- package/src/templates/DocPage.tsx +40 -0
- package/src/templates/MigrationsGuidePage.tsx +1 -1
- package/src/templates/ModuleGuidePage.tsx +3 -2
- package/src/templates/SimpleHomePage.tsx +1 -1
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nouveau système de sitemaps basé sur les manifests
|
|
3
|
+
* Architecture PLATE (pas d'imbrication) : index global -> sitemaps enfants (urlset)
|
|
4
|
+
* Conforme Google Search Console : pas d'index imbriqués
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import type { ModuleBuildConfig } from "../index.js";
|
|
10
|
+
import {
|
|
11
|
+
collectAllContentSitemaps,
|
|
12
|
+
generateFlatGlobalSitemapIndex,
|
|
13
|
+
validateNoNestedIndexes,
|
|
14
|
+
} from "./sitemap-flat-generator.js";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Charge les paths ignorés depuis menu-ignored.ts de l'app
|
|
18
|
+
*/
|
|
19
|
+
function loadMenuIgnoredPaths(appDirectory: string): string[] {
|
|
20
|
+
try {
|
|
21
|
+
const menuIgnoredPath = path.join(
|
|
22
|
+
appDirectory,
|
|
23
|
+
"..",
|
|
24
|
+
"config",
|
|
25
|
+
"menu-ignored.ts"
|
|
26
|
+
);
|
|
27
|
+
if (!fs.existsSync(menuIgnoredPath)) {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const content = fs.readFileSync(menuIgnoredPath, "utf-8");
|
|
32
|
+
const ignoredPaths: string[] = [];
|
|
33
|
+
|
|
34
|
+
// Parser simple pour extraire les paths du fichier
|
|
35
|
+
const pathMatches = content.matchAll(/path:\s*["']([^"']+)["']/g);
|
|
36
|
+
for (const match of pathMatches) {
|
|
37
|
+
ignoredPaths.push(match[1]);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return ignoredPaths;
|
|
41
|
+
} catch (error) {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Types dupliqués depuis les modules (pour éviter dépendances circulaires)
|
|
47
|
+
type SitemapChildKind = "static" | "reexport";
|
|
48
|
+
|
|
49
|
+
interface SitemapChild {
|
|
50
|
+
id: string;
|
|
51
|
+
path: string;
|
|
52
|
+
kind: SitemapChildKind;
|
|
53
|
+
handler?: string;
|
|
54
|
+
paging?: {
|
|
55
|
+
pageSize: number;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface SitemapManifest {
|
|
60
|
+
module: string;
|
|
61
|
+
enabled: boolean;
|
|
62
|
+
includePublicPagesFromBuildConfig: boolean;
|
|
63
|
+
children: SitemapChild[];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Charge le manifest sitemap d'un module (si existe)
|
|
68
|
+
*/
|
|
69
|
+
export async function loadModuleManifest(
|
|
70
|
+
moduleConfig: ModuleBuildConfig,
|
|
71
|
+
projectRequire: NodeRequire,
|
|
72
|
+
isDebugMode: boolean
|
|
73
|
+
): Promise<SitemapManifest | null> {
|
|
74
|
+
try {
|
|
75
|
+
const manifestPath = `${moduleConfig.moduleName}/sitemap/manifest`;
|
|
76
|
+
|
|
77
|
+
if (isDebugMode) {
|
|
78
|
+
console.log(` Trying to load manifest from: ${manifestPath}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Utiliser require synchrone plutôt que import dynamique
|
|
82
|
+
const manifestModule = projectRequire(manifestPath);
|
|
83
|
+
const manifest = manifestModule.sitemapManifest;
|
|
84
|
+
|
|
85
|
+
if (manifest && isDebugMode) {
|
|
86
|
+
console.log(` ✅ Loaded manifest for module: ${manifest.module}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return manifest || null;
|
|
90
|
+
} catch (error) {
|
|
91
|
+
if (isDebugMode) {
|
|
92
|
+
console.log(
|
|
93
|
+
` ⏭️ No manifest found for ${moduleConfig.moduleName}:`,
|
|
94
|
+
error
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Génère le sitemap.xml racine PLAT - liste directement tous les sitemaps de contenu
|
|
103
|
+
* SUPPRIME les index intermédiaires de modules (pas d'imbrication)
|
|
104
|
+
*/
|
|
105
|
+
export function generateGlobalSitemapIndex(
|
|
106
|
+
appDirectory: string,
|
|
107
|
+
moduleManifests: Array<{
|
|
108
|
+
config: ModuleBuildConfig;
|
|
109
|
+
manifest: SitemapManifest;
|
|
110
|
+
}>,
|
|
111
|
+
languages: string[],
|
|
112
|
+
isDebugMode: boolean
|
|
113
|
+
) {
|
|
114
|
+
// Collecter tous les sitemaps de contenu (urlset) directement
|
|
115
|
+
const entries = collectAllContentSitemaps(
|
|
116
|
+
moduleManifests,
|
|
117
|
+
languages,
|
|
118
|
+
appDirectory
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
if (isDebugMode) {
|
|
122
|
+
console.log(`\n📋 Collected ${entries.length} sitemap entries:`);
|
|
123
|
+
entries
|
|
124
|
+
.slice(0, 5)
|
|
125
|
+
.forEach((e) =>
|
|
126
|
+
console.log(` - ${e.path} (module: ${e.module}, kind: ${e.kind})`)
|
|
127
|
+
);
|
|
128
|
+
if (entries.length > 5) {
|
|
129
|
+
console.log(` ... and ${entries.length - 5} more`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Générer le sitemap.xml racine plat
|
|
134
|
+
generateFlatGlobalSitemapIndex(appDirectory, entries, isDebugMode);
|
|
135
|
+
|
|
136
|
+
// Valider qu'il n'y a pas d'imbrication
|
|
137
|
+
const validation = validateNoNestedIndexes(
|
|
138
|
+
appDirectory,
|
|
139
|
+
entries,
|
|
140
|
+
isDebugMode
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
if (!validation.valid) {
|
|
144
|
+
console.error("\n❌ SITEMAP VALIDATION FAILED:");
|
|
145
|
+
validation.errors.forEach((err) => console.error(err));
|
|
146
|
+
throw new Error("Sitemap validation failed: nested indexes detected");
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (isDebugMode) {
|
|
150
|
+
console.log(`✅ Sitemap validation passed: no nested indexes`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* SUPPRIMÉE - Les index de modules créent une imbrication non conforme
|
|
156
|
+
* Les sitemaps de contenu sont maintenant listés directement dans /sitemap.xml
|
|
157
|
+
*
|
|
158
|
+
* Ancienne fonction : generateModuleSitemapIndex()
|
|
159
|
+
* Raison suppression : Google Search Console refuse les index imbriqués
|
|
160
|
+
*/
|
|
161
|
+
// export function generateModuleSitemapIndex() { ... } // DEPRECATED
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Génère un sitemap enfant statique (pages build.config)
|
|
165
|
+
*/
|
|
166
|
+
export function generateStaticSitemap(
|
|
167
|
+
appDirectory: string,
|
|
168
|
+
moduleConfig: ModuleBuildConfig,
|
|
169
|
+
manifest: SitemapManifest,
|
|
170
|
+
child: any,
|
|
171
|
+
lang: string,
|
|
172
|
+
isDebugMode: boolean
|
|
173
|
+
) {
|
|
174
|
+
const childPath = child.path.replace(":lang", lang);
|
|
175
|
+
|
|
176
|
+
// Retirer l'extension .xml du path pour créer un dossier
|
|
177
|
+
const pathWithoutExt = childPath.replace(/\.xml$/, ".xml");
|
|
178
|
+
const pathSegments = pathWithoutExt.split("/").filter(Boolean);
|
|
179
|
+
|
|
180
|
+
const targetDir = path.join(
|
|
181
|
+
appDirectory,
|
|
182
|
+
"sitemap",
|
|
183
|
+
manifest.module,
|
|
184
|
+
...pathSegments
|
|
185
|
+
);
|
|
186
|
+
const targetFile = path.join(targetDir, "route.ts");
|
|
187
|
+
|
|
188
|
+
if (!fs.existsSync(targetDir)) {
|
|
189
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Collecter UNIQUEMENT les pages statiques (sans patterns dynamiques [])
|
|
193
|
+
// Si le manifest spécifie includePublicPagesFromBuildConfig = false, ne pas inclure les pages
|
|
194
|
+
let publicPages: any[] = [];
|
|
195
|
+
|
|
196
|
+
if (manifest.includePublicPagesFromBuildConfig !== false) {
|
|
197
|
+
publicPages = (moduleConfig.pages || [])
|
|
198
|
+
.filter((p) => p.section === "public")
|
|
199
|
+
.filter((p) => !p.path.includes("[") && !p.path.includes("]"));
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Charger et exclure les pages dans menu-ignored.ts
|
|
203
|
+
const ignoredPaths = loadMenuIgnoredPaths(appDirectory);
|
|
204
|
+
if (ignoredPaths.length > 0) {
|
|
205
|
+
publicPages = publicPages.filter((p) => {
|
|
206
|
+
// p.path peut être "/blog" ou "/shop"
|
|
207
|
+
// ignoredPaths contient ["/shop", "/prompts", ...]
|
|
208
|
+
// On doit vérifier si p.path match exactement
|
|
209
|
+
return !ignoredPaths.some((ignoredPath) => {
|
|
210
|
+
// Normaliser les chemins (retirer les slashes finaux, etc.)
|
|
211
|
+
const normalizedPagePath = p.path.replace(/\/$/, "");
|
|
212
|
+
const normalizedIgnoredPath = ignoredPath.replace(/\/$/, "");
|
|
213
|
+
return normalizedPagePath === normalizedIgnoredPath;
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const content = `// GENERATED BY LASTBRAIN MODULE BUILD - Static Pages Sitemap
|
|
219
|
+
// Module: ${manifest.module}
|
|
220
|
+
// Lang: ${lang}
|
|
221
|
+
|
|
222
|
+
export async function GET(): Promise<Response> {
|
|
223
|
+
const baseUrl =
|
|
224
|
+
process.env.NEXT_PUBLIC_SITE_URL ||
|
|
225
|
+
(process.env.VERCEL_URL ? \`https://\${process.env.VERCEL_URL}\` : "https://example.com");
|
|
226
|
+
|
|
227
|
+
const pages: string[] = ${JSON.stringify(publicPages.map((p) => `/${lang}${p.path}`))};
|
|
228
|
+
|
|
229
|
+
const xml = \`<?xml version="1.0" encoding="UTF-8"?>
|
|
230
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
231
|
+
\${pages.map((page: string) => \` <url>
|
|
232
|
+
<loc>\${baseUrl}\${page}</loc>
|
|
233
|
+
<lastmod>\${new Date().toISOString()}</lastmod>
|
|
234
|
+
<changefreq>weekly</changefreq>
|
|
235
|
+
<priority>0.8</priority>
|
|
236
|
+
</url>\`).join("\\n")}
|
|
237
|
+
</urlset>\`;
|
|
238
|
+
|
|
239
|
+
return new Response(xml, {
|
|
240
|
+
headers: {
|
|
241
|
+
"Content-Type": "application/xml",
|
|
242
|
+
"Cache-Control": "public, max-age=3600, s-maxage=3600",
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
`;
|
|
247
|
+
|
|
248
|
+
fs.writeFileSync(targetFile, content);
|
|
249
|
+
|
|
250
|
+
if (isDebugMode) {
|
|
251
|
+
console.log(
|
|
252
|
+
`📄 Generated static sitemap: ${targetFile} (${publicPages.length} pages)`
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Génère un sitemap enfant dynamique (reexport handler)
|
|
259
|
+
*/
|
|
260
|
+
export function generateReexportSitemap(
|
|
261
|
+
appDirectory: string,
|
|
262
|
+
manifest: SitemapManifest,
|
|
263
|
+
child: any,
|
|
264
|
+
lang: string,
|
|
265
|
+
type?: string,
|
|
266
|
+
isDebugMode?: boolean
|
|
267
|
+
) {
|
|
268
|
+
let childPath = child.path.replace(":lang", lang);
|
|
269
|
+
if (type) {
|
|
270
|
+
childPath = childPath.replace(":type", type);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const segments = childPath.split("/").filter(Boolean);
|
|
274
|
+
const targetDir = path.join(
|
|
275
|
+
appDirectory,
|
|
276
|
+
"sitemap",
|
|
277
|
+
manifest.module,
|
|
278
|
+
...segments.slice(0, -1)
|
|
279
|
+
);
|
|
280
|
+
const fileName = segments[segments.length - 1];
|
|
281
|
+
const targetFile = path.join(targetDir, fileName, "route.ts");
|
|
282
|
+
|
|
283
|
+
if (!fs.existsSync(path.dirname(targetFile))) {
|
|
284
|
+
fs.mkdirSync(path.dirname(targetFile), { recursive: true });
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Créer un wrapper qui passe les params au handler
|
|
288
|
+
const paramsObject: Record<string, string> = { lang };
|
|
289
|
+
if (type) {
|
|
290
|
+
paramsObject.type = type;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const content = `// GENERATED BY LASTBRAIN MODULE BUILD - Reexport Sitemap
|
|
294
|
+
// Module: ${manifest.module}
|
|
295
|
+
// Handler: ${child.handler}
|
|
296
|
+
// Params: ${JSON.stringify(paramsObject)}
|
|
297
|
+
|
|
298
|
+
import { GET as handler } from "${child.handler}";
|
|
299
|
+
|
|
300
|
+
export async function GET(request: Request): Promise<Response> {
|
|
301
|
+
// Wrapper pour passer les params au handler
|
|
302
|
+
const context = {
|
|
303
|
+
params: Promise.resolve(${JSON.stringify(paramsObject)})
|
|
304
|
+
};
|
|
305
|
+
return handler(request, context);
|
|
306
|
+
}
|
|
307
|
+
`;
|
|
308
|
+
|
|
309
|
+
fs.writeFileSync(targetFile, content);
|
|
310
|
+
|
|
311
|
+
if (isDebugMode) {
|
|
312
|
+
console.log(`🔗 Generated reexport sitemap: ${targetFile}`);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Génère tous les sitemaps pour un module
|
|
318
|
+
*/
|
|
319
|
+
export async function generateModuleSitemaps(
|
|
320
|
+
appDirectory: string,
|
|
321
|
+
moduleConfig: ModuleBuildConfig,
|
|
322
|
+
manifest: SitemapManifest,
|
|
323
|
+
languages: string[],
|
|
324
|
+
isDebugMode: boolean
|
|
325
|
+
) {
|
|
326
|
+
// NE PLUS GÉNÉRER D'INDEX INTERMÉDIAIRE
|
|
327
|
+
// Ancien code : generateModuleSitemapIndex() - SUPPRIMÉ pour éviter l'imbrication
|
|
328
|
+
// Le sitemap global /sitemap.xml liste maintenant directement tous les sitemaps enfants
|
|
329
|
+
|
|
330
|
+
// Générer chaque sitemap enfant (sitemaps de contenu = urlset)
|
|
331
|
+
for (const child of manifest.children) {
|
|
332
|
+
if (child.kind === "static") {
|
|
333
|
+
// Générer static.xml pour chaque langue
|
|
334
|
+
for (const lang of languages) {
|
|
335
|
+
generateStaticSitemap(
|
|
336
|
+
appDirectory,
|
|
337
|
+
moduleConfig,
|
|
338
|
+
manifest,
|
|
339
|
+
child,
|
|
340
|
+
lang,
|
|
341
|
+
isDebugMode
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
} else if (child.kind === "reexport") {
|
|
345
|
+
// Générer les reexports selon le pattern du path
|
|
346
|
+
if (child.path.includes(":lang") && child.path.includes(":type")) {
|
|
347
|
+
// Ancien système avec :type (déprécié) - Blog: par type et langue
|
|
348
|
+
const contentTypes = ["blog", "tutorial", "faq", "help", "docs"];
|
|
349
|
+
for (const lang of languages) {
|
|
350
|
+
for (const type of contentTypes) {
|
|
351
|
+
generateReexportSitemap(
|
|
352
|
+
appDirectory,
|
|
353
|
+
manifest,
|
|
354
|
+
child,
|
|
355
|
+
lang,
|
|
356
|
+
type,
|
|
357
|
+
isDebugMode
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
} else if (child.path.includes(":lang")) {
|
|
362
|
+
// Path avec :lang uniquement
|
|
363
|
+
// Peut contenir un type fixe dans le path comme :lang/blog/categories.xml
|
|
364
|
+
for (const lang of languages) {
|
|
365
|
+
// Extraire le type du path si présent
|
|
366
|
+
const pathSegments = child.path.split("/").filter(Boolean);
|
|
367
|
+
let extractedType: string | undefined;
|
|
368
|
+
|
|
369
|
+
// Si le path est comme :lang/blog/categories.xml, extraire "blog"
|
|
370
|
+
if (pathSegments.length >= 2 && pathSegments[0] === ":lang") {
|
|
371
|
+
const potentialType = pathSegments[1];
|
|
372
|
+
// Vérifier si c'est un type de contenu connu
|
|
373
|
+
const contentTypes = ["blog", "tutorial", "faq", "help", "docs"];
|
|
374
|
+
if (contentTypes.includes(potentialType)) {
|
|
375
|
+
extractedType = potentialType;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
generateReexportSitemap(
|
|
380
|
+
appDirectory,
|
|
381
|
+
manifest,
|
|
382
|
+
child,
|
|
383
|
+
lang,
|
|
384
|
+
extractedType,
|
|
385
|
+
isDebugMode
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
} else {
|
|
389
|
+
// Path statique sans params
|
|
390
|
+
generateReexportSitemap(
|
|
391
|
+
appDirectory,
|
|
392
|
+
manifest,
|
|
393
|
+
child,
|
|
394
|
+
"",
|
|
395
|
+
undefined,
|
|
396
|
+
isDebugMode
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Point d'entrée principal du nouveau système de sitemaps
|
|
405
|
+
*/
|
|
406
|
+
export async function generateManifestBasedSitemaps(
|
|
407
|
+
appDirectory: string,
|
|
408
|
+
moduleConfigs: ModuleBuildConfig[],
|
|
409
|
+
languages: string[],
|
|
410
|
+
projectRequire: NodeRequire,
|
|
411
|
+
isDebugMode: boolean
|
|
412
|
+
) {
|
|
413
|
+
const moduleManifests: Array<{
|
|
414
|
+
config: ModuleBuildConfig;
|
|
415
|
+
manifest: SitemapManifest;
|
|
416
|
+
}> = [];
|
|
417
|
+
|
|
418
|
+
if (isDebugMode) {
|
|
419
|
+
console.log(
|
|
420
|
+
`🔍 Checking ${moduleConfigs.length} module(s) for sitemap manifests...`
|
|
421
|
+
);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Charger les manifests de tous les modules
|
|
425
|
+
for (const config of moduleConfigs) {
|
|
426
|
+
const manifest = await loadModuleManifest(
|
|
427
|
+
config,
|
|
428
|
+
projectRequire,
|
|
429
|
+
isDebugMode
|
|
430
|
+
);
|
|
431
|
+
if (manifest && manifest.enabled) {
|
|
432
|
+
moduleManifests.push({ config, manifest });
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (moduleManifests.length === 0) {
|
|
437
|
+
if (isDebugMode) {
|
|
438
|
+
console.log(
|
|
439
|
+
"⏭️ No sitemap manifests found, skipping manifest-based generation"
|
|
440
|
+
);
|
|
441
|
+
}
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
if (isDebugMode) {
|
|
446
|
+
console.log(
|
|
447
|
+
`🗺️ Found ${moduleManifests.length} module(s) with sitemap manifests`
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Générer l'index global PLAT (liste directement tous les sitemaps de contenu)
|
|
452
|
+
generateGlobalSitemapIndex(
|
|
453
|
+
appDirectory,
|
|
454
|
+
moduleManifests,
|
|
455
|
+
languages,
|
|
456
|
+
isDebugMode
|
|
457
|
+
);
|
|
458
|
+
|
|
459
|
+
// Générer les sitemaps de chaque module
|
|
460
|
+
for (const { config, manifest } of moduleManifests) {
|
|
461
|
+
if (isDebugMode) {
|
|
462
|
+
console.log(`📦 Generating sitemaps for module: ${manifest.module}`);
|
|
463
|
+
}
|
|
464
|
+
await generateModuleSitemaps(
|
|
465
|
+
appDirectory,
|
|
466
|
+
config,
|
|
467
|
+
manifest,
|
|
468
|
+
languages,
|
|
469
|
+
isDebugMode
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
if (isDebugMode) {
|
|
474
|
+
console.log("✅ Manifest-based sitemaps generated successfully");
|
|
475
|
+
}
|
|
476
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest des sitemaps du package app
|
|
3
|
+
* Package désactivé (pas un module avec pages publiques)
|
|
4
|
+
*/
|
|
5
|
+
import type {
|
|
6
|
+
SitemapManifest,
|
|
7
|
+
SitemapChild,
|
|
8
|
+
SitemapChildKind,
|
|
9
|
+
} from "@lastbrain/core";
|
|
10
|
+
|
|
11
|
+
export type { SitemapManifest, SitemapChild, SitemapChildKind };
|
|
12
|
+
export const sitemapManifest: SitemapManifest = {
|
|
13
|
+
module: "app",
|
|
14
|
+
enabled: false,
|
|
15
|
+
includePublicPagesFromBuildConfig: false,
|
|
16
|
+
children: [],
|
|
17
|
+
} as const;
|