MallaDocs

SDK de plugins

definePlugin : connexions, secrets, opérations et la politique de requêtes sortantes.

Guide développeur

Les intégrations sont des plugins. Les connecteurs intégrés REST, GraphQL et CMS sont écrits avec le même @malla/plugin-sdk que n'importe quel plugin : une connection (connexion : réglages, champs secrets, un test) et des operations (opérations : requêtes et mutations) validées avec Zod.

Définir un plugin

ts
import { definePlugin, defineOperation } from '@malla/plugin-sdk'
import { z } from 'zod'

const config = z.object({
  baseUrl: z.url().describe('API base URL'),
})

export default definePlugin({
  id: 'weather',
  name: 'Weather',
  version: '1.0.0',
  description: 'Current conditions by city.',
  connection: {
    config,
    secrets: { apiKey: { label: 'API key' } },
    secretBoundFields: ['baseUrl'],          // changing it clears the stored key
    hosts: (c) => [new URL(c.baseUrl).host],  // the only hosts ctx.fetch may reach
    test: async (ctx) => {
      const res = await ctx.fetch(`${ctx.config.baseUrl}/ping`)
      if (!res.ok) throw new Error('Weather API unreachable')
    },
  },
  operations: {
    'weather.current': defineOperation({
      kind: 'query',
      name: 'Current weather',
      input: z.object({ city: z.string().min(1) }),
      output: z.object({ tempC: z.number(), summary: z.string() }),
      run: async (ctx, input) => {
        const url = `${ctx.config.baseUrl}/current?city=${encodeURIComponent(input.city)}`
        const res = await ctx.fetch(url, { headers: { 'x-api-key': ctx.secrets.apiKey ?? '' } })
        return res.json()
      },
    }),
  },
})
  • Les ids d'opération sont de la forme <plugin id>.<name> ; definePlugin le vérifie.
  • Le schéma input devient le formulaire de l'éditeur (sous forme de JSON Schema) et valide les entrées résolues ; output alimente l'autocomplétion.
  • connection: null signifie qu'aucune ligne d'intégration n'est nécessaire, comme pour le CMS intégré.
  • icon définit l'icône dans l'éditeur ; fetchTimeoutMs augmente le délai d'expiration de fetch pour les services amont lents comme les API de modèles (120 s au maximum).

Le contexte du plugin

ctx.configLes réglages de l'intégration, analysés par le schéma de votre connexion.
ctx.secretsLes secrets déchiffrés qui ont une valeur. Jamais envoyés au navigateur.
ctx.fetchUn fetch qui applique la politique : hôtes autorisés, HTTPS, pas d'adresses privées, délais d'expiration, taille plafonnée.
ctx.publishedVrai sur le site en ligne (données en ligne), faux dans l'éditeur (données de travail).
ctx.cmsPlugins maison uniquement : lister et lire les éléments du CMS.
ctx.postgresPlugins maison uniquement : une connexion TLS par appel, avec les mêmes vérifications d'adresse que fetch.
ctx.signalS'interrompt quand l'appelant annule.

Politique des requêtes sortantes

ctx.fetch n'atteint que les hôtes que déclare la connexion, en HTTPS. Il résout les noms d'hôte (DNS over HTTPS) avant chaque requête et chaque redirection, et bloque les réponses privées, de loopback et link-local ; il suit au maximum 5 redirections sur le même hôte, expire au bout de 10 secondes et plafonne les réponses à 2 Mo. ALLOW_LOCAL_INTEGRATIONS=1 lève les vérifications d'adresse, uniquement pour le développement local.

Secrets

Les valeurs secrètes sont chiffrées au repos et jamais renvoyées par l'API ; l'éditeur sait seulement lesquelles sont définies. Modifier un réglage de secretBoundFields ou l'ensemble des hôtes efface les secrets stockés, sauf si de nouvelles valeurs arrivent dans la même mise à jour : un jeton ne peut donc jamais être redirigé en silence vers un autre hôte.

Le catalogue de plugins

Les plugins sont publiés avec un manifeste qui déclare leurs permissions, passent une revue, puis sont installés par site, figés sur une version. Les mises à jour se font sur demande.