Files
iti-technology/apps/public/scripts/content-index.mjs
T
Lorenzo SanesiandClaude Opus 5.5 b83ce039fb
Deploy stack su Proxmox / deploy (push) Failing after 3s
Piattaforma ITI TECHNOLOGY: monorepo, Medusa, API, sito, area riservata e deploy
Monorepo npm con apps/public (Angular SSR), apps/private (Angular SPA),
apps/api (Fastify), packages/shared e packages/styles; Medusa 2.21 in medusa/;
infrastruttura Docker (Postgres PostGIS+pgvector, Redis, Caddy, backup) e
workflow Gitea Actions per il deploy via SSH a ogni push su master.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018jQyT6dR9czzGwqb7FkG6u
2026-10-20 09:30:48 +02:00

86 lines
3.9 KiB
JavaScript

// Genera l'indice dei file di contenuto in src/content/generated/ (gli import li scrive lui, non a mano).
// Uso: node scripts/content-index.mjs → (ri)scrive l'indice
// node scripts/content-index.mjs --check → exit 1 se l'indice non è aggiornato (usato dai test)
// Parte da solo prima di dev, build, test e typecheck (script "pre*" in package.json).
import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
const root = join(dirname(fileURLToPath(import.meta.url)), '..', 'src', 'content')
const outDir = join(root, 'generated')
const check = process.argv.includes('--check')
const SLUG = /^[a-z0-9]+(-[a-z0-9]+)*$/
/** File .ts di una cartella (slug = nome senza estensione), ordinati. */
function slugsIn(dir) {
if (!existsSync(dir)) return []
return readdirSync(dir)
.filter((f) => f.endsWith('.ts') && !f.endsWith('.spec.ts'))
.map((f) => f.slice(0, -3))
.sort()
.map((slug) => {
if (!SLUG.test(slug)) throw new Error(`Nome file non valido: ${join(dir, slug)}.ts (solo a-z, 0-9 e "-")`)
return slug
})
}
const ident = (...parts) => parts.join('_').replace(/-/g, '_')
const areas = slugsIn(join(root, 'areas'))
const solutionsDir = join(root, 'solutions')
const solutionAreas = existsSync(solutionsDir)
? readdirSync(solutionsDir).filter((d) => statSync(join(solutionsDir, d)).isDirectory()).sort()
: []
const solutions = solutionAreas.flatMap((area) => {
if (!areas.includes(area)) throw new Error(`src/content/solutions/${area}/: non esiste la macro-area src/content/areas/${area}.ts`)
return slugsIn(join(solutionsDir, area)).map((slug) => ({ area, slug }))
})
const companyPages = slugsIn(join(root, 'company'))
const header = '// File generato da scripts/content-index.mjs: non modificare a mano.\n'
const files = {
'paths.ts':
header +
'// Solo slug (dai nomi dei file), senza importare i contenuti: per le route e la sitemap.\n\n' +
`export const AREA_SLUGS: readonly string[] = ${JSON.stringify(areas)}\n\n` +
`export const SOLUTION_PATHS: readonly { area: string; slug: string }[] = ${JSON.stringify(solutions)}\n\n` +
`export const COMPANY_PAGE_SLUGS: readonly string[] = ${JSON.stringify(companyPages)}\n`,
'areas.ts':
header +
"import type { AreaContent } from '../types'\n" +
areas.map((s) => `import ${ident('area', s)} from '../areas/${s}'\n`).join('') +
`\nexport const AREA_FILES: readonly AreaContent[] = [${areas.map((s) => ident('area', s)).join(', ')}]\n`,
'solutions.ts':
header +
"import type { SolutionContent } from '../types'\n" +
solutions.map(({ area, slug }) => `import ${ident('solution', area, slug)} from '../solutions/${area}/${slug}'\n`).join('') +
`\nexport const SOLUTION_FILES: readonly SolutionContent[] = [\n${solutions
.map(({ area, slug }) => ` ${ident('solution', area, slug)},\n`)
.join('')}]\n`,
'company.ts':
header +
"import type { CompanyPageContent } from '../types'\n" +
companyPages.map((s) => `import ${ident('company', s)} from '../company/${s}'\n`).join('') +
`\nexport const COMPANY_PAGE_FILES: readonly CompanyPageContent[] = [${companyPages.map((s) => ident('company', s)).join(', ')}]\n`,
}
let stale = []
if (!check) mkdirSync(outDir, { recursive: true })
for (const [name, content] of Object.entries(files)) {
const path = join(outDir, name)
const current = existsSync(path) ? readFileSync(path, 'utf8') : null
if (current === content) continue
if (check) stale.push(name)
else writeFileSync(path, content)
}
if (check && stale.length) {
console.error(`Indice dei contenuti non aggiornato (${stale.join(', ')}): esegui "npm run content -w apps/public"`)
process.exit(1)
}
console.log(
`Contenuti: ${areas.length} aree, ${solutions.length} soluzioni, ${companyPages.length} pagine azienda${check ? ' (indice aggiornato)' : ''}`,
)