jlf-typed-form-craft
Version:
A library to create forms with typed datas and validations
1 lines • 20.7 kB
Source Map (JSON)
{"version":3,"file":"jlf-typed-form-craft.mjs","sources":["../../../projects/typed-form-craft/src/lib/typed-form-craft.service.ts","../../../projects/typed-form-craft/src/lib/typed-form-craft.component.ts","../../../projects/typed-form-craft/src/lib/utils/constantes.ts","../../../projects/typed-form-craft/src/lib/utils/forms.utils.ts","../../../projects/typed-form-craft/src/lib/utils/validators.utils.ts","../../../projects/typed-form-craft/src/lib/utils/form-decorator.ts","../../../projects/typed-form-craft/src/public-api.ts","../../../projects/typed-form-craft/src/jlf-typed-form-craft.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class TypedFormCraftService {\r\n\r\n constructor() { }\r\n}\r\n","import { Component } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'lib-typed-form-craft',\r\n imports: [],\r\n template: `\r\n <p>\r\n typed-form-craft works!\r\n </p>\r\n `,\r\n styles: ``\r\n})\r\nexport class TypedFormCraftComponent {\r\n\r\n}\r\n","export const FORM_CONTROL_METADATA = 'form:control:metadata';\r\n\r\nexport const FORM_GROUP_METADATA = 'form:group:metadata';\r\n","import {FormControl, FormGroup} from '@angular/forms';\r\nimport 'reflect-metadata';\r\nimport {Subscription, zip} from 'rxjs';\r\nimport {FORM_CONTROL_METADATA, FORM_GROUP_METADATA} from './constantes';\r\nimport {FormControlOptions} from '../types/form-control-options.type';\r\n\r\n// Type for validation options\r\n\r\n\r\n\r\n\r\n// Utility type for form controls\r\nexport type FormGroupControls<T> = {\r\n [K in keyof T]?: T[K] extends object ? FormGroup<FormGroupControls<T[K]>> : FormControl<T[K]>;\r\n};\r\n\r\nexport interface DestroyableFormGroup<T> extends FormGroup<FormGroupControls<T>> {\r\n destroy: () => void;\r\n}\r\n\r\n\r\n// Updated Form Factory\r\n\r\n\r\n/**\r\n * Creates a `DestroyableFormGroup` instance from a given class instance, using metadata to configure form controls and\r\n * validators. It maps the class instance's properties to form controls, applying default values, synchronous validators,\r\n * asynchronous validators, and enable/disable conditions where applicable.\r\n *\r\n * @template T The type of the class instance used for creating the form.\r\n * @param {T} instance An object instance of the class for which form controls should be created.\r\n * @returns {DestroyableFormGroup<T>} A reactive form group enhanced with a `destroy` method for cleanup.\r\n *\r\n * The method extracts metadata from the class instance to dynamically configure the form:\r\n * - Metadata specifies form control values, validators, and conditions for enabling or disabling controls.\r\n * - Validators and async validators are applied after the form group is created.\r\n * - The enable/disable logic listens to form changes and adjusts controls dynamically.\r\n *\r\n * The returned `DestroyableFormGroup` includes a `destroy` method, which unsubscribes from any internal subscriptions,\r\n * ensuring proper resource cleanup.\r\n */\r\n/*export const createFormFromClass = <T extends Record<string, any>>(instance: T): DestroyableFormGroup<T> => {\r\n const sub = new Subscription();\r\n const metadata: Record<string, FormControlOptions> | undefined = Reflect.getMetadata(\r\n FORM_CONTROL_METADATA,\r\n instance.constructor.prototype\r\n );\r\n\r\n const controls: { [key: string]: FormControl } = {};\r\n\r\n // First: create all the controls\r\n if (metadata) {\r\n for (const propertyKey in metadata) {\r\n if (Object.prototype.hasOwnProperty.call(metadata, propertyKey) &&\r\n Object.prototype.hasOwnProperty.call(instance, propertyKey)) {\r\n const options: FormControlOptions = metadata[propertyKey];\r\n const control = new FormControl(\r\n options.defaultValue !== undefined ? options.defaultValue : instance[propertyKey]\r\n );\r\n controls[propertyKey] = control;\r\n }\r\n }\r\n }\r\n\r\n // Create the FormGroup with controls\r\n const formGroup = new FormGroup(controls);\r\n\r\n // Second: configure validators after the FormGroup is created\r\n if (metadata) {\r\n for (const propertyKey in metadata) {\r\n const options = metadata[propertyKey];\r\n const control = controls[propertyKey];\r\n if (control) {\r\n if (options.validators) {\r\n control.setValidators(options.validators);\r\n }\r\n if (options.asyncValidators) {\r\n control.setAsyncValidators(options.asyncValidators);\r\n }\r\n control.updateValueAndValidity();\r\n }\r\n }\r\n }\r\n\r\n\r\n // Configure enable/disable conditions\r\n if (metadata) {\r\n for (const propertyKey in metadata) {\r\n const options = metadata[propertyKey];\r\n const control = controls[propertyKey];\r\n if (options.disable) {\r\n const shouldDisable = options.disable(formGroup);\r\n if (shouldDisable) {\r\n control.disable({ emitEvent: false });\r\n }\r\n\r\n sub.add(\r\n zip(formGroup.valueChanges, formGroup.statusChanges).subscribe({\r\n next: () => {\r\n const shouldDisable = options.disable(formGroup);\r\n if (shouldDisable && control.enabled) {\r\n control.disable();\r\n } else if (!shouldDisable && control.disabled) {\r\n control.enable();\r\n }\r\n\r\n }\r\n })\r\n )\r\n }\r\n }\r\n }\r\n\r\n return Object.assign(formGroup, {\r\n destroy: () => sub.unsubscribe()\r\n }) as DestroyableFormGroup<T>;\r\n}*/\r\n\r\n\r\nexport const createFormFromClass = <T extends Record<string, any>>(instance: T): DestroyableFormGroup<T> => {\r\n const sub = new Subscription();\r\n const controlMetadata: Record<string, FormControlOptions> | undefined = Reflect.getMetadata(\r\n FORM_CONTROL_METADATA,\r\n instance.constructor.prototype\r\n );\r\n\r\n const controls: { [key: string]: FormControl | FormGroup } = {};\r\n\r\n if (controlMetadata) {\r\n for (const propertyKey in instance) {\r\n if (instance.hasOwnProperty(propertyKey)) {\r\n const options = controlMetadata[propertyKey];\r\n\r\n if (options) {\r\n // Create a FormControl for properties with @controlProp\r\n const control = new FormControl(\r\n options.defaultValue !== undefined ? options.defaultValue : instance[propertyKey]\r\n );\r\n controls[propertyKey] = control;\r\n } else {\r\n // Assume it's a nested object and create a FormGroup for properties with @controlGroupProp\r\n if (typeof instance[propertyKey] === 'object' && instance[propertyKey] !== null) {\r\n const nestedFormGroup = createFormFromClass(instance[propertyKey]);\r\n controls[propertyKey] = nestedFormGroup;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n const formGroup = new FormGroup(controls);\r\n\r\n // Configure validators and async validators\r\n if (controlMetadata) {\r\n for (const propertyKey in controlMetadata) {\r\n const options = controlMetadata[propertyKey];\r\n const control = controls[propertyKey] as FormControl;\r\n if (control) {\r\n if (options.validators) {\r\n control.setValidators(options.validators);\r\n }\r\n if (options.asyncValidators) {\r\n control.setAsyncValidators(options.asyncValidators);\r\n }\r\n control.updateValueAndValidity();\r\n }\r\n }\r\n }\r\n\r\n // Configure enable/disable conditions\r\n if (controlMetadata) {\r\n for (const propertyKey in controlMetadata) {\r\n const options = controlMetadata[propertyKey];\r\n const control = controls[propertyKey] as FormControl;\r\n if (options.disable) {\r\n const shouldDisable = options.disable(formGroup);\r\n if (shouldDisable) {\r\n control.disable({ emitEvent: false });\r\n }\r\n\r\n sub.add(\r\n zip(formGroup.valueChanges, formGroup.statusChanges).subscribe({\r\n next: () => {\r\n const shouldDisable = options.disable(formGroup);\r\n if (shouldDisable && control.enabled) {\r\n control.disable();\r\n } else if (!shouldDisable && control.disabled) {\r\n control.enable();\r\n }\r\n }\r\n })\r\n );\r\n }\r\n }\r\n }\r\n\r\n return Object.assign(formGroup, {\r\n destroy: () => sub.unsubscribe()\r\n }) as DestroyableFormGroup<T>;\r\n};\r\n","import {AbstractControl, FormGroup, ValidationErrors, ValidatorFn, Validators} from '@angular/forms';\r\nimport {Subscription, zip} from 'rxjs';\r\n\r\n\r\nexport interface ConditionalValidatorConfig<T = any> {\r\n condition: (control: AbstractControl) => boolean;\r\n validator: ValidatorFn;\r\n}\r\n\r\n/**\r\n * A custom validator function that applies conditional validation logic\r\n * based on a user-defined configuration.\r\n *\r\n * The function evaluates a `condition` provided in the configuration to determine\r\n * whether the associated `validator` function should be applied to the control.\r\n * It also tracks changes to relevant fields in the form and revalidates the control\r\n * whenever any of the dependent fields are updated.\r\n *\r\n * This supports dynamic validation scenarios where the validity of a control\r\n * is determined by its relationship with other controls in the form.\r\n *\r\n * @param {ConditionalValidatorConfig} config - The configuration object containing\r\n * the condition function and the validator.\r\n * @returns {ValidatorFn} A validator function that implements the conditional validation logic.\r\n */\r\nexport const conditionalValidator = (config: ConditionalValidatorConfig): ValidatorFn => {\r\n let lastForm: FormGroup | null = null;\r\n let subscriptions = new Subscription();\r\n\r\n return (control: AbstractControl): ValidationErrors | null => {\r\n const form = control.parent as FormGroup;\r\n\r\n if (form && form !== lastForm) {\r\n subscriptions.unsubscribe();\r\n subscriptions = new Subscription();\r\n\r\n // execute the condition a first time by intercepting the calls to get()\r\n const watchedFields = new Set<string>();\r\n const originalGet = form.get.bind(form);\r\n\r\n form.get = (path: string) => {\r\n watchedFields.add(path);\r\n return originalGet(path);\r\n };\r\n\r\n // Test execution to detect used fields\r\n config.condition(control);\r\n\r\n // Restore the original get method\r\n form.get = originalGet;\r\n\r\n // Setting up monitoring for detected fields\r\n watchedFields.forEach(fieldName => {\r\n const field = form.get(fieldName);\r\n if (field) {\r\n subscriptions.add(\r\n zip(field.valueChanges, field.statusChanges).subscribe({\r\n next: () => (control.updateValueAndValidity({ emitEvent: false }))\r\n })\r\n );\r\n }\r\n });\r\n\r\n lastForm = form;\r\n }\r\n\r\n return config.condition(control) ? config.validator(control) : null;\r\n };\r\n}\r\n\r\n\r\n\r\n/**\r\n * JlValidators provides a collection of custom validators that execute conditionally\r\n * based on a specified condition function and Angular's built-in validators.\r\n */\r\nexport const JlValidators = {\r\n required: (condition: (formGroup: FormGroup) => boolean): ValidatorFn => {\r\n return conditionalValidator({\r\n condition: (control: AbstractControl) => condition(control.parent as FormGroup),\r\n validator: Validators.required,\r\n });\r\n },\r\n\r\n minLength: (length: number, condition: (control: AbstractControl) => boolean, watchFields?: string[]): ValidatorFn => {\r\n return conditionalValidator({\r\n condition,\r\n validator: Validators.minLength(length)\r\n });\r\n },\r\n\r\n maxLength: (length: number, condition: (control: AbstractControl) => boolean, watchFields?: string[]): ValidatorFn => {\r\n return conditionalValidator({\r\n condition,\r\n validator: Validators.maxLength(length)\r\n });\r\n },\r\n\r\n pattern: (pattern: string | RegExp, condition: (control: AbstractControl) => boolean, watchFields?: string[]): ValidatorFn => {\r\n return conditionalValidator({\r\n condition,\r\n validator: Validators.pattern(pattern)\r\n });\r\n },\r\n\r\n email: (condition: (control: AbstractControl) => boolean): ValidatorFn => {\r\n return conditionalValidator({\r\n condition,\r\n validator: Validators.email\r\n });\r\n },\r\n\r\n min: (min: number, condition: (control: AbstractControl) => boolean): ValidatorFn => {\r\n return conditionalValidator({\r\n condition,\r\n validator: Validators.min(min)\r\n });\r\n },\r\n\r\n max: (max: number, condition: (control: AbstractControl) => boolean): ValidatorFn => {\r\n return conditionalValidator({\r\n condition,\r\n validator: Validators.max(max)\r\n });\r\n },\r\n\r\n requiredTrue: (condition: (control: AbstractControl) => boolean): ValidatorFn => {\r\n return conditionalValidator({\r\n condition,\r\n validator: Validators.requiredTrue\r\n });\r\n }\r\n};\r\n","// Definition of decorator\r\nimport {FORM_CONTROL_METADATA} from './constantes';\r\nimport {FormControlOptions} from '../types/form-control-options.type';\r\nimport 'reflect-metadata';\r\n\r\nexport const controlProp = (options: Partial<FormControlOptions>) => {\r\n return (target: any, propertyKey: string) => {\r\n // Stores options in class (not instance) metadata\r\n const existingMetadata: Record<string, Partial<FormControlOptions>> =\r\n Reflect.getMetadata(FORM_CONTROL_METADATA, target) || {};\r\n\r\n existingMetadata[propertyKey] = options;\r\n Reflect.defineMetadata(FORM_CONTROL_METADATA, existingMetadata, target);\r\n };\r\n};\r\n/*TODO fonctionne (penser à instancier l'objet par défaut). Il faut maintenant chercher un moyen pour faire communiquer\r\n* le Formgroup parent avec le Formgroup enfant, en particulier pour les conditionnal validators */\r\nexport const controlGroupProp = () => {\r\n return (target: any, propertyKey: string) => {\r\n };\r\n};\r\n","/*\r\n * Public API Surface of typed-form-craft\r\n */\r\n\r\nexport * from './lib/typed-form-craft.service';\r\nexport * from './lib/typed-form-craft.component';\r\nexport * from './lib/utils/forms.utils';\r\nexport * from './lib/utils/validators.utils';\r\nexport * from './lib/utils/constantes';\r\nexport * from './lib/utils/form-decorator';\r\nexport * from './lib/types/form-control-options.type';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}