Protocole agnostique pour décrire, valider et alimenter dynamiquement des champs de saisie – version 2 unifiée (atomic constraints + domaine de valeurs centralisé).
La branche principale reflète la spécification v2. Le modèle v1 (composite constraints,
enumValues
) est déprécié. Voirdocs/MIGRATION_V1_V2.md
.
Définissez côté serveur les champs (métadonnées, contraintes, domaine de valeurs) et laissez les clients appliquer une validation déterministe et fournir une UX riche (autocomplete, pagination, filtrage) sans logique dupliquée.
Besoin | Ce projet | JSON Schema | Zod / Yup |
---|---|---|---|
Domaine de valeurs dynamique (search + pagination) | ✅ Modèle unifié valuesEndpoint |
❌ (extensions ad-hoc) | ❌ (logique code) |
Mode suggestions vs fermé | ✅ mode: SUGGESTIONS/CLOSED |
❌ | ❌ |
Pipeline inter-langages normatif | ✅ Spécifié | Partiel (validation générique) | ❌ (exécution runtime locale) |
Migration versionnée protocolaire | ✅ Pages dédiées | ❌ | |
Séparation norme / impl extensions | ✅ (Impl Notes) | ❌ | ❌ |
Ce protocole complète plutôt qu’il ne remplace ces outils : vous pouvez générer plus tard un JSON Schema dérivé pour du gating API.
// ❌ Avant : Logique dupliquée et incohérente
const validateEmailA = (email:string) => /^[^@]+@[^@]+\.[^@]+$/.test(email);
const validateEmailB = (email:string) => email.includes('@'); // Différent !
// ✅ Après : Spécification centrale
const emailFieldSpec = {
displayName: 'Email', dataType: 'STRING', required: true,
constraints: [{ name: 'pattern', type: 'pattern', params: { regex: '^[^@]+@[^@]+\\.[^@]+$' } }]
};
Domaine | Description | Statut |
---|---|---|
Modèle unifié | Champ = métadonnées + contraintes atomiques + valuesEndpoint |
Stable |
Domaine de valeurs | INLINE ou endpoint (pagination + recherche + mode CLOSED/SUGGESTIONS) | Stable |
Pipeline validation | REQUIRED → TYPE → MEMBERSHIP → CONTRAINTES ordonnées | Stable |
Erreurs structurées | Nom de contrainte + message + index multi | Stable |
Legacy adapter | Traduction v1 → v2 (TS uniquement) | Stable (déprécié) |
Coercion douce | Conversion nombre, booléen, date epoch (TS) | Extension |
Short‑circuit | Arrêt sur première erreur (Java) | Extension |
Hints performance | debounceMs , stratégies cache côté client |
Stable |
Extensibilité | custom + futurs types |
Stable |
Les éléments "Extension" ne sont pas normatifs (hors cœur protocole) et sont documentés dans
docs/IMPLEMENTATION_NOTES.md
.
{
"displayName": "Assigné à",
"description": "Sélection utilisateur (autocomplete)",
"dataType": "STRING",
"expectMultipleValues": false,
"required": true,
"valuesEndpoint": {
"protocol": "HTTPS",
"uri": "/api/users",
"searchField": "name",
"paginationStrategy": "PAGE_NUMBER",
"mode": "CLOSED",
"debounceMs": 300,
"responseMapping": { "dataField": "data" },
"requestParams": { "pageParam": "page", "limitParam": "limit", "searchParam": "q", "defaultLimit": 20 }
},
"constraints": [
{ "name": "syntax", "type": "pattern", "params": { "regex": "^[A-Za-z0-9_]+$" }, "errorMessage": "Identifiant invalide" }
]
}
import { FieldValidator } from '@cyfko/input-spec';
const validator = new FieldValidator();
const result = await validator.validate(fieldSpec, selectedUserId);
if(!result.isValid) console.log(result.errors);
import { FieldValidator } from '@cyfko/input-spec';
const spec = {
displayName: 'Code pays', dataType: 'STRING', required: true,
expectMultipleValues: false,
constraints: [{ name: 'iso', type: 'pattern', params: { regex: '^[A-Z]{2}$' }, errorMessage: 'Format ISO2 requis' }]
};
const validator = new FieldValidator();
console.log(await validator.validate(spec, 'FR').isValid); // true
console.log(await validator.validate(spec, 'France').errors[0]); // { constraintName: 'iso', message: 'Format ISO2 requis' }
{
"isValid": false,
"errors": [
{ "constraintName": "iso", "message": "Format ISO2 requis", "index": 1 },
{ "constraintName": "iso", "message": "Format ISO2 requis", "index": 3 }
]
}
import { ValuesResolver, FetchHttpClient, MemoryCacheProvider } from '@cyfko/input-spec';
const resolver = new ValuesResolver(new FetchHttpClient(), new MemoryCacheProvider());
const { values } = await resolver.resolveValues(fieldSpec.valuesEndpoint!, { search: 'john', page: 1 });
Niveau | Guide | Contenu |
---|---|---|
Débutant | docs/QUICK_START.md |
Premier champ et validation |
Intermédiaire | docs/INTERMEDIATE_GUIDE.md |
Composition, multi-champs |
Expert | docs/EXPERT_GUIDE.md |
Architecture interne |
- Spécification :
PROTOCOL_SPECIFICATION.md
- Migration v1→v2 :
docs/MIGRATION_V1_V2.md
- Notes implémentation :
docs/IMPLEMENTATION_NOTES.md
- FAQ :
docs/FAQ.md
- Contribution :
docs/CONTRIBUTING.md
npm install @cyfko/input-spec
<dependency>
<groupId>io.github.cyfko</groupId>
<artifactId>input-spec</artifactId>
<version>2.0.0</version>
</dependency>
Langage | Validation | Résolution valeurs | Cache | Tests | Statut |
---|---|---|---|---|---|
TypeScript | ✅ (atomic, membership) | ✅ (INLINE + remote hints) | ✅ mémoire | ✅ | Stable |
Java | ✅ (atomic) | Partiel (remote hors scope) | 🚧 | ✅ | Beta |
Python | Planifié | - | - | - | Backlog |
C# | Planifié | - | - | - | Backlog |
- Formulaire complet :
impl/typescript/examples/complete-form.ts
- Valeurs dynamiques :
impl/typescript/examples/dynamic-values.ts
- FAQ scénarios :
docs/FAQ.md
graph TB
SPEC[Spécifications Champs] --> VALID[Validation]
SPEC --> VALUES[Résolution Valeurs]
VALUES --> CACHE[Cache]
VALID --> ERR[Résultats Structurés]
Parfait pour : multi-formulaires, multi-clients, validation métier riche, configuration dynamique. Moins utile pour micro-apps statiques.
Version | Objectifs | Statut |
---|---|---|
2.0.x | Corrections mineures, alignement Java (minLength single) | En cours |
2.1.0 | Génération JSON Schema, membership strict remote, collectionSize |
Planifié |
2.x | I18n messages, contraintes email/uuid natives | Backlog |
3.0.0 | Retrait legacy adapter v1 (TS) | Prévision |
Guide : docs/CONTRIBUTING.md
– tests, implémentations supplémentaires, exemples réels bienvenus.
- Stars / Forks / Issues : onglets GitHub
- Contributions prioritaires : tests de conformité multi-langages, adaptateurs frameworks
Licence MIT – voir LICENSE
.
- Doc site : https://cyfko.github.io/input-spec/
- Issues : ../../issues
- Discussions : ../../discussions
- Releases : ../../releases
- Changelog TypeScript :
impl/typescript/CHANGELOG.md
- Changelog Java :
impl/java/CHANGELOG.md
Fait avec ❤️ par la communauté
Version protocole: 2.0.0 • Dernière mise à jour: Octobre 2025