@decaf-ts/for-angular 0.0.4 → 0.0.5

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.
Files changed (85) hide show
  1. package/LICENSE.md +646 -144
  2. package/README.md +37 -242
  3. package/dist/lib/README.md +92 -0
  4. package/dist/lib/assets/i18n/en.json +131 -0
  5. package/dist/lib/assets/images/angular-logo.svg +45 -0
  6. package/dist/lib/assets/images/decaf-logo-black.svg +22 -0
  7. package/dist/lib/assets/images/decaf-logo-lw.svg +50 -0
  8. package/dist/lib/assets/images/decaf-logo-white.svg +22 -0
  9. package/dist/lib/assets/images/decaf-logo.svg +54 -0
  10. package/dist/lib/components/component-renderer/component-renderer.component.d.ts +267 -0
  11. package/dist/lib/components/crud-field/crud-field.component.d.ts +447 -0
  12. package/dist/{for-angular/components/decaf-crud-form → lib/components/crud-form}/constants.d.ts +0 -0
  13. package/dist/lib/components/crud-form/crud-form.component.d.ts +102 -0
  14. package/dist/{for-angular/components/decaf-crud-form → lib/components/crud-form}/types.d.ts +0 -0
  15. package/dist/lib/components/model-renderer/model-renderer.component.d.ts +97 -0
  16. package/dist/lib/engine/DynamicModule.d.ts +17 -0
  17. package/dist/{for-angular → lib}/engine/NgxCrudFormField.d.ts +22 -14
  18. package/dist/lib/engine/NgxFormService.d.ts +167 -0
  19. package/dist/lib/engine/NgxRenderingEngine.d.ts +128 -0
  20. package/dist/lib/engine/NgxRenderingEngine2.d.ts +251 -0
  21. package/dist/lib/engine/ValidatorFactory.d.ts +15 -0
  22. package/dist/lib/engine/constants.d.ts +151 -0
  23. package/dist/lib/engine/decorators.d.ts +25 -0
  24. package/dist/lib/engine/index.d.ts +15 -0
  25. package/dist/lib/engine/types.d.ts +293 -0
  26. package/dist/lib/esm2022/components/component-renderer/component-renderer.component.mjs +309 -0
  27. package/dist/lib/esm2022/components/crud-field/crud-field.component.mjs +288 -0
  28. package/dist/lib/esm2022/components/crud-form/constants.mjs +14 -0
  29. package/dist/lib/esm2022/components/crud-form/crud-form.component.mjs +140 -0
  30. package/dist/lib/esm2022/components/crud-form/types.mjs +2 -0
  31. package/dist/lib/esm2022/components/model-renderer/model-renderer.component.mjs +137 -0
  32. package/dist/{for-angular → lib}/esm2022/decaf-ts-for-angular.mjs +0 -0
  33. package/dist/lib/esm2022/engine/DynamicModule.mjs +18 -0
  34. package/dist/lib/esm2022/engine/NgxCrudFormField.mjs +117 -0
  35. package/dist/lib/esm2022/engine/NgxFormService.mjs +315 -0
  36. package/dist/lib/esm2022/engine/NgxRenderingEngine.mjs +194 -0
  37. package/dist/lib/esm2022/engine/NgxRenderingEngine2.mjs +333 -0
  38. package/dist/lib/esm2022/engine/ValidatorFactory.mjs +102 -0
  39. package/dist/lib/esm2022/engine/constants.mjs +160 -0
  40. package/dist/lib/esm2022/engine/decorators.mjs +38 -0
  41. package/dist/lib/esm2022/engine/index.mjs +16 -0
  42. package/dist/lib/esm2022/engine/types.mjs +2 -0
  43. package/dist/lib/esm2022/for-angular.module.mjs +118 -0
  44. package/dist/lib/esm2022/interfaces.mjs +2 -0
  45. package/dist/lib/esm2022/public-apis.mjs +13 -0
  46. package/dist/lib/fesm2022/decaf-ts-for-angular.mjs +2138 -0
  47. package/dist/lib/fesm2022/decaf-ts-for-angular.mjs.map +1 -0
  48. package/dist/lib/for-angular.module.d.ts +44 -0
  49. package/dist/{for-angular → lib}/index.d.ts +0 -0
  50. package/dist/lib/interfaces.d.ts +28 -0
  51. package/dist/lib/public-apis.d.ts +12 -0
  52. package/package.json +73 -26
  53. package/dist/for-angular/README.md +0 -297
  54. package/dist/for-angular/assets/i18n/en.json +0 -21
  55. package/dist/for-angular/components/decaf-crud-field/decaf-crud-field.component.d.ts +0 -49
  56. package/dist/for-angular/components/decaf-crud-form/decaf-crud-form.component.d.ts +0 -28
  57. package/dist/for-angular/components/decaf-model-renderer/decaf-model-renderer.component.d.ts +0 -20
  58. package/dist/for-angular/engine/DynamicModule.d.ts +0 -2
  59. package/dist/for-angular/engine/NgxFormService.d.ts +0 -119
  60. package/dist/for-angular/engine/NgxRenderingEngine.d.ts +0 -18
  61. package/dist/for-angular/engine/ValidatorFactory.d.ts +0 -4
  62. package/dist/for-angular/engine/constants.d.ts +0 -13
  63. package/dist/for-angular/engine/decorators.d.ts +0 -1
  64. package/dist/for-angular/engine/index.d.ts +0 -5
  65. package/dist/for-angular/engine/types.d.ts +0 -44
  66. package/dist/for-angular/esm2022/components/decaf-crud-field/decaf-crud-field.component.mjs +0 -129
  67. package/dist/for-angular/esm2022/components/decaf-crud-form/constants.mjs +0 -14
  68. package/dist/for-angular/esm2022/components/decaf-crud-form/decaf-crud-form.component.mjs +0 -80
  69. package/dist/for-angular/esm2022/components/decaf-crud-form/types.mjs +0 -2
  70. package/dist/for-angular/esm2022/components/decaf-model-renderer/decaf-model-renderer.component.mjs +0 -47
  71. package/dist/for-angular/esm2022/engine/DynamicModule.mjs +0 -3
  72. package/dist/for-angular/esm2022/engine/NgxCrudFormField.mjs +0 -115
  73. package/dist/for-angular/esm2022/engine/NgxFormService.mjs +0 -235
  74. package/dist/for-angular/esm2022/engine/NgxRenderingEngine.mjs +0 -84
  75. package/dist/for-angular/esm2022/engine/ValidatorFactory.mjs +0 -48
  76. package/dist/for-angular/esm2022/engine/constants.mjs +0 -15
  77. package/dist/for-angular/esm2022/engine/decorators.mjs +0 -14
  78. package/dist/for-angular/esm2022/engine/index.mjs +0 -6
  79. package/dist/for-angular/esm2022/engine/types.mjs +0 -2
  80. package/dist/for-angular/esm2022/interfaces.mjs +0 -2
  81. package/dist/for-angular/esm2022/public-apis.mjs +0 -6
  82. package/dist/for-angular/fesm2022/decaf-ts-for-angular.mjs +0 -759
  83. package/dist/for-angular/fesm2022/decaf-ts-for-angular.mjs.map +0 -1
  84. package/dist/for-angular/interfaces.d.ts +0 -8
  85. package/dist/for-angular/public-apis.d.ts +0 -5
@@ -1,17 +1,18 @@
1
1
  import { FieldProperties } from '@decaf-ts/ui-decorators';
2
- import { FieldUpdateMode, PossibleInputTypes } from './types';
2
+ import { PossibleInputTypes } from './types';
3
3
  import { CrudOperations } from '@decaf-ts/db-decorators';
4
- import { ControlValueAccessor, FormGroup } from '@angular/forms';
4
+ import { ControlValueAccessor, FormControl, FormGroup } from '@angular/forms';
5
5
  import { ElementRef } from '@angular/core';
6
6
  /**
7
7
  * @class NgxCrudFormField
8
- * @implements {CrudFormField<AngularFieldDefinition>}
8
+ * @implements {FieldProperties}
9
9
  * @implements {ControlValueAccessor}
10
10
  * @summary Abstract class representing a CRUD form field for Angular applications
11
11
  * @description This class provides the base implementation for CRUD form fields in Angular,
12
12
  * implementing both CrudFormField and ControlValueAccessor interfaces.
13
13
  */
14
14
  export declare abstract class NgxCrudFormField implements ControlValueAccessor, FieldProperties {
15
+ protected elementRef: ElementRef;
15
16
  /**
16
17
  * @summary Reference to the component's element
17
18
  * @description ElementRef representing the component's native element
@@ -26,8 +27,11 @@ export declare abstract class NgxCrudFormField implements ControlValueAccessor,
26
27
  * @summary Form group for the field
27
28
  * @description Angular FormGroup instance for the field
28
29
  */
29
- formGroup: FormGroup;
30
+ formGroup: FormGroup | undefined;
31
+ formControl: FormControl;
30
32
  name: string;
33
+ path: string;
34
+ childOf?: string;
31
35
  type: PossibleInputTypes;
32
36
  disabled?: boolean;
33
37
  format?: string;
@@ -40,7 +44,14 @@ export declare abstract class NgxCrudFormField implements ControlValueAccessor,
40
44
  readonly?: boolean;
41
45
  required?: boolean;
42
46
  step?: number;
47
+ equals?: string;
48
+ different?: string;
49
+ lessThan?: string;
50
+ lessThanOrEqual?: string;
51
+ greaterThan?: string;
52
+ greaterThanOrEqual?: string;
43
53
  value: string | number | Date;
54
+ protected constructor(elementRef: ElementRef);
44
55
  /**
45
56
  * @summary Parent HTML element
46
57
  * @description Reference to the parent HTML element of the field
@@ -49,16 +60,19 @@ export declare abstract class NgxCrudFormField implements ControlValueAccessor,
49
60
  /**
50
61
  * @summary String formatting function
51
62
  * @description Provides access to the sf function for error message formatting
63
+ * @prop {function(string, ...string): string} sf - String formatting function
52
64
  */
53
65
  sf: typeof import("@decaf-ts/decorator-validation").stringFormat;
54
66
  /**
55
67
  * @summary Change callback function
56
68
  * @description Function called when the field value changes
69
+ * @property {function(): unknown} onChange - onChange event handler
57
70
  */
58
71
  onChange: () => unknown;
59
72
  /**
60
73
  * @summary Touch callback function
61
74
  * @description Function called when the field is touched
75
+ * @property {function(): unknown} onTouch - onTouch event handler
62
76
  */
63
77
  onTouch: () => unknown;
64
78
  /**
@@ -70,13 +84,13 @@ export declare abstract class NgxCrudFormField implements ControlValueAccessor,
70
84
  /**
71
85
  * @summary Register change callback
72
86
  * @description Registers a function to be called when the field value changes
73
- * @param {() => unknown} fn - The function to be called on change
87
+ * @param {function(): unknown} fn - The function to be called on change
74
88
  */
75
89
  registerOnChange(fn: () => unknown): void;
76
90
  /**
77
91
  * @summary Register touch callback
78
92
  * @description Registers a function to be called when the field is touched
79
- * @param {() => unknown} fn - The function to be called on touch
93
+ * @param {function(): unknown} fn - The function to be called on touch
80
94
  */
81
95
  registerOnTouched(fn: () => unknown): void;
82
96
  /**
@@ -96,18 +110,12 @@ export declare abstract class NgxCrudFormField implements ControlValueAccessor,
96
110
  * @description Unregisters the field when the component is destroyed
97
111
  */
98
112
  onDestroy(): void;
99
- /**
100
- * @summary Initialize the field
101
- * @description Sets up the form group and field name
102
- * @param {FieldUpdateMode} updateOn - The update mode for the field
103
- */
104
- onInit(updateOn: FieldUpdateMode): void;
105
113
  /**
106
114
  * @summary Get field errors
107
115
  * @description Retrieves all errors associated with the field
108
- * @returns {{key: string, message: string}[]} An array of error objects
116
+ * @returns {Array<{key: string, message: string}>} An array of error objects
109
117
  */
110
- getErrors(): {
118
+ getErrors(parent: HTMLElement): {
111
119
  key: string;
112
120
  message: string;
113
121
  }[];
@@ -0,0 +1,167 @@
1
+ import { FieldProperties } from '@decaf-ts/ui-decorators';
2
+ import { ComponentConfig, FieldUpdateMode } from './types';
3
+ import { AbstractControl, FormControl, FormGroup } from '@angular/forms';
4
+ /**
5
+ * @description Service for managing Angular forms and form controls.
6
+ * @summary The NgxFormService provides utility methods for creating, managing, and validating Angular forms and form controls. It includes functionality for registering forms, adding controls, validating fields, and handling form data.
7
+ *
8
+ * @class
9
+ * @param {WeakMap<AbstractControl, FieldProperties>} controls - A WeakMap to store control properties.
10
+ * @param {Map<string, FormGroup>} formRegistry - A Map to store registered forms.
11
+ *
12
+ * @example
13
+ * // Creating a form from components
14
+ * const components = [
15
+ * { inputs: { name: 'username', type: 'text', required: true } },
16
+ * { inputs: { name: 'password', type: 'password', minLength: 8 } }
17
+ * ];
18
+ * const form = NgxFormService.createFormFromComponents('loginForm', components, true);
19
+ *
20
+ * // Validating fields
21
+ * NgxFormService.validateFields(form);
22
+ *
23
+ * // Getting form data
24
+ * const formData = NgxFormService.getFormData(form);
25
+ *
26
+ * @mermaid
27
+ * sequenceDiagram
28
+ * participant C as Component
29
+ * participant NFS as NgxFormService
30
+ * participant AF as Angular Forms
31
+ * C->>NFS: createFormFromComponents()
32
+ * NFS->>AF: new FormGroup()
33
+ * NFS->>NFS: addFormControl()
34
+ * NFS->>AF: addControl()
35
+ * NFS-->>C: Return FormGroup
36
+ * C->>NFS: validateFields()
37
+ * NFS->>AF: markAsTouched(), markAsDirty(), updateValueAndValidity()
38
+ * C->>NFS: getFormData()
39
+ * NFS->>AF: Get control values
40
+ * NFS-->>C: Return form data
41
+ */
42
+ export declare class NgxFormService {
43
+ private static controls;
44
+ private static formRegistry;
45
+ /**
46
+ * @description Adds a form to the registry.
47
+ * @summary Registers a FormGroup with a unique identifier. Throws an error if the identifier is already in use.
48
+ * @param {string} formId - The unique identifier for the form.
49
+ * @param {FormGroup} formGroup - The FormGroup to be registered.
50
+ * @throws {Error} If a FormGroup with the given id is already registered.
51
+ */
52
+ static addRegistry(formId: string, formGroup: FormGroup): void;
53
+ /**
54
+ * @description Removes a form from the registry.
55
+ * @summary Deletes a FormGroup from the registry using its unique identifier.
56
+ * @param {string} formId - The unique identifier of the form to be removed.
57
+ */
58
+ static removeRegistry(formId: string): void;
59
+ /**
60
+ * @description Resolves the parent group and control name from a path.
61
+ * @summary Traverses the form group structure to find the parent group and control name for a given path.
62
+ * @param {FormGroup} formGroup - The root FormGroup.
63
+ * @param {string} path - The path to the control.
64
+ * @return {FormParentGroup} A tuple containing the parent FormGroup and the control name.
65
+ */
66
+ private static resolveParentGroup;
67
+ /**
68
+ * @description Adds a form control to a form group.
69
+ * @summary Creates and adds a form control to the specified form group based on the provided component properties.
70
+ * @param {FormGroup} formGroup - The form group to add the control to.
71
+ * @param {ComponentInput} componentProps - The properties of the component to create the control from.
72
+ */
73
+ private static addFormControl;
74
+ /**
75
+ * @description Retrieves a control from a registered form.
76
+ * @summary Finds and returns an AbstractControl from a registered form using the form id and optional path.
77
+ * @param {string} formId - The unique identifier of the form.
78
+ * @param {string} [path] - The path to the control within the form.
79
+ * @return {AbstractControl} The requested AbstractControl.
80
+ * @throws {Error} If the form is not found in the registry or the control is not found in the form.
81
+ */
82
+ static getControlFromForm(formId: string, path?: string): AbstractControl;
83
+ /**
84
+ * @description Creates a form from component configurations.
85
+ * @summary Generates a FormGroup based on an array of component configurations and optionally registers it.
86
+ * @param {string} id - The unique identifier for the form.
87
+ * @param {ComponentConfig[]} components - An array of component configurations.
88
+ * @param {boolean} [registry=false] - Whether to register the created form.
89
+ * @return {FormGroup} The created FormGroup.
90
+ */
91
+ static createFormFromComponents(id: string, components: ComponentConfig[], registry?: boolean): FormGroup;
92
+ /**
93
+ * @description Adds a control to a form based on component properties.
94
+ * @summary Creates and adds a form control to a form (existing or new) based on the provided component properties.
95
+ * @param {string} id - The unique identifier of the form.
96
+ * @param {FieldProperties} componentProperties - The properties of the component to create the control from.
97
+ * @return {AbstractControl} The form or created control.
98
+ */
99
+ static addControlFromProps(id: string, componentProperties: FieldProperties): AbstractControl;
100
+ /**
101
+ * @description Retrieves form data from a FormGroup.
102
+ * @summary Extracts and processes the data from a FormGroup, handling different input types and nested form groups.
103
+ * @param {FormGroup} formGroup - The FormGroup to extract data from.
104
+ * @return {Record<string, unknown>} An object containing the form data.
105
+ */
106
+ static getFormData(formGroup: FormGroup): Record<string, unknown>;
107
+ /**
108
+ * @description Validates fields in a form control or form group.
109
+ * @summary Recursively validates all fields in a form control or form group, marking them as touched and dirty.
110
+ * @param {AbstractControl} control - The control or form group to validate.
111
+ * @param {string} [path] - The path to the control within the form.
112
+ * @return {boolean} True if all fields are valid, false otherwise.
113
+ * @throws {Error} If no control is found at the specified path or if the control type is unknown.
114
+ */
115
+ static validateFields(control: AbstractControl, path?: string): boolean;
116
+ /**
117
+ * @description Generates validators from component properties.
118
+ * @summary Creates an array of ValidatorFn based on the supported validation keys in the component properties.
119
+ * @param {FieldProperties} props - The component properties.
120
+ * @return {ValidatorFn[]} An array of validator functions.
121
+ */
122
+ private static validatorsFromProps;
123
+ /**
124
+ * @description Creates a FormControl from component properties.
125
+ * @summary Generates a FormControl with validators based on the provided component properties.
126
+ * @param {FieldProperties} props - The component properties.
127
+ * @param {FieldUpdateMode} [updateMode='change'] - The update mode for the control.
128
+ * @return {FormControl} The created FormControl.
129
+ */
130
+ static fromProps(props: FieldProperties, updateMode?: FieldUpdateMode): FormControl;
131
+ /**
132
+ * @description Retrieves properties from a FormControl.
133
+ * @summary Gets the FieldProperties associated with a FormControl from the internal WeakMap.
134
+ * @param {FormControl} control - The FormControl to get properties for.
135
+ * @return {FieldProperties} The properties associated with the control.
136
+ */
137
+ static getPropsFromControl(control: FormControl): FieldProperties;
138
+ /**
139
+ * @description Finds a parent element with a specific tag.
140
+ * @summary Traverses up the DOM tree to find the nearest parent element with the specified tag.
141
+ * @param {HTMLElement} el - The starting element.
142
+ * @param {string} tag - The tag name to search for.
143
+ * @return {HTMLElement} The found parent element.
144
+ * @throws {Error} If no parent with the specified tag is found.
145
+ */
146
+ static getParentEl(el: HTMLElement, tag: string): HTMLElement;
147
+ /**
148
+ * @description Registers a control with its properties.
149
+ * @summary Associates a control with its properties in the internal WeakMap.
150
+ * @param {AbstractControl} control - The control to register.
151
+ * @param {FieldProperties} props - The properties to associate with the control.
152
+ */
153
+ static register(control: AbstractControl, props: FieldProperties): void;
154
+ /**
155
+ * @description Unregisters a control.
156
+ * @summary Removes a control and its associated properties from the internal WeakMap.
157
+ * @param {AbstractControl} control - The control to unregister.
158
+ * @return {boolean} True if the control was successfully unregistered, false otherwise.
159
+ */
160
+ static unregister(control: AbstractControl): boolean;
161
+ /**
162
+ * @description Resets a form group.
163
+ * @summary Recursively resets all controls in a form group, clearing values, errors, and marking them as pristine and untouched.
164
+ * @param {FormGroup} formGroup - The form group to reset.
165
+ */
166
+ static reset(formGroup: FormGroup): void;
167
+ }
@@ -0,0 +1,128 @@
1
+ import { RenderingEngine } from '@decaf-ts/ui-decorators';
2
+ import { AngularDynamicOutput, AngularFieldDefinition } from './types';
3
+ import { Constructor, Model } from '@decaf-ts/decorator-validation';
4
+ import { Injector, TemplateRef, ViewContainerRef } from '@angular/core';
5
+ /**
6
+ * @description Angular implementation of the RenderingEngine
7
+ * @summary This class extends the base RenderingEngine to provide Angular-specific rendering capabilities.
8
+ * It handles the conversion of field definitions to Angular components and manages component registration.
9
+ * @template AngularFieldDefinition - Type for Angular-specific field definitions
10
+ * @template AngularDynamicOutput - Type for Angular-specific component output
11
+ * @param {Injector} injector - Angular injector for dependency injection
12
+ * @param {ViewContainerRef} vcr - View container reference for component creation
13
+ * @param {TemplateRef<any>} tpl - Template reference for content projection
14
+ * @class NgxRenderingEngine
15
+ * @example
16
+ * ```typescript
17
+ * const engine = new NgxRenderingEngine();
18
+ * engine.initialize();
19
+ * const output = engine.render(myModel, {}, viewContainerRef, injector, templateRef);
20
+ * ```
21
+ * @mermaid
22
+ * sequenceDiagram
23
+ * participant Client
24
+ * participant Engine as NgxRenderingEngine
25
+ * participant Components as RegisteredComponents
26
+ *
27
+ * Client->>Engine: new NgxRenderingEngine()
28
+ * Client->>Engine: initialize()
29
+ * Client->>Engine: render(model, props, vcr, injector, tpl)
30
+ * Engine->>Engine: toFieldDefinition(model, props)
31
+ * Engine->>Engine: fromFieldDefinition(fieldDef, vcr, injector, tpl)
32
+ * Engine->>Components: components(fieldDef.tag)
33
+ * Components-->>Engine: component constructor
34
+ * Engine->>Client: return AngularDynamicOutput
35
+ */
36
+ export declare class NgxRenderingEngine extends RenderingEngine<AngularFieldDefinition, AngularDynamicOutput> {
37
+ private static _components;
38
+ constructor();
39
+ /**
40
+ * @description Converts a field definition to an Angular component output
41
+ * @summary This private method takes a field definition and creates the corresponding Angular component.
42
+ * It handles component instantiation, input property mapping, and child component rendering.
43
+ * @param {FieldDefinition<AngularFieldDefinition>} fieldDef - The field definition to convert
44
+ * @param {ViewContainerRef} vcr - The view container reference for component creation
45
+ * @param {Injector} injector - The Angular injector for dependency injection
46
+ * @param {TemplateRef<any>} tpl - The template reference for content projection
47
+ * @return {AngularDynamicOutput} The Angular component output with component reference and inputs
48
+ * @mermaid
49
+ * sequenceDiagram
50
+ * participant Method as fromFieldDefinition
51
+ * participant Components as NgxRenderingEngine.components
52
+ * participant Angular as Angular Core
53
+ *
54
+ * Method->>Components: components(fieldDef.tag)
55
+ * Components-->>Method: component constructor
56
+ * Method->>Angular: reflectComponentType(component)
57
+ * Angular-->>Method: componentMetadata
58
+ * Method->>Method: Check input properties
59
+ * Method->>Method: Create result object
60
+ * Method->>Method: Process children if any
61
+ * Method-->>Caller: return AngularDynamicOutput
62
+ */
63
+ private fromFieldDefinition;
64
+ /**
65
+ * @description Renders a model into an Angular component output
66
+ * @summary This method takes a model and converts it to an Angular component output.
67
+ * It first converts the model to a field definition using the base RenderingEngine's
68
+ * toFieldDefinition method, then converts that field definition to an Angular component output.
69
+ * @template M - Type extending Model
70
+ * @param {M} model - The model to render
71
+ * @param {Record<string, unknown>} globalProps - Global properties to pass to the component
72
+ * @param {ViewContainerRef} vcr - The view container reference for component creation
73
+ * @param {Injector} injector - The Angular injector for dependency injection
74
+ * @param {TemplateRef<any>} tpl - The template reference for content projection
75
+ * @return {AngularDynamicOutput} The Angular component output with component reference and inputs
76
+ * @mermaid
77
+ * sequenceDiagram
78
+ * participant Client as Client Code
79
+ * participant Render as render method
80
+ * participant ToField as toFieldDefinition
81
+ * participant FromField as fromFieldDefinition
82
+ *
83
+ * Client->>Render: render(model, globalProps, vcr, injector, tpl)
84
+ * Render->>ToField: toFieldDefinition(model, globalProps)
85
+ * ToField-->>Render: fieldDef
86
+ * Render->>FromField: fromFieldDefinition(fieldDef, vcr, injector, tpl)
87
+ * FromField-->>Render: AngularDynamicOutput
88
+ * Render-->>Client: return AngularDynamicOutput
89
+ */
90
+ render<M extends Model>(model: M, globalProps: Record<string, unknown>, vcr: ViewContainerRef, injector: Injector, tpl: TemplateRef<any>): AngularDynamicOutput;
91
+ /**
92
+ * @description Initializes the rendering engine
93
+ * @summary This method initializes the rendering engine. It checks if the engine is already initialized
94
+ * and sets the initialized flag to true. This method is called before the engine is used.
95
+ * @param {...any[]} args - Initialization arguments
96
+ * @return {Promise<void>} A promise that resolves when initialization is complete
97
+ */
98
+ initialize(...args: any[]): Promise<void>;
99
+ /**
100
+ * @description Registers a component with the rendering engine
101
+ * @summary This static method registers a component constructor with the rendering engine
102
+ * under a specific name. It throws an error if a component is already registered under the same name.
103
+ * @param {string} name - The name to register the component under
104
+ * @param {Constructor<unknown>} constructor - The component constructor
105
+ * @return {void}
106
+ */
107
+ static registerComponent(name: string, constructor: Constructor<unknown>): void;
108
+ /**
109
+ * @description Retrieves registered components from the rendering engine
110
+ * @summary This static method retrieves either all registered components or a specific component
111
+ * by its selector. It throws an error if the requested component is not registered.
112
+ * @param {string} [selector] - Optional selector to retrieve a specific component
113
+ * @return {Object|Array} Either a specific component or an array of all components
114
+ */
115
+ static components(selector?: string): {
116
+ constructor: Constructor<unknown>;
117
+ } | {
118
+ constructor: Constructor<unknown>;
119
+ }[];
120
+ /**
121
+ * @description Generates a key for reflection metadata
122
+ * @summary This static method generates a key for reflection metadata by prefixing the input key
123
+ * with the Angular engine's reflection prefix. This is used for storing and retrieving metadata.
124
+ * @param {string} key - The base key to prefix
125
+ * @return {string} The prefixed key for reflection metadata
126
+ */
127
+ static key(key: string): string;
128
+ }
@@ -0,0 +1,251 @@
1
+ import { FieldDefinition, RenderingEngine } from '@decaf-ts/ui-decorators';
2
+ import { AngularDynamicOutput, AngularFieldDefinition, KeyValue } from './types';
3
+ import { Constructor, Model } from '@decaf-ts/decorator-validation';
4
+ import { ComponentMirror, ComponentRef, Injector, TemplateRef, Type, ViewContainerRef } from '@angular/core';
5
+ /**
6
+ * @description Angular implementation of the RenderingEngine with enhanced features
7
+ * @summary This class extends the base RenderingEngine to provide Angular-specific rendering capabilities
8
+ * with additional features compared to NgxRenderingEngine. It handles the conversion of field definitions
9
+ * to Angular components, manages component registration, and provides utilities for component creation
10
+ * and input handling. This implementation uses Angular's newer component APIs.
11
+ *
12
+ * @template AngularFieldDefinition - Type for Angular-specific field definitions
13
+ * @template AngularDynamicOutput - Type for Angular-specific component output
14
+ *
15
+ * @class NgxRenderingEngine2
16
+ * @example
17
+ * ```typescript
18
+ * const engine = NgxRenderingEngine2.get();
19
+ * engine.initialize();
20
+ * const output = engine.render(myModel, {}, viewContainerRef, injector, templateRef);
21
+ * ```
22
+ *
23
+ * @mermaid
24
+ * sequenceDiagram
25
+ * participant Client
26
+ * participant Engine as NgxRenderingEngine2
27
+ * participant Components as RegisteredComponents
28
+ *
29
+ * Client->>Engine: get()
30
+ * Client->>Engine: initialize()
31
+ * Client->>Engine: render(model, props, vcr, injector, tpl)
32
+ * Engine->>Engine: toFieldDefinition(model, props)
33
+ * Engine->>Engine: fromFieldDefinition(fieldDef, vcr, injector, tpl)
34
+ * Engine->>Components: components(fieldDef.tag)
35
+ * Components-->>Engine: component constructor
36
+ * Engine->>Engine: createComponent(component, inputs, metadata, vcr, injector, template)
37
+ * Engine-->>Client: return AngularDynamicOutput
38
+ */
39
+ export declare class NgxRenderingEngine2 extends RenderingEngine<AngularFieldDefinition, AngularDynamicOutput> {
40
+ /**
41
+ * @description Registry of registered components
42
+ * @summary Static registry that maps component names to their constructors.
43
+ * This allows the engine to look up components by name when rendering.
44
+ * @type {Record<string, { constructor: Constructor<unknown> }>}
45
+ */
46
+ private static _components;
47
+ /**
48
+ * @description Collection of child component outputs
49
+ * @summary Stores the outputs of child components during rendering.
50
+ * @type {AngularDynamicOutput[]}
51
+ */
52
+ private _childs;
53
+ /**
54
+ * @description Current model being rendered
55
+ * @summary Reference to the model currently being processed by the rendering engine.
56
+ * @type {Model}
57
+ */
58
+ private _model;
59
+ /**
60
+ * @description Static reference to the current instance
61
+ * @summary Singleton instance reference for the rendering engine.
62
+ * @type {Type<unknown> | undefined}
63
+ */
64
+ private static _instance;
65
+ /**
66
+ * @description Creates a new instance of NgxRenderingEngine2
67
+ * @summary Initializes the rendering engine with the 'angular' engine type.
68
+ * This constructor sets up the base configuration needed for Angular-specific rendering.
69
+ */
70
+ constructor();
71
+ /**
72
+ * @description Converts a field definition to an Angular component output
73
+ * @summary This private method takes a field definition and creates the corresponding Angular component.
74
+ * It handles component instantiation, input property mapping, and child component rendering.
75
+ * The method validates input properties against the component's metadata and processes
76
+ * child components recursively.
77
+ *
78
+ * @param {FieldDefinition<AngularFieldDefinition>} fieldDef - The field definition to convert
79
+ * @param {ViewContainerRef} vcr - The view container reference for component creation
80
+ * @param {Injector} injector - The Angular injector for dependency injection
81
+ * @param {TemplateRef<any>} tpl - The template reference for content projection
82
+ * @param {string} registryFormId - Form identifier for the component renderer
83
+ * @return {AngularDynamicOutput} The Angular component output with component reference and inputs
84
+ *
85
+ * @mermaid
86
+ * sequenceDiagram
87
+ * participant Method as fromFieldDefinition
88
+ * participant Components as NgxRenderingEngine2.components
89
+ * participant Angular as Angular Core
90
+ * participant Process as processChild
91
+ *
92
+ * Method->>Components: components(fieldDef.tag)
93
+ * Components-->>Method: component constructor
94
+ * Method->>Angular: reflectComponentType(component)
95
+ * Angular-->>Method: componentMetadata
96
+ * Method->>Method: Validate input properties
97
+ * Method->>Method: Create result object
98
+ * alt Has children
99
+ * Method->>Process: Process children recursively
100
+ * Process->>Method: Return processed children
101
+ * Method->>Angular: Create embedded view
102
+ * Method->>Method: Create component instance
103
+ * end
104
+ * Method-->>Caller: return AngularDynamicOutput
105
+ */
106
+ private fromFieldDefinition;
107
+ /**
108
+ * @description Creates an Angular component instance
109
+ * @summary This static utility method creates an Angular component instance with the specified
110
+ * inputs and template. It uses Angular's component creation API to instantiate the component
111
+ * and then sets the input properties using the provided metadata.
112
+ *
113
+ * @param {Type<unknown>} component - The component type to create
114
+ * @param {KeyValue} [inputs={}] - The input properties to set on the component
115
+ * @param {ComponentMirror<unknown>} metadata - The component metadata for input validation
116
+ * @param {ViewContainerRef} vcr - The view container reference for component creation
117
+ * @param {Injector} injector - The Angular injector for dependency injection
118
+ * @param {any} [template=[]] - The template nodes to project into the component
119
+ * @return {ComponentRef<unknown>} The created component reference
120
+ */
121
+ static createComponent(component: Type<unknown>, inputs: KeyValue | undefined, metadata: ComponentMirror<unknown>, vcr: ViewContainerRef, injector: Injector, template?: any): ComponentRef<unknown>;
122
+ /**
123
+ * @description Extracts decorator metadata from a model
124
+ * @summary This method provides access to the field definition generated from a model's
125
+ * decorators. It's a convenience wrapper around the toFieldDefinition method that
126
+ * converts a model to a field definition based on its decorators and the provided
127
+ * global properties.
128
+ *
129
+ * @param {Model} model - The model to extract decorators from
130
+ * @param {Record<string, unknown>} globalProps - Global properties to include in the field definition
131
+ * @return {FieldDefinition<AngularFieldDefinition>} The field definition generated from the model
132
+ */
133
+ getDecorators(model: Model, globalProps: Record<string, unknown>): FieldDefinition<AngularFieldDefinition>;
134
+ /**
135
+ * @description Destroys the current engine instance
136
+ * @summary This static method clears the current instance reference, effectively
137
+ * destroying the singleton instance of the rendering engine. This can be used
138
+ * to reset the engine state or to prepare for a new instance creation.
139
+ *
140
+ * @return {Promise<void>} A promise that resolves when the instance is destroyed
141
+ */
142
+ static destroy(): Promise<void>;
143
+ /**
144
+ * @description Renders a model into an Angular component output
145
+ * @summary This method takes a model and converts it to an Angular component output.
146
+ * It first stores a reference to the model, then converts it to a field definition
147
+ * using the base RenderingEngine's toFieldDefinition method, and finally converts
148
+ * that field definition to an Angular component output using fromFieldDefinition.
149
+ *
150
+ * @template M - Type extending Model
151
+ * @param {M} model - The model to render
152
+ * @param {Record<string, unknown>} globalProps - Global properties to pass to the component
153
+ * @param {ViewContainerRef} vcr - The view container reference for component creation
154
+ * @param {Injector} injector - The Angular injector for dependency injection
155
+ * @param {TemplateRef<any>} tpl - The template reference for content projection
156
+ * @return {AngularDynamicOutput} The Angular component output with component reference and inputs
157
+ *
158
+ * @mermaid
159
+ * sequenceDiagram
160
+ * participant Client as Client Code
161
+ * participant Render as render method
162
+ * participant ToField as toFieldDefinition
163
+ * participant FromField as fromFieldDefinition
164
+ *
165
+ * Client->>Render: render(model, globalProps, vcr, injector, tpl)
166
+ * Render->>Render: Store model reference
167
+ * Render->>ToField: toFieldDefinition(model, globalProps)
168
+ * ToField-->>Render: fieldDef
169
+ * Render->>FromField: fromFieldDefinition(fieldDef, vcr, injector, tpl)
170
+ * FromField-->>Render: AngularDynamicOutput
171
+ * Render-->>Client: return AngularDynamicOutput
172
+ */
173
+ render<M extends Model>(model: M, globalProps: Record<string, unknown>, vcr: ViewContainerRef, injector: Injector, tpl: TemplateRef<any>): AngularDynamicOutput;
174
+ /**
175
+ * @description Initializes the rendering engine
176
+ * @summary This method initializes the rendering engine. It checks if the engine is already initialized
177
+ * and sets the initialized flag to true. This method is called before the engine is used
178
+ * to ensure it's properly set up for rendering operations.
179
+ *
180
+ * @param {...any[]} args - Initialization arguments
181
+ * @return {Promise<void>} A promise that resolves when initialization is complete
182
+ */
183
+ initialize(...args: any[]): Promise<void>;
184
+ /**
185
+ * @description Registers a component with the rendering engine
186
+ * @summary This static method registers a component constructor with the rendering engine
187
+ * under a specific name. It initializes the components registry if needed and throws
188
+ * an error if a component is already registered under the same name to prevent
189
+ * accidental overrides.
190
+ *
191
+ * @param {string} name - The name to register the component under
192
+ * @param {Constructor<unknown>} constructor - The component constructor
193
+ * @return {void}
194
+ */
195
+ static registerComponent(name: string, constructor: Constructor<unknown>): void;
196
+ /**
197
+ * @description Retrieves registered components from the rendering engine
198
+ * @summary This static method retrieves either all registered components or a specific component
199
+ * by its selector. When called without a selector, it returns an array of all registered
200
+ * components. When called with a selector, it returns the specific component if found,
201
+ * or throws an error if the component is not registered.
202
+ *
203
+ * @param {string} [selector] - Optional selector to retrieve a specific component
204
+ * @return {Object|Array} Either a specific component or an array of all components
205
+ */
206
+ static components(selector?: string): object | any[];
207
+ /**
208
+ * @description Generates a key for reflection metadata
209
+ * @summary This static method generates a key for reflection metadata by prefixing the input key
210
+ * with the Angular engine's reflection prefix. This is used for storing and retrieving
211
+ * metadata in a namespaced way to avoid conflicts with other metadata.
212
+ *
213
+ * @param {string} key - The base key to prefix
214
+ * @return {string} The prefixed key for reflection metadata
215
+ */
216
+ static key(key: string): string;
217
+ /**
218
+ * @description Sets input properties on a component instance
219
+ * @summary This static utility method sets input properties on a component instance
220
+ * based on the provided inputs object and component metadata. It handles both simple
221
+ * values and nested objects, recursively processing object properties. The method
222
+ * validates each input against the component's metadata to ensure only valid inputs
223
+ * are set.
224
+ *
225
+ * @param {ComponentRef<unknown>} component - The component reference to set inputs on
226
+ * @param {KeyValue} inputs - The input properties to set
227
+ * @param {ComponentMirror<unknown>} metadata - The component metadata for input validation
228
+ * @return {void}
229
+ *
230
+ * @mermaid
231
+ * sequenceDiagram
232
+ * participant Caller
233
+ * participant SetInputs as setInputs
234
+ * participant Parse as parseInputValue
235
+ * participant Component as ComponentRef
236
+ *
237
+ * Caller->>SetInputs: setInputs(component, inputs, metadata)
238
+ * SetInputs->>SetInputs: Iterate through inputs
239
+ * loop For each input
240
+ * SetInputs->>SetInputs: Check if input exists in metadata
241
+ * alt Input is 'props'
242
+ * SetInputs->>Parse: parseInputValue(component, value)
243
+ * Parse->>Parse: Recursively process nested objects
244
+ * Parse->>Component: setInput(key, value)
245
+ * else Input is valid
246
+ * SetInputs->>Component: setInput(key, value)
247
+ * end
248
+ * end
249
+ */
250
+ static setInputs(component: ComponentRef<unknown>, inputs: KeyValue, metadata: ComponentMirror<unknown>): void;
251
+ }
@@ -0,0 +1,15 @@
1
+ import { AbstractControl, ValidatorFn } from '@angular/forms';
2
+ import { PathProxy } from '@decaf-ts/decorator-validation';
3
+ import { FieldProperties } from '@decaf-ts/ui-decorators';
4
+ export declare class ValidatorFactory {
5
+ static spawn(fieldProps: FieldProperties, key: string): ValidatorFn;
6
+ /**
7
+ * @summary Creates a proxy wrapper for an Angular AbstractControl to assist with custom validation logic.
8
+ * @description Returns a structured proxy object that simulates a hierarchical tree of form values.
9
+ * Enables Validators handling method to access parent and child properties using consistent dot-notation in Angular forms.
10
+ *
11
+ * @param {AbstractControl} control - The control to wrap in a proxy.
12
+ * @returns {PathProxy<any>} A proxy object exposing form values and enabling recursive parent access.
13
+ */
14
+ static createProxy(control: AbstractControl): PathProxy<any>;
15
+ }