Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 1x 76x 76x 76x 76x 1x 25x 1x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 4x 4x 4x 5x 4x 4x 4x 4x 4x 4x 4x 4x 2x 2x 4x 4x 5x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 5x 1x 1x 5x 5x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import type {Category, Product, Universe} from '~/types/shop'
type LlmSiteContent = {
seoSiteName?: string
seoDescription?: string
seoOrganizationName?: string
seoOrganizationEmail?: string
seoLanguage?: string
}
const clean = (value: unknown) => String(value ?? '')
.replace(/[\r\n\t]+/g, ' ')
.replace(/\s{2,}/g, ' ')
.replace(/[\[\]]/g, '')
.trim()
const link = (label: unknown, url: string, description?: unknown) =>
`- [${clean(label)}](${url})${clean(description) ? `: ${clean(description)}` : ''}`
export function formatLlmsDocument(input: {
origin: string
content: LlmSiteContent
products: Product[]
categories: Category[]
universes: Universe[]
}) {
const {origin, content, products, categories, universes} = input
const siteName = clean(content.seoSiteName || content.seoOrganizationName || 'Boutique en ligne')
const lines = [
`# ${siteName}`,
'',
`> ${clean(content.seoDescription || 'Boutique en ligne de produits physiques.')}`,
'',
`Langue principale : ${clean(content.seoLanguage || 'fr')}.`,
'Les produits présentés sont des articles physiques vendus en ligne.',
'',
'## Pages principales',
'',
link('Accueil', `${origin}/`, content.seoDescription),
link('Plan du site XML', `${origin}/sitemap.xml`)
]
if (categories.length) {
lines.push('', '## Catégories', '')
for (const category of categories) lines.push(link(category.label, `${origin}/categories/${encodeURIComponent(category.slug)}`))
}
if (universes.length) {
lines.push('', '## Univers', '')
for (const universe of universes) {
const universeKey = encodeURIComponent(universe.slug || String(universe.id))
lines.push(link(universe.title, `${origin}/univers/${universeKey}`))
const categoryIds = new Set(products
.filter(product => product.universeIds.includes(universe.id))
.flatMap(product => product.categoryIds))
for (const category of categories.filter(item => categoryIds.has(item.id))) {
lines.push(` ${link(`${universe.title} — ${category.label}`, `${origin}/univers/${universeKey}/${encodeURIComponent(category.slug)}`)}`)
}
}
}
if (products.length) {
lines.push('', '## Produits', '')
for (const product of products) {
const price = `${(product.priceCents / 100).toFixed(2).replace('.', ',')} €`
const context = [product.description, `Prix : ${price}`,
product.categories.length ? `Catégories : ${product.categories.map(item => item.label).join(', ')}` : '',
product.universes.length ? `Univers : ${product.universes.map(item => item.title).join(', ')}` : '']
.filter(Boolean).join(' — ')
lines.push(link(product.name, `${origin}/produits/${encodeURIComponent(product.slug)}`, context))
}
}
if (clean(content.seoOrganizationEmail)) {
lines.push('', '## Contact', '', `- Email : ${clean(content.seoOrganizationEmail)}`)
}
return `${lines.join('\n')}\n`
}
export async function buildLlmsDocument(event: any) {
const db = database(event)
await ready(db)
const {results: contentRows} = await db.prepare("SELECT `key`,value FROM site_content WHERE `key` IN ('seoSiteName','seoDescription','seoOrganizationName','seoOrganizationEmail','seoLanguage','seoCanonicalUrl')").all<any>()
const content = Object.fromEntries(contentRows.map(row => [row.key, row.value])) as LlmSiteContent & {
seoCanonicalUrl?: string
}
const origin = String(content.seoCanonicalUrl || useRuntimeConfig(event).public.siteUrl || getRequestURL(event).origin).replace(/\/$/, '')
const {results: productRows} = await db.prepare(`${productSelect} WHERE p.active=1 ORDER BY p.featured DESC,p.featured_position,p.id`).all<any>()
const products = await mapProductsWithRelations(db, productRows)
const {results: categoryRows} = await db.prepare('SELECT * FROM categories WHERE active=1 ORDER BY position,id').all<any>()
const {results: universeRows} = await db.prepare(`${universeSelect} WHERE u.active=1 ORDER BY u.position,u.id`).all<any>()
return formatLlmsDocument({
origin,
content,
products,
categories: categoryRows.map(mapCategory),
universes: universeRows.map(mapUniverse)
})
}
|