Types

MFEComponent

Componente Vue riutilizzabile esposto dal MFE. Include MFEComponentProp e MFEComponentEvent per documentare props ed eventi.

MFEComponent

interface MFEComponent {
  /** Nome univoco del componente (es: "UserCard") */
  name: string

  /** Descrizione funzionale del componente */
  description: string

  /** Categoria per organizzazione (es: "Cards", "Forms", "Tables") */
  category?: string

  /** Props accettate dal componente */
  props?: MFEComponentProp[]

  /** Eventi emessi dal componente */
  events?: MFEComponentEvent[]

  /** HTML pre-renderizzato dell'esempio (security-sensitive) */
  exampleRendered?: string

  /** Esempio sorgente per documentazione */
  exampleSource?: string
}

MFEComponentProp

interface MFEComponentProp {
  name: string
  type: string         // es: "string", "User[]", "{ id: number }"
  required?: boolean
  default?: unknown
  description?: string
}

MFEComponentEvent

interface MFEComponentEvent {
  name: string
  payload?: string     // tipo TypeScript del payload (es: "User", "{ id: number }")
  description?: string
}

Quando usarlo

MFEComponent è metadata, non runtime: descrive componenti che il MFE espone ad altri MFE o alla shell per riuso UI. Il componente Vue concreto viene caricato separatamente (vedi MFELoadedComponent).

I casi tipici:

  • Design system distribuito: un MFE "ui-kit" espone bottoni/card/tabelle ad altri MFE
  • Widget catalog: il MFE registra una galleria di widget montabili in dashboard
  • Documentazione runtime: la shell genera markdown dei componenti via generateComponentDocs

Esempio

import type { MFEComponent } from '@pzeta/mfe-contracts'

const ClienteCard: MFEComponent = {
  name: 'ClienteCard',
  description: 'Card riassuntiva di un cliente con foto, nome e contatti',
  category: 'Cards',
  props: [
    {
      name: 'cliente',
      type: 'Cliente',
      required: true,
      description: 'Oggetto cliente da visualizzare',
    },
    {
      name: 'compact',
      type: 'boolean',
      required: false,
      default: false,
      description: 'Versione compatta senza foto',
    },
  ],
  events: [
    {
      name: 'edit',
      payload: 'Cliente',
      description: "Emesso al click sull'icona modifica",
    },
    {
      name: 'delete',
      payload: 'string', // id
      description: "Emesso al click sull'icona elimina",
    },
  ],
  exampleSource: `<ClienteCard
  :cliente="cliente"
  @edit="onEdit"
  @delete="onDelete"
/>`,
}

Sicurezza: exampleRendered

Attenzione XSS: il campo exampleRendered contiene HTML pre-renderizzato. Se viene mostrato via v-html:
  • Assicurati che provenga da fonte trusted (manifest statico hardcoded nel MFE, non input utente)
  • Sanitizza con DOMPurify se la fonte non è controllata
  • Considera di mostrare solo exampleSource (string) in un blocco <pre> per evitare il problema

Per default usa solo exampleSource (testo) e renderizza con <pre><code>{{ exampleSource }}</code></pre>.

Helpers correlati

Pattern: catalogo widget

// Manifest del MFE "widget-library"
{
  name: 'widget-library',
  components: [
    { name: 'KpiTile', category: 'Metrics', /* ... */ },
    { name: 'AreaChart', category: 'Charts', /* ... */ },
    { name: 'GeoMap', category: 'Maps', /* ... */ },
  ],
}

// Shell: catalogo automatico
import { groupComponentsByCategory } from '@pzeta/mfe-contracts/helpers'

const byCategory = groupComponentsByCategory(manifest.components ?? [])
// Map: 'Metrics' → [KpiTile], 'Charts' → [AreaChart], 'Maps' → [GeoMap]

Tipi correlati