Helpers
Manifest validation
Funzioni validateManifest e isValidManifest per validare a runtime payload non trusted come MFEManifest.
API
function validateManifest(manifest: unknown): {
valid: boolean
errors: string[]
}
function isValidManifest(manifest: unknown): manifest is MFEManifest
Quando usarle
Quando il manifest arriva da fonti non controllate (config remota, admin panel, JSON di API esterne, file caricato da utente). Il TypeScript da solo non protegge a runtime: un payload unknown deve essere validato prima di essere usato.
validateManifest
Ritorna { valid, errors } con dettagli di validazione. Adatto per mostrare errori all'utente o loggarli.
import { validateManifest } from '@pzeta/mfe-contracts/helpers'
const payload: unknown = JSON.parse(rawJson)
const { valid, errors } = validateManifest(payload)
if (!valid) {
console.error('Manifest non valido:')
errors.forEach((e) => console.error(' -', e))
return
}
// Sicuro da usare (ma typecast esplicito)
const manifest = payload as MFEManifest
Cosa valida
| Check | Errore |
|---|---|
manifest non null/undefined e tipo object | 'manifest deve essere un oggetto non-null' |
name stringa non vuota | 'manifest.name è richiesto e deve essere una stringa non vuota' |
version stringa non vuota | 'manifest.version è richiesto e deve essere una stringa non vuota' |
description stringa non vuota | 'manifest.description è richiesto e deve essere una stringa non vuota' |
routes array | 'manifest.routes deve essere un array' |
Per ogni routes[i]: oggetto | 'route[i] deve essere un oggetto' |
routes[i].path stringa non vuota | 'route[i].path è richiesto e deve essere una stringa non vuota' |
routes[i].label stringa non vuota | 'route[i].label è richiesto e deve essere una stringa non vuota' |
Validazione shallow: campi
permissions, components, tailwindStyles, metanon sono validati in dettaglio. Se ti servono check più stringenti, aggiungi una validazione custom dopo validateManifest.isValidManifest (type guard)
Versione boolean adatta a if/assert:
import { isValidManifest } from '@pzeta/mfe-contracts/helpers'
if (isValidManifest(payload)) {
// payload è ora typed come MFEManifest, senza cast
console.log(payload.name, payload.version)
}
Internamente è un wrapper su validateManifest(payload).valid.
Esempio: fetch da config remota
import {
validateManifest,
isValidManifest,
} from '@pzeta/mfe-contracts/helpers'
async function fetchManifests(): Promise<MFEManifest[]> {
const res = await fetch('/api/mfe-registry')
const payloads = (await res.json()) as unknown[]
const valid: MFEManifest[] = []
for (const payload of payloads) {
const { valid: isValid, errors } = validateManifest(payload)
if (isValid) {
valid.push(payload as MFEManifest)
} else {
console.warn(
`Manifest scartato:\n ${errors.join('\n ')}`,
payload,
)
}
}
return valid
}
Esempio: errori user-friendly
function validateAndReport(payload: unknown): MFEManifest | null {
const { valid, errors } = validateManifest(payload)
if (!valid) {
toast.add({
severity: 'error',
summary: 'Manifest MFE non valido',
detail: errors.join('\n'),
life: 10000,
})
return null
}
return payload as MFEManifest
}
Pattern: validazione + sanitizzazione
validateManifest controlla la struttura ma non sanitizza il contenuto. Per CSS custom dichiarato in tailwindStyles.customClasses, usa anche sanitizeCss:
if (isValidManifest(payload)) {
if (payload.tailwindStyles?.customClasses) {
try {
sanitizeCss(payload.tailwindStyles.customClasses)
} catch (err) {
console.error('CSS custom non sicuro:', err.message)
delete payload.tailwindStyles.customClasses
}
}
// usa payload
}
Tipi correlati
MFEManifest— type ritornato daisValidManifestsanitizeCss— validazione complementare per CSS custom