Aller au contenu principal

Manifeste de contrôle personnalisé

Identifiant du schéma : custom-control-manifest@1 Schéma lisible par machine : custom-control-manifest.schema.json

La description canonique d’un contrôle personnalisé (de type PCF, section 6.3) : le remote Module Federation que le Player d’application pilotée par modèle monte à la place d’un éditeur de champ natif dans un formulaire ou une vue. Un manifeste est validé de manière identique, qu’il soit enregistré depuis le Centre de contrôle d’administration, soumis par un appel d’API direct, généré par un assistant IA ou transporté dans une importation de solution — la règle du chemin de validation unique (section 6.7).

Il ne s’écrit pas à la main. L’enregistrement d’un contrôle consiste à téléverser le package construit par @parsware/pack, et ce manifeste est composé à partir du parsware.json de cette archive (§28). Ce qui suit décrit la forme stockée, pour lire une solution exportée ou valider une solution que vous avez générée.

Structure​

ChampTypeObligatoireRemarques
logicalNamestringouiPréfixé par l’éditeur, en snake-case minuscule (p. ex. par_signature_pad). Lié à un champ de formulaire via la propriété control du champ.
displayNamestringouiNom lisible affiché dans la palette de champs du concepteur de formulaires.
descriptionstring | nullnonBrève description affichée à côté du contrôle.
scopestringouiLe nom de scope global du conteneur Module Federation (unique par remote), lu dans le mf-manifest.json du build plutôt que ressaisi.
modulestringouiLe chemin du module exposé que charge le Player (p. ex. ./Control). Doit commencer par ./. Également lu dans le build.
entryFileNamestringnonLe fichier d’entrée du conteneur dans le package (p. ex. remoteEntry.js). L’URL de service est calculée à partir de l’environnement, du nom logique et de ce fichier — il n’y a aucune URL à stocker. Vide en mode Hébergé.
packageHashstring | nullnonSHA-256 en hexadécimal minuscule de l’archive de package à partir de laquelle le contrôle a été enregistré. Comparé à l’importation aux octets transportés dans un package de solution, afin que ce qui est servi soit bien ce qui a été exporté. Null en mode Hébergé.
remoteEntryUrlstring | nullnonMode Hébergé uniquement : une URL http(s) absolue vers un remoteEntry.js servi en externe, pour le rechargement à chaud pendant la conception. Son enregistrement est refusé si le niveau de l’environnement n’est pas Développement, et un contrôle hébergé ne voyage pas dans un package de solution — son code n’appartient pas à la plateforme.
substitutesForstring[]ouiLes types de contrôle de champ auxquels ce contrôle peut être lié : un ou plusieurs parmi Text, MultilineText, Number, Boolean, DateTime, Lookup, File, Image, Custom. Doit contenir au moins une entrée. La palette de champs ne propose le contrôle que là où le type de contrôle d’un champ correspond. Il s’agit des familles de types de données auxquelles appartient un champ — et non des noms de contrôles intégrés que choisit un placement dans un formulaire (TextArea, Toggle, Dropdown, …), qui constituent un vocabulaire différent partageant par hasard quatre noms.

Ce qu’il n’a plus​

requestedScopes et declaredEntities ont disparu, et additionalProperties vaut false : un manifeste qui porte encore l’un ou l’autre est donc rejeté plutôt qu’ignoré en silence. Un contrôle s’exécute avec les autorisations de la personne qui l’utilise (§24) : un ensemble de portées demandées n’était jamais qu’intersecté avec la session de l’utilisateur, il pouvait donc restreindre l’utilisateur d’un contrôle mais jamais l’élargir, et la liste des tables déclarées n’était lue par aucun chemin de code. Supprimer les deux ramène l’histoire de la sécurité à une phrase plutôt qu’à deux réglages.

Le remoteEntryUrl obligatoire a disparu lui aussi. Le bundle voyage désormais sous forme de package servi depuis l’origine même de la plateforme ; l’URL est donc calculée au lieu d’être stockée (§28).

Le contrat du contrôle​

Le module exposé (./Control) est un unique composant React qui implémente le contrat fixe ParswareControlProps de @parsware/runtime-sdk :

interface ParswareControlProps {
value: unknown; // the bound field's current value
onChange: (next: unknown) => void; // commit a new value back to the form
fieldMetadata: FieldMetadata; // the bound field's type/label/constraints
context: RuntimeContext; // the same auth/data/logging context apps get
}

Le Player fournit ces props au moment du rendu. Un contrôle n’accède à la plateforme que par context (un ParswareRuntime) — jamais par un appel direct à la Gateway ou au service d’identité.

Où il est validé​

  • Enregistrement — l’Application Layer valide le manifeste selon custom-control-manifest@1 et exige que logicalName commence par le préfixe de l’éditeur propriétaire avant d’enregistrer le contrôle dans un environnement.
  • Importation de solution — chaque manifeste intégré à un package de solution est validé à nouveau selon le même schéma avant que le contrôle ne soit enregistré dans l’environnement cible.

Remarques de sécurité​

Un contrôle personnalisé s’exécute dans le même realm JavaScript que le Shell (Module Federation, pas une iframe — section 6.3) ; la frontière de confiance est donc appliquée ailleurs :

  • Un contrôle packagé est servi depuis l’origine même de la plateforme : il n’y a donc aucune origine externe à autoriser. La liste d’autorisation CSP conditionne toujours le mode Hébergé, seule forme dont un créateur peut faire pointer le bundle n’importe où — et qui est refusée hors d’un environnement de développement.
  • L’archive est vérifiée avant d’être stockée : taille, nombre de fichiers, taille une fois décompressée, absence d’entrée nommant un chemin hors de son propre dossier, et appartenance de chaque fichier à un type que sert la plateforme.
  • Le contrôle n’est chargeable que si une solution l’a déployé dans cet environnement, et l’empreinte du package est vérifiée à l’importation puis de nouveau avant toute décompression sur disque.
  • Chaque appel de données qu’il effectue via le Runtime SDK est autorisé côté serveur en fonction de l’App Context Token, qui porte les propres portées de l’utilisateur. Un contrôle peut faire exactement ce que peut faire la personne qui l’utilise, et aucun champ de ce manifeste ne change cela.

Voir aussi​