@ainelo/form-engine 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,453 @@
1
+ /**
2
+ * Represents a generic response value that can be of various types.
3
+ *
4
+ * @property responseValue - The value of the response, which can be a string, an array of strings,
5
+ * a number, an array of numbers, a boolean, a File, or an array of Files.
6
+ */
7
+ interface ResponseInForm {
8
+ responseValue: string | string[] | number | number[] | boolean | File | File[] | null;
9
+ }
10
+ /**
11
+ * Représente une option sélectionnable dans un champ de formulaire de type sélection.
12
+ *
13
+ * @property value - La valeur unique associée à l’option (utilisée en interne).
14
+ * @property label - Le libellé affiché à l’utilisateur. Peut être une chaîne de caractères ou un objet de traductions par langue.
15
+ * @property points - (Optionnel) Nombre de points associés à cette option, utilisé pour des calculs ou des scores.
16
+ * @property icon - (Optionnel) Icône à afficher à côté de l’option dans l’interface utilisateur.
17
+ */
18
+ interface SelectOption {
19
+ value: string;
20
+ label: string | {
21
+ [lang: string]: string;
22
+ };
23
+ points?: number;
24
+ icon?: string;
25
+ }
26
+ type ConditionalOperator = "==" | "!=" | ">" | "<" | "IN" | "NOT IN" | "CONTAINS" | "NOT CONTAINS";
27
+ /**
28
+ * Méthodes d’agrégation de valeurs de plusieurs champs
29
+ */
30
+ type TypeComputation = "SOMME" | "MULTIPLICATION";
31
+ /**
32
+ * Une règle unique de condition d'affichage.
33
+ */
34
+ interface ConditionalDisplayRule {
35
+ /**
36
+ * Clé(s) technique(s) des champs sur lesquels appliquer la règle.
37
+ * Peut être utilisé si formFieldId n’est pas renseigné.
38
+ */
39
+ fieldName?: string | string[];
40
+ /**
41
+ * ID(s) unique(s) des champs (UUID).
42
+ * Peut remplacer ou compléter fieldName.
43
+ */
44
+ formFieldId?: string | string[];
45
+ /**
46
+ * La valeur ou les valeurs attendues (cible de comparaison).
47
+ */
48
+ value?: string | number | boolean | string[] | number[];
49
+ /**
50
+ * L’opérateur de comparaison.
51
+ */
52
+ operator?: ConditionalOperator;
53
+ /**
54
+ * Comparaison à une valeur numérique (dans le cas d’une agrégation ou d’un champ nombre).
55
+ */
56
+ numeric_compare_to?: number;
57
+ /**
58
+ * Si plusieurs champs sont ciblés, méthode d’agrégation des valeurs.
59
+ * Exemple : SOMME, MULTIPLICATION
60
+ */
61
+ typeComputation?: TypeComputation;
62
+ }
63
+ /**
64
+ * Groupe de règles à combiner selon une logique AND ou OR
65
+ */
66
+ interface ConditionalDisplayGroup {
67
+ rules: ConditionalDisplayRule | ConditionalDisplayRule[];
68
+ logic?: "AND" | "OR";
69
+ }
70
+ /**
71
+ * Represents the available validation types for form fields.
72
+ *
73
+ * - `"required"`: Ensures the field is not empty.
74
+ * - `"minLength"`: Validates that the field value meets a minimum length.
75
+ * - `"maxLength"`: Validates that the field value does not exceed a maximum length.
76
+ * - `"regex"`: Validates the field value against a regular expression pattern.
77
+ * - `"email"`: Ensures the field value is a valid email address.
78
+ * - `"number"`: Ensures the field value is a valid number.
79
+ * - `"fileSize"`: Validates the size of an uploaded file.
80
+ * - `"phone_number"`: Ensures the field value is a valid phone number.
81
+ * - `"textarea"`: Indicates the field is a textarea input.
82
+ * - `"fileType"`: Validates the type of an uploaded file.
83
+ */
84
+ type ValidationType = "required" | "minLength" | "maxLength" | "regex" | "email" | "number" | "fileSize" | "phone_number" | "textarea" | "fileType";
85
+ /**
86
+ * Represents a validation rule for a form field.
87
+ *
88
+ * @property validationType - The type of validation to apply (e.g., required, minLength, pattern).
89
+ * @property value - The value associated with the validation rule. This can be a number, a string, or an array of strings, depending on the validation type.
90
+ * @property errMsg - The error message to display if the validation fails.
91
+ */
92
+ interface ValidationRule {
93
+ validationType?: ValidationType;
94
+ value?: number | string | string[];
95
+ errMsg: string;
96
+ }
97
+ /**
98
+ * Décrit la logique de répétition d’un groupe de champs selon une valeur numérique saisie dans un autre champ.
99
+ */
100
+ interface RepeatRule {
101
+ /**
102
+ * Limite maximale du nombre de répétitions autorisées (optionnelle).
103
+ */
104
+ max?: number;
105
+ /**
106
+ * Limite minimale du nombre de répétitions requises (optionnelle).
107
+ */
108
+ min?: number;
109
+ /**
110
+ * Indique si on pré-remplit automatiquement un ensemble vide (utile pour le rendu initial).
111
+ */
112
+ prefillEmpty?: boolean;
113
+ }
114
+ interface FormRepeatGroup {
115
+ repeatGroupId: string;
116
+ fieldName: string;
117
+ label: string | {
118
+ [lang: string]: string;
119
+ };
120
+ minRepeats?: number;
121
+ maxRepeats?: number;
122
+ initialRepeats?: number;
123
+ formFields: FormField[];
124
+ position?: number;
125
+ conditionalDisplay?: ConditionalDisplayGroup;
126
+ }
127
+ declare enum SpecialField {
128
+ IMAGE = "IMAGE",
129
+ VIDEO = "VIDEO",
130
+ AUDIO = "AUDIO",
131
+ DOCUMENT = "DOCUMENT",
132
+ PDF = "PDF",
133
+ VOICE = "VOICE",
134
+ TIP_TAP_DOC_TEXT = "TIP_TAP_DOC_TEXT",
135
+ OTP = "OTP"
136
+ }
137
+ interface OTPFormFieldExecOptions {
138
+ serverDns: string;
139
+ /** Endpoint relatif, ex: /api/otp/send */
140
+ postApiEndPoint: string;
141
+ /** Payload à envoyer avec la requête OTP (sera fusionné avec les données du formulaire) */
142
+ payload?: Record<string, any> | Map<string, unknown>;
143
+ /** Headers additionnels à joindre à la requête */
144
+ extraHeaders?: Record<string, string>;
145
+ /** Token Bearer pour l'authentification */
146
+ bearer?: string;
147
+ /** Timeout en ms pour la requête */
148
+ timeoutMs?: number;
149
+ /** Nombre de cases OTP (défaut: 6) */
150
+ otpLength?: number;
151
+ /** Nom du champ Email qui doit déclencher l'envoi de l'OTP (dans une section précédente) */
152
+ linkedEmailFieldName?: string;
153
+ /** Configuration pour l'envoi initial de l'OTP (quand l'email est saisi). Si non défini, utilise la même config que la vérification */
154
+ sendOTPApiConfig?: {
155
+ serverDns: string;
156
+ postApiEndPoint: string;
157
+ payload?: Record<string, any> | Map<string, unknown>;
158
+ extraHeaders?: Record<string, string>;
159
+ bearer?: string;
160
+ };
161
+ /** Activer la validation automatique quand tous les chiffres sont saisis (défaut: false) */
162
+ autoValidate?: boolean;
163
+ /** Activer le bouton "Renvoyer le code" (défaut: true) */
164
+ enableResend?: boolean;
165
+ /** Délai minimum en secondes entre deux envois de code (défaut: 60) */
166
+ resendCooldownSeconds?: number;
167
+ }
168
+ interface EmailFormFieldExecOptions {
169
+ /** Si true, déclenche automatiquement l'envoi d'OTP quand l'email est validé */
170
+ triggerOTPSend?: boolean;
171
+ /** Nom du champ OTP lié (optionnel, pour validation) */
172
+ linkedOTPFieldName?: string;
173
+ /** Configuration API pour l'envoi d'OTP */
174
+ otpSendApiConfig?: {
175
+ serverDns: string;
176
+ postApiEndPoint: string;
177
+ payload?: Record<string, any> | Map<string, unknown>;
178
+ extraHeaders?: Record<string, string>;
179
+ bearer?: string;
180
+ };
181
+ }
182
+ interface OTPFormFieldLink {
183
+ fieldName: string;
184
+ fieldType: "email" | "favoris";
185
+ }
186
+ interface FileToBucketManage {
187
+ uploadOption: UploadOption;
188
+ deleteOption: DeleteOption;
189
+ }
190
+ /**
191
+ * Options pour l’upload d’un fichier vers le bucket.
192
+ * Correspond à POST /api/files/upload-file (ou /upload-files pour du multi).
193
+ */
194
+ interface UploadOption {
195
+ /** Base URL du service, ex: https://bucket.urmaphalab.com */
196
+ serverDns: string;
197
+ /** Endpoint relatif, ex: /api/files/upload-file */
198
+ postApiEndPoint: string;
199
+ /**
200
+ * Payload non sérialisé : sera converti en multipart/form-data.
201
+ * Clés attendues par l’API :
202
+ * - file : File ou Blob (obligatoire)
203
+ * - secret_key : string (obligatoire)
204
+ * - folder_name : string (optionnel, défaut “general”)
205
+ * - filename : string (optionnel, sans extension)
206
+ * - files / filenames pour la variante multi-upload
207
+ */
208
+ payload?: Map<string, unknown> | Record<string, unknown>;
209
+ /** Optionnel : Authorization: Bearer ... si l’API évolue en nécessite */
210
+ bearer?: string;
211
+ /** Headers supplémentaires à joindre à la requête (hors Content-Type géré par FormData) */
212
+ extraHeaders?: Record<string, string>;
213
+ /** Timeout en ms, si l’on veut borner la requête */
214
+ timeoutMs?: number;
215
+ /** Optionnel : hook pour logger ou transformer la réponse brute */
216
+ onResponse?(response: Response): Promise<void>;
217
+ }
218
+ /**
219
+ * Options pour supprimer un fichier du bucket.
220
+ * Compatible avec:
221
+ * - DELETE /api/files/delete-file
222
+ * - DELETE /api/files/delete-file-by-url
223
+ */
224
+ interface DeleteOption {
225
+ /** Base URL du service, ex: https://bucket.urmaphalab.com */
226
+ serverDns: string;
227
+ /** Endpoint relatif, ex: /api/files/delete-file */
228
+ deleteApiEndPoint: string;
229
+ /**
230
+ * Payload JSON envoyé en body (ou query string).
231
+ * Clés possibles suivant la route utilisée :
232
+ * - secret_key : string (obligatoire)
233
+ * - folder_name : string (optionnel, défaut “general”)
234
+ * - filename : string (obligatoire si delete-file)
235
+ * - file_url : string (obligatoire si delete-file-by-url)
236
+ */
237
+ payload?: Record<string, unknown> | Map<string, unknown>;
238
+ /** Optionnel : Authorization: Bearer ... */
239
+ bearer?: string;
240
+ /** Headers additionnels à envoyer */
241
+ extraHeaders?: Record<string, string>;
242
+ /** Timeout en ms pour cette requête */
243
+ timeoutMs?: number;
244
+ /** Optionnel : hook pour logger ou transformer la réponse brute */
245
+ onResponse?(response: Response): Promise<void>;
246
+ }
247
+ /**
248
+ * Represents a form field definition with metadata, validation, and display options.
249
+ *
250
+ * @property formFieldId - Unique identifier for the form field (UUID or generated).
251
+ * @property fieldName - Internal technical key for the field.
252
+ * @property slug - Optional, human-readable key for URLs or UI.
253
+ * @property dataLabel - Optional, label used for export or processing.
254
+ * @property fieldType - Type of the form field (e.g., text, dropdown, date, etc.).
255
+ * @property label - Field label, can be a string or a multilingual object.
256
+ * @property response - The response value or list of responses for the field.
257
+ * @property selectOptions - Optional, list of selectable options for select, radio, or checkbox fields.
258
+ * @property validations - Optional, array of validation rules for the field.
259
+ * @property position - Optional, display order of the field.
260
+ * @property placeholder - Optional, placeholder text, can be a string or multilingual object.
261
+ * @property tooltip - Optional, tooltip text, can be a string or multilingual object.
262
+ * @property helpText - Optional, help text, can be a string or multilingual object.
263
+ * @property example - Optional, example value, can be a string or multilingual object.
264
+ * @property conditionalDisplay - Optional, conditional display logic for the field.
265
+ */
266
+ interface FormField {
267
+ formFieldId: string;
268
+ fieldName: string;
269
+ slug?: string;
270
+ fieldType: "text" | "textarea" | "dropdown" | "radio" | "checkbox" | "date" | "number" | "bool" | "file" | "password" | SpecialField;
271
+ label: string | {
272
+ [lang: string]: string;
273
+ };
274
+ repeatGroup?: FormRepeatGroup;
275
+ repeatRule?: RepeatRule;
276
+ response: ResponseInForm;
277
+ selectOptions?: SelectOption[];
278
+ validations?: ValidationRule[];
279
+ position?: number;
280
+ placeholder?: string | {
281
+ [lang: string]: string;
282
+ };
283
+ tooltip?: string | {
284
+ [lang: string]: string;
285
+ };
286
+ helpText?: string | {
287
+ [lang: string]: string;
288
+ };
289
+ example?: string | {
290
+ [lang: string]: string;
291
+ };
292
+ enableSearch?: boolean;
293
+ dynamicFilterRule?: DynamicFilterRule;
294
+ conditionalDisplay?: ConditionalDisplayGroup;
295
+ fileToBucketManage?: FileToBucketManage;
296
+ width?: "full" | "half";
297
+ otpFormFieldExecOptions?: OTPFormFieldExecOptions;
298
+ emailFormFieldExecOptions?: EmailFormFieldExecOptions;
299
+ flattenOnSubmit?: boolean;
300
+ detailInfos?: DetailInfosConfig;
301
+ }
302
+ /**
303
+ * Configuration pour générer automatiquement des champs de détails
304
+ * quand une option est sélectionnée dans un dropdown, radio ou checkbox.
305
+ *
306
+ * @property [optionValue] - Pour chaque valeur d'option, définir les champs de détails à générer
307
+ * @property formFields - Liste des champs à générer pour cette option
308
+ * @property label - Label optionnel pour le groupe de détails (peut être multilingue)
309
+ */
310
+ interface DetailInfosConfig {
311
+ [optionValue: string]: {
312
+ formFields: FormField[];
313
+ label?: string | {
314
+ [lang: string]: string;
315
+ };
316
+ };
317
+ }
318
+ interface DynamicFilterRule {
319
+ dependentFieldName: string;
320
+ filterType: "exact" | "hierarchical";
321
+ dataSource: {
322
+ type: "static" | "external";
323
+ data: Record<string, DynamicFilteringDataSourceElement[]>;
324
+ endpoint?: string;
325
+ };
326
+ transform?: {
327
+ valueKey: string;
328
+ labelKey: string;
329
+ };
330
+ }
331
+ interface DynamicFilteringDataSourceElement {
332
+ value: string;
333
+ label: string | {
334
+ [lang: string]: string;
335
+ };
336
+ }
337
+ /**
338
+ * Sous-section regroupant des champs.
339
+ */
340
+ /**
341
+ * Represents a subsection within a form structure.
342
+ *
343
+ * @property subSectionId - Unique identifier for the subsection.
344
+ * @property title - Optional title of the subsection. Can be a string, a localized object, or null.
345
+ * @property subTitle - Optional subtitle of the subsection. Can be a string, a localized object, or null.
346
+ * @property isSpacer - Optional visual spacer indicator (e.g., for visual separation).
347
+ * @property position - Optional display order of the subsection.
348
+ * @property formFields - Array of form fields contained in this subsection.
349
+ */
350
+ interface Section {
351
+ sectionId: string;
352
+ title?: string | {
353
+ [lang: string]: string;
354
+ } | null;
355
+ subTitle?: string | {
356
+ [lang: string]: string;
357
+ } | null;
358
+ isSpacer?: string;
359
+ position?: number;
360
+ formFields: FormField[];
361
+ conditionalDisplay?: ConditionalDisplayGroup;
362
+ }
363
+ /**
364
+ * Structure complète d’un formulaire.
365
+ */
366
+ /**
367
+ * Represents the structure of a form.
368
+ *
369
+ * @property name - The name of the form.
370
+ * @property provider - The author or provider of the form.
371
+ * @property description - A general description of the form.
372
+ * @property status - The activation status of the form. Can be "ACTIVE" or "INACTIVE".
373
+ * @property isDeclaration - Indicates if the form is an official declaration (1 = yes, 0 = no).
374
+ * @property isTest - Indicates if the form is a test form (1 = yes, 0 = no).
375
+ * @property version - (Optional) The version of the form.
376
+ * @property createdAt - (Optional) The ISO date when the form was created.
377
+ * @property updatedAt - (Optional) The ISO date when the form was last updated.
378
+ * @property sections - The sections that compose the form.
379
+ */
380
+ interface FormTheme {
381
+ primaryColor?: string;
382
+ }
383
+ interface FormStructure {
384
+ name: string;
385
+ provider: string;
386
+ description: string;
387
+ status: "ACTIVE" | "INACTIVE";
388
+ isDeclaration: number;
389
+ isTest: number;
390
+ version?: string;
391
+ createdAt?: string;
392
+ updatedAt?: string;
393
+ sections: Section[];
394
+ theme?: FormTheme;
395
+ layoutOptions?: FormEngineLayoutOptions;
396
+ }
397
+ interface FormEngineLayoutOptions {
398
+ paginationMode?: "byFields" | "bySection";
399
+ progressBarType?: ProgressBarType;
400
+ headerOptions?: HeaderOptions;
401
+ displayDeleteButton?: boolean;
402
+ containerStyles?: ContainerStylesOptions;
403
+ }
404
+ interface ProgressBarType {
405
+ type: "default_step" | "custom" | "pastel" | "linear" | "section_bubble" | "section_bubble_pastel";
406
+ colors?: {
407
+ background: string;
408
+ foreground: string;
409
+ };
410
+ visible?: boolean;
411
+ }
412
+ interface HeaderOptions {
413
+ visible?: boolean;
414
+ type: "default" | "custom";
415
+ customHeader?: React.ReactNode;
416
+ }
417
+ interface ContainerStyles {
418
+ borderColor?: string;
419
+ borderWidth?: string | number;
420
+ backgroundColor?: string;
421
+ }
422
+ interface ContainerStylesOptions {
423
+ mainContainer?: ContainerStyles;
424
+ sectionContainer?: ContainerStyles;
425
+ }
426
+
427
+ interface FormEngineProps {
428
+ form: FormStructure;
429
+ formId: string;
430
+ onSubmit: (data: Record<string, any>) => void;
431
+ currentLang?: string;
432
+ submitButtonText?: string;
433
+ paginationMode?: "byFields" | "bySection";
434
+ }
435
+ interface FieldValidationError {
436
+ fieldName: string;
437
+ fieldLabel: string;
438
+ errors: string[];
439
+ }
440
+ interface FormValidationResult {
441
+ isValid: boolean;
442
+ touched: boolean;
443
+ allRequiredFieldsFilled: boolean;
444
+ visibleFieldsCount: number;
445
+ requiredFieldsCount: number;
446
+ invalidFields?: FieldValidationError[];
447
+ untouchedRequiredFields?: FieldValidationError[];
448
+ emptyRequiredFields?: FieldValidationError[];
449
+ }
450
+
451
+ declare const FormEngine: React.FC<FormEngineProps>;
452
+
453
+ export { type ConditionalDisplayGroup, type ConditionalDisplayRule, type ConditionalOperator, type ContainerStyles, type ContainerStylesOptions, type DeleteOption, type DetailInfosConfig, type DynamicFilterRule, type DynamicFilteringDataSourceElement, type EmailFormFieldExecOptions, type FieldValidationError, type FileToBucketManage, FormEngine, type FormEngineLayoutOptions, type FormEngineProps, type FormField, type FormRepeatGroup, type FormStructure, type FormTheme, type FormValidationResult, type HeaderOptions, type OTPFormFieldExecOptions, type OTPFormFieldLink, type ProgressBarType, type RepeatRule, type ResponseInForm, type Section, type SelectOption, SpecialField, type TypeComputation, type UploadOption, type ValidationRule, type ValidationType };