@ngx-formbar/core 0.11.0

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 (201) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +42 -0
  3. package/fesm2022/ngx-formbar-core.mjs +2429 -0
  4. package/fesm2022/ngx-formbar-core.mjs.map +1 -0
  5. package/index.d.ts +5 -0
  6. package/lib/components/form/ngxfb-form.component.d.ts +28 -0
  7. package/lib/composables/computed-value.d.ts +8 -0
  8. package/lib/composables/disabled.state.d.ts +36 -0
  9. package/lib/composables/dynamic-label.d.ts +9 -0
  10. package/lib/composables/dynamic-title.d.ts +9 -0
  11. package/lib/composables/hidden.state.d.ts +68 -0
  12. package/lib/composables/readonly.state.d.ts +19 -0
  13. package/lib/composables/testId.d.ts +16 -0
  14. package/lib/composables/update-strategy.d.ts +20 -0
  15. package/lib/composables/validators.d.ts +22 -0
  16. package/lib/config/config.d.ts +7 -0
  17. package/lib/config/provide-formbar.d.ts +38 -0
  18. package/lib/directives/ngxfb-abstract-control.directive.d.ts +53 -0
  19. package/lib/directives/ngxfb-block.directive.d.ts +124 -0
  20. package/lib/directives/ngxfb-control.directive.d.ts +203 -0
  21. package/lib/directives/ngxfb-group.directive.d.ts +253 -0
  22. package/lib/helper/control-container-view-providers.d.ts +33 -0
  23. package/lib/index.d.ts +23 -0
  24. package/lib/services/component-registration.service.d.ts +8 -0
  25. package/lib/services/configuration.service.d.ts +8 -0
  26. package/lib/services/expression.service.d.ts +148 -0
  27. package/lib/services/form.service.d.ts +10 -0
  28. package/lib/services/validator-registration.service.d.ts +10 -0
  29. package/lib/tokens/component-registrations.d.ts +2 -0
  30. package/lib/tokens/component-resolver.d.ts +3 -0
  31. package/lib/tokens/default-update-strategy.d.ts +3 -0
  32. package/lib/tokens/global-config.d.ts +5 -0
  33. package/lib/tokens/validator-registrations.d.ts +8 -0
  34. package/lib/tokens/validator-resolver.d.ts +3 -0
  35. package/lib/types/component-resolver.type.d.ts +4 -0
  36. package/lib/types/content.type.d.ts +137 -0
  37. package/lib/types/expression.type.d.ts +2 -0
  38. package/lib/types/form.type.d.ts +4 -0
  39. package/lib/types/functions.type.d.ts +4 -0
  40. package/lib/types/global-configuration.type.d.ts +4 -0
  41. package/lib/types/provide.type.d.ts +42 -0
  42. package/lib/types/registration.type.d.ts +18 -0
  43. package/lib/types/validation.type.d.ts +59 -0
  44. package/lib/types/validator-resolver.type.d.ts +6 -0
  45. package/package.json +52 -0
  46. package/public-api.d.ts +1 -0
  47. package/schematics/block/files/__componentName@dasherize__.component.html.template +1 -0
  48. package/schematics/block/files/__componentName@dasherize__.component.ts.template +29 -0
  49. package/schematics/block/files/__interfaceName@dasherize__.type.ts.template +6 -0
  50. package/schematics/block/index.d.ts +3 -0
  51. package/schematics/block/index.js +11 -0
  52. package/schematics/block/index.js.map +1 -0
  53. package/schematics/block/schema.json +62 -0
  54. package/schematics/collection.json +31 -0
  55. package/schematics/control/files/__componentName@dasherize__.component.html.template +0 -0
  56. package/schematics/control/files/__componentName@dasherize__.component.ts.template +29 -0
  57. package/schematics/control/files/__interfaceName@dasherize__.type.ts.template +6 -0
  58. package/schematics/control/index.d.ts +3 -0
  59. package/schematics/control/index.js +11 -0
  60. package/schematics/control/index.js.map +1 -0
  61. package/schematics/control/schema.json +61 -0
  62. package/schematics/group/files/__componentName@dasherize__.component.html.template +5 -0
  63. package/schematics/group/files/__componentName@dasherize__.component.ts.template +29 -0
  64. package/schematics/group/files/__interfaceName@dasherize__.type.ts.template +5 -0
  65. package/schematics/group/index.d.ts +3 -0
  66. package/schematics/group/index.js +11 -0
  67. package/schematics/group/index.js.map +1 -0
  68. package/schematics/group/schema.json +62 -0
  69. package/schematics/ng-add/files/config-registrations/async-validator-registrations.ts.template +4 -0
  70. package/schematics/ng-add/files/config-registrations/component-registrations.ts.template +4 -0
  71. package/schematics/ng-add/files/config-registrations/index.ts.template +3 -0
  72. package/schematics/ng-add/files/config-registrations/validator-registrations.ts.template +4 -0
  73. package/schematics/ng-add/files/helper/block.host-directive.ts.template +6 -0
  74. package/schematics/ng-add/files/helper/control.host-directive.ts.template +6 -0
  75. package/schematics/ng-add/files/helper/group.host-directive.ts.template +6 -0
  76. package/schematics/ng-add/files/helper/index.ts.template +4 -0
  77. package/schematics/ng-add/files/helper/view-provider.ts.template +9 -0
  78. package/schematics/ng-add/files/provider-config/config/__providerConfigFileName__.ts.template +9 -0
  79. package/schematics/ng-add/files/provider-config/inline/__providerConfigFileName__.ts.template +8 -0
  80. package/schematics/ng-add/files/provider-config/token/__providerConfigFileName__.ts.template +4 -0
  81. package/schematics/ng-add/files/schematics-config/__schematicConfigFileName__.json.template +1 -0
  82. package/schematics/ng-add/files/token-registrations/async-validator-registrations.ts.template +8 -0
  83. package/schematics/ng-add/files/token-registrations/component-registrations.ts.template +8 -0
  84. package/schematics/ng-add/files/token-registrations/index.ts.template +3 -0
  85. package/schematics/ng-add/files/token-registrations/validator-registrations.ts.template +8 -0
  86. package/schematics/ng-add/helper.d.ts +11 -0
  87. package/schematics/ng-add/helper.js +198 -0
  88. package/schematics/ng-add/helper.js.map +1 -0
  89. package/schematics/ng-add/index.d.ts +3 -0
  90. package/schematics/ng-add/index.js +68 -0
  91. package/schematics/ng-add/index.js.map +1 -0
  92. package/schematics/ng-add/rules/create-config-registration-files.rule.d.ts +3 -0
  93. package/schematics/ng-add/rules/create-config-registration-files.rule.js +32 -0
  94. package/schematics/ng-add/rules/create-config-registration-files.rule.js.map +1 -0
  95. package/schematics/ng-add/rules/create-formbar-registration-config.rule.d.ts +3 -0
  96. package/schematics/ng-add/rules/create-formbar-registration-config.rule.js +30 -0
  97. package/schematics/ng-add/rules/create-formbar-registration-config.rule.js.map +1 -0
  98. package/schematics/ng-add/rules/create-helper-files.rule.d.ts +6 -0
  99. package/schematics/ng-add/rules/create-helper-files.rule.js +22 -0
  100. package/schematics/ng-add/rules/create-helper-files.rule.js.map +1 -0
  101. package/schematics/ng-add/rules/create-schematics-config.rule.d.ts +3 -0
  102. package/schematics/ng-add/rules/create-schematics-config.rule.js +42 -0
  103. package/schematics/ng-add/rules/create-schematics-config.rule.js.map +1 -0
  104. package/schematics/ng-add/rules/create-token-registration-files.rule.d.ts +3 -0
  105. package/schematics/ng-add/rules/create-token-registration-files.rule.js +32 -0
  106. package/schematics/ng-add/rules/create-token-registration-files.rule.js.map +1 -0
  107. package/schematics/ng-add/rules/include-templates.rule.d.ts +3 -0
  108. package/schematics/ng-add/rules/include-templates.rule.js +11 -0
  109. package/schematics/ng-add/rules/include-templates.rule.js.map +1 -0
  110. package/schematics/ng-add/rules/install-dependencies.rule.d.ts +2 -0
  111. package/schematics/ng-add/rules/install-dependencies.rule.js +12 -0
  112. package/schematics/ng-add/rules/install-dependencies.rule.js.map +1 -0
  113. package/schematics/ng-add/rules/update-app-config.rule.d.ts +3 -0
  114. package/schematics/ng-add/rules/update-app-config.rule.js +48 -0
  115. package/schematics/ng-add/rules/update-app-config.rule.js.map +1 -0
  116. package/schematics/ng-add/rules/update-schematics-config.rule.d.ts +6 -0
  117. package/schematics/ng-add/rules/update-schematics-config.rule.js +28 -0
  118. package/schematics/ng-add/rules/update-schematics-config.rule.js.map +1 -0
  119. package/schematics/ng-add/schema.d.ts +23 -0
  120. package/schematics/ng-add/schema.js +3 -0
  121. package/schematics/ng-add/schema.js.map +1 -0
  122. package/schematics/ng-add/schema.json +81 -0
  123. package/schematics/register/component-info.type.d.ts +11 -0
  124. package/schematics/register/component-info.type.js +3 -0
  125. package/schematics/register/component-info.type.js.map +1 -0
  126. package/schematics/register/discover-components.d.ts +19 -0
  127. package/schematics/register/discover-components.js +267 -0
  128. package/schematics/register/discover-components.js.map +1 -0
  129. package/schematics/register/index.d.ts +3 -0
  130. package/schematics/register/index.js +49 -0
  131. package/schematics/register/index.js.map +1 -0
  132. package/schematics/register/register-components.d.ts +3 -0
  133. package/schematics/register/register-components.js +38 -0
  134. package/schematics/register/register-components.js.map +1 -0
  135. package/schematics/register/schema.d.ts +14 -0
  136. package/schematics/register/schema.js +3 -0
  137. package/schematics/register/schema.js.map +1 -0
  138. package/schematics/register/schema.json +44 -0
  139. package/schematics/shared/ast/decorators.d.ts +9 -0
  140. package/schematics/shared/ast/decorators.js +182 -0
  141. package/schematics/shared/ast/decorators.js.map +1 -0
  142. package/schematics/shared/ast/imports.d.ts +3 -0
  143. package/schematics/shared/ast/imports.js +93 -0
  144. package/schematics/shared/ast/imports.js.map +1 -0
  145. package/schematics/shared/ast/parse.d.ts +3 -0
  146. package/schematics/shared/ast/parse.js +17 -0
  147. package/schematics/shared/ast/parse.js.map +1 -0
  148. package/schematics/shared/ast/registrations.d.ts +22 -0
  149. package/schematics/shared/ast/registrations.js +654 -0
  150. package/schematics/shared/ast/registrations.js.map +1 -0
  151. package/schematics/shared/ast/types.d.ts +3 -0
  152. package/schematics/shared/ast/types.js +58 -0
  153. package/schematics/shared/ast/types.js.map +1 -0
  154. package/schematics/shared/file.d.ts +4 -0
  155. package/schematics/shared/file.js +60 -0
  156. package/schematics/shared/file.js.map +1 -0
  157. package/schematics/shared/helper.d.ts +2 -0
  158. package/schematics/shared/helper.js +29 -0
  159. package/schematics/shared/helper.js.map +1 -0
  160. package/schematics/shared/rules/create-component.rule.d.ts +3 -0
  161. package/schematics/shared/rules/create-component.rule.js +15 -0
  162. package/schematics/shared/rules/create-component.rule.js.map +1 -0
  163. package/schematics/shared/rules/register-control.rule.d.ts +3 -0
  164. package/schematics/shared/rules/register-control.rule.js +30 -0
  165. package/schematics/shared/rules/register-control.rule.js.map +1 -0
  166. package/schematics/shared/rules/register-type-map.rule.d.ts +3 -0
  167. package/schematics/shared/rules/register-type-map.rule.js +46 -0
  168. package/schematics/shared/rules/register-type-map.rule.js.map +1 -0
  169. package/schematics/shared/rules/register-type-token.rule.d.ts +3 -0
  170. package/schematics/shared/rules/register-type-token.rule.js +49 -0
  171. package/schematics/shared/rules/register-type-token.rule.js.map +1 -0
  172. package/schematics/shared/rules/scaffold-and-register.rule.d.ts +3 -0
  173. package/schematics/shared/rules/scaffold-and-register.rule.js +134 -0
  174. package/schematics/shared/rules/scaffold-and-register.rule.js.map +1 -0
  175. package/schematics/shared/schema.d.ts +32 -0
  176. package/schematics/shared/schema.js +3 -0
  177. package/schematics/shared/schema.js.map +1 -0
  178. package/schematics/tests/generators.spec.d.ts +1 -0
  179. package/schematics/tests/generators.spec.js +450 -0
  180. package/schematics/tests/generators.spec.js.map +1 -0
  181. package/schematics/tests/helper.d.ts +20 -0
  182. package/schematics/tests/helper.js +275 -0
  183. package/schematics/tests/helper.js.map +1 -0
  184. package/schematics/tests/ng-add.spec.d.ts +1 -0
  185. package/schematics/tests/ng-add.spec.js +380 -0
  186. package/schematics/tests/ng-add.spec.js.map +1 -0
  187. package/schematics/tests/register.spec.d.ts +1 -0
  188. package/schematics/tests/register.spec.js +340 -0
  189. package/schematics/tests/register.spec.js.map +1 -0
  190. package/schematics/tests/workspace-setup.d.ts +21 -0
  191. package/schematics/tests/workspace-setup.js +255 -0
  192. package/schematics/tests/workspace-setup.js.map +1 -0
  193. package/shared/ast.d.ts +10 -0
  194. package/shared/ast.js +93 -0
  195. package/shared/ast.js.map +1 -0
  196. package/shared/constants.d.ts +16 -0
  197. package/shared/constants.js +20 -0
  198. package/shared/constants.js.map +1 -0
  199. package/shared/shared-config.type.d.ts +20 -0
  200. package/shared/shared-config.type.js +3 -0
  201. package/shared/shared-config.type.js.map +1 -0
@@ -0,0 +1,137 @@
1
+ import { Expression } from './expression.type';
2
+ /**
3
+ * The foundation for all form controls and groups. It defines a common set of options
4
+ * that control registration, validation, visibility, and behavior of the form elements.
5
+ */
6
+ export interface NgxFbBaseContent {
7
+ /**
8
+ * Specifies the kind of form control. Determines what control is used and what
9
+ * additional properties are available.
10
+ */
11
+ type: string;
12
+ /**
13
+ * A string expression that determines when the control should be hidden.
14
+ * This condition is evaluated at runtime against the whole form object.
15
+ */
16
+ hidden?: Expression<boolean>;
17
+ }
18
+ /**
19
+ * Extends the base content with validation and control state management properties.
20
+ * Used as a base for both form controls and groups.
21
+ */
22
+ export interface NgxFbAbstractControl extends NgxFbBaseContent {
23
+ /**
24
+ * Array of strings representing names of synchronous validators that apply to the control.
25
+ * These can be registered globally with a validator registration object.
26
+ */
27
+ validators?: string[];
28
+ /**
29
+ * Similar to validators, but for asynchronous validation logic that may involve
30
+ * API calls or other deferred operations.
31
+ */
32
+ asyncValidators?: string[];
33
+ /**
34
+ * Defines whether the control should be disabled. Can be a boolean value or a
35
+ * string expression that evaluates against the form object.
36
+ */
37
+ disabled?: Expression<boolean> | boolean;
38
+ /**
39
+ * Specifies how to handle the control when hidden: 'keep' (remains in form model)
40
+ * or 'remove' (removed from form model).
41
+ */
42
+ hideStrategy?: HideStrategy;
43
+ /**
44
+ * Determines how the control's value is handled when visibility changes:
45
+ * 'last' (preserves last value), 'default' (reverts to default value),
46
+ * or 'reset' (clears value).
47
+ */
48
+ valueStrategy?: ValueStrategy;
49
+ /**
50
+ * Indicates if the control is read-only (displayed but not modifiable).
51
+ * Accepts either a boolean value or a string expression for dynamic evaluation.
52
+ */
53
+ readonly?: Expression<boolean> | boolean;
54
+ /**
55
+ * Specifies when to update the control's value: 'change' (as user types, default),
56
+ * 'blur' (when control loses focus), or 'submit' (when form is submitted).
57
+ */
58
+ updateOn?: UpdateStrategy;
59
+ /**
60
+ * A value that is automatically derived and set for the control.
61
+ * It will overwrite user input if one of its dependencies changes.
62
+ */
63
+ computedValue?: Expression<unknown>;
64
+ }
65
+ /**
66
+ * Specifies when to update the control's value:
67
+ * - 'change': as user types (default)
68
+ * - 'blur': when control loses focus
69
+ * - 'submit': when form is submitted
70
+ */
71
+ export type UpdateStrategy = 'change' | 'blur' | 'submit' | undefined;
72
+ /**
73
+ * Represents a group of controls that can be nested within a form.
74
+ */
75
+ export interface NgxFbFormGroup<T extends NgxFbBaseContent = NgxFbContent> extends NgxFbAbstractControl {
76
+ /**
77
+ * Specifies a title for the group
78
+ */
79
+ title?: string;
80
+ /**
81
+ * Dynamic title that can be evaluated from form data
82
+ */
83
+ dynamicTitle?: Expression<string>;
84
+ /**
85
+ * Object mapping keys to NgxFbContent that configure the controls of the group
86
+ */
87
+ controls: Record<string, T>;
88
+ }
89
+ /**
90
+ * Represents an individual form control with label and value properties.
91
+ */
92
+ export interface NgxFbControl extends NgxFbAbstractControl {
93
+ /**
94
+ * Specifies the label for the control
95
+ */
96
+ label?: string;
97
+ /**
98
+ * Dynamic label that can be evaluated from form data
99
+ */
100
+ dynamicLabel?: Expression<string>;
101
+ /**
102
+ * Default value for the control. Should be overwritten with the proper value type of the control.
103
+ */
104
+ defaultValue?: unknown;
105
+ /**
106
+ * Whether this control can have a null value. Used to set the same property through the reactive forms API.
107
+ */
108
+ nonNullable?: boolean;
109
+ }
110
+ /**
111
+ * Represents a block element that doesn't behave like a form control.
112
+ * Used for UI elements that aren't part of the form model.
113
+ */
114
+ export interface NgxFbBlock extends NgxFbBaseContent {
115
+ /**
116
+ * Required property for TypeScript to properly do type narrowing
117
+ */
118
+ isControl: false;
119
+ [key: string]: unknown;
120
+ }
121
+ /**
122
+ * Union type representing all possible content types that can be used in a form.
123
+ */
124
+ export type NgxFbContent = NgxFbFormGroup | NgxFbControl | NgxFbBlock;
125
+ /**
126
+ * Specifies how to handle the control when hidden:
127
+ * - 'keep': control remains in form model
128
+ * - 'remove': control is removed from form model
129
+ */
130
+ export type HideStrategy = 'keep' | 'remove';
131
+ /**
132
+ * Determines how the control's value is handled when visibility changes:
133
+ * - 'last': preserves last value
134
+ * - 'default': reverts to default value
135
+ * - 'reset': clears value
136
+ */
137
+ export type ValueStrategy = 'last' | 'default' | 'reset';
@@ -0,0 +1,2 @@
1
+ export type FormContext = Record<string, unknown>;
2
+ export type Expression<T> = string | ((formValue: FormContext) => T);
@@ -0,0 +1,4 @@
1
+ import { NgxFbBaseContent, NgxFbContent } from './content.type';
2
+ export interface NgxFbForm<ContentType extends NgxFbBaseContent = NgxFbContent> {
3
+ content: Record<string, ContentType>;
4
+ }
@@ -0,0 +1,4 @@
1
+ import { NgxFbBaseContent, ValueStrategy } from './content.type';
2
+ export type SimpleFunction = () => void;
3
+ export type ValueHandleFunction = (valueStrategy?: ValueStrategy) => void;
4
+ export type TestIdBuilderFn = (content: NgxFbBaseContent, name: string, parentTestId?: string) => string;
@@ -0,0 +1,4 @@
1
+ import { TestIdBuilderFn } from './functions.type';
2
+ export interface NgxFbGlobalConfiguration {
3
+ testIdBuilderFn: TestIdBuilderFn | undefined;
4
+ }
@@ -0,0 +1,42 @@
1
+ import { ComponentRegistrationConfig } from './registration.type';
2
+ import { AsyncValidatorConfig, RegistrationRecord, ValidatorConfig } from './validation.type';
3
+ import { UpdateStrategy } from './content.type';
4
+ import { NgxFbGlobalConfiguration } from './global-configuration.type';
5
+ /**
6
+ * Configuration for registering and providing components and validators in Ngx Formbar
7
+ *
8
+ * @template S - Type extending RegistrationRecord for synchronous validators
9
+ * @template A - Type extending RegistrationRecord for asynchronous validators
10
+ *
11
+ * @property componentRegistrations - Optional mapping of control types to component implementations
12
+ * @property validatorRegistrations - Optional configuration for synchronous validators
13
+ * @property asyncValidatorRegistrations - Optional configuration for asynchronous validators
14
+ * @property updateOn - (Optional) Specifies when to update the control's value
15
+ * @property globalConfig - (Optional) Configuration that is used for all controls
16
+ *
17
+ * @example
18
+ * // Define custom form components and validators
19
+ * const formbarConfig: FormbarConfig<SyncValidators, AsyncValidators> = {
20
+ * componentRegistrations:
21
+ * {
22
+ * 'text-input': TextInputComponent
23
+ * 'address-group': AddressGroupComponent
24
+ * },
25
+ * validatorRegistrations: {
26
+ * 'min-chars': [Validators.minLength(3)],
27
+ * letter: [letterValidator],
28
+ * combined: ['min-chars', Validators.required, 'letter'],
29
+ * }
30
+ * asyncValidatorRegistrations: {
31
+ * async: [asyncValidator],
32
+ * 'async-group': [asyncGroupValidator],
33
+ * },
34
+ * };
35
+ */
36
+ export interface FormbarConfig<S extends RegistrationRecord, A extends RegistrationRecord> {
37
+ componentRegistrations?: ComponentRegistrationConfig;
38
+ validatorRegistrations?: ValidatorConfig<S>;
39
+ asyncValidatorRegistrations?: AsyncValidatorConfig<A>;
40
+ updateOn?: UpdateStrategy;
41
+ globalConfig?: NgxFbGlobalConfiguration;
42
+ }
@@ -0,0 +1,18 @@
1
+ import { Type } from '@angular/core';
2
+ /**
3
+ * Configuration for registering component types
4
+ *
5
+ * Used to map string type identifiers to component implementations
6
+ * for dynamic rendering.
7
+ */
8
+ export type ComponentRegistrationConfig = Record<string, Type<unknown>>;
9
+ /**
10
+ * Strategy for handling component states
11
+ *
12
+ * Determines how visibility, disabled, and other component states
13
+ * are managed.
14
+ *
15
+ * - 'auto': Formbar automatically manages the state
16
+ * - 'manual': The component/host manages the state itself
17
+ */
18
+ export type StateHandling = 'auto' | 'manual';
@@ -0,0 +1,59 @@
1
+ import { AsyncValidatorFn, ValidatorFn } from '@angular/forms';
2
+ /**
3
+ * Base record type for validator registrations
4
+ *
5
+ * Represents a key-value store where keys are validator identifiers
6
+ * and values are the validator implementations
7
+ */
8
+ export type RegistrationRecord = Record<string, unknown>;
9
+ /**
10
+ * Utility type that extracts string keys from a validator registration
11
+ *
12
+ * Used to ensure type safety when referencing validators by their string identifiers
13
+ *
14
+ * @template Registration - A record type containing registered validators
15
+ */
16
+ export type ValidatorKey<Registration extends RegistrationRecord> = Extract<keyof Registration, string>;
17
+ /**
18
+ * Configuration for synchronous form validators
19
+ *
20
+ * Maps validator identifiers to arrays of validator definitions which can be:
21
+ * - Direct validator functions (ValidatorFn)
22
+ * - References to other validators by their string identifiers
23
+ *
24
+ * @template T - Record type containing registered validators
25
+ *
26
+ * @example
27
+ * // Define validator configurations
28
+ * const validatorConfig: ValidatorConfig<MyValidators> = {
29
+ * required: [Validators.required],
30
+ * email: [Validators.email],
31
+ * password: [Validators.minLength(8), 'required'],
32
+ * // Reference other validators or combine them
33
+ * profile: ['required', 'email', customProfileValidator]
34
+ * };
35
+ */
36
+ export type ValidatorConfig<T extends RegistrationRecord> = {
37
+ [K in keyof T]: (ValidatorFn | ValidatorKey<T>)[];
38
+ };
39
+ /**
40
+ * Configuration for asynchronous form validators
41
+ *
42
+ * Maps validator identifiers to arrays of async validator definitions which can be:
43
+ * - Direct async validator functions (AsyncValidatorFn)
44
+ * - References to other validators by their string identifiers
45
+ *
46
+ * @template T - Record type containing registered validators
47
+ *
48
+ * @example
49
+ * // Define async validator configurations
50
+ * const asyncValidatorConfig: AsyncValidatorConfig<MyAsyncValidators> = {
51
+ * uniqueEmail: [emailUniquenessValidator],
52
+ * serverCheck: [serverValidationFn],
53
+ * // Reference other validators or combine them
54
+ * complexCheck: ['uniqueEmail', customAsyncValidator]
55
+ * };
56
+ */
57
+ export type AsyncValidatorConfig<T extends RegistrationRecord> = {
58
+ [K in keyof T]: (AsyncValidatorFn | ValidatorKey<T>)[];
59
+ };
@@ -0,0 +1,6 @@
1
+ import { Signal } from '@angular/core';
2
+ import { AsyncValidatorFn, ValidatorFn } from '@angular/forms';
3
+ export interface ValidatorResolver {
4
+ registrations: Signal<ReadonlyMap<string, ValidatorFn[]>>;
5
+ asyncRegistrations: Signal<ReadonlyMap<string, AsyncValidatorFn[]>>;
6
+ }
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@ngx-formbar/core",
3
+ "version": "0.11.0",
4
+ "peerDependencies": {
5
+ "@angular/cdk": "^19.0.0",
6
+ "@angular/common": "^19.0.0",
7
+ "@angular/core": "^19.0.0"
8
+ },
9
+ "dependencies": {
10
+ "acorn": "^8.14.1",
11
+ "eval-estree-expression": "^3.0.0",
12
+ "tslib": "^2.3.0"
13
+ },
14
+ "schematics": "./schematics/collection.json",
15
+ "ng-add": {
16
+ "save": true
17
+ },
18
+ "private": false,
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "sideEffects": false,
23
+ "license": "MIT",
24
+ "keywords": [
25
+ "angular",
26
+ "typescript",
27
+ "reactive-forms",
28
+ "json-form"
29
+ ],
30
+ "author": {
31
+ "name": "Alexander Pahn",
32
+ "email": "alexander.pahn@outlook.com"
33
+ },
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/TheNordicOne/ngx-formbar.git"
37
+ },
38
+ "bugs": {
39
+ "url": "https://github.com/TheNordicOne/ngx-formbar/issues"
40
+ },
41
+ "module": "fesm2022/ngx-formbar-core.mjs",
42
+ "typings": "index.d.ts",
43
+ "exports": {
44
+ "./package.json": {
45
+ "default": "./package.json"
46
+ },
47
+ ".": {
48
+ "types": "./index.d.ts",
49
+ "default": "./fesm2022/ngx-formbar-core.mjs"
50
+ }
51
+ }
52
+ }
@@ -0,0 +1 @@
1
+ export * from './lib';
@@ -0,0 +1,29 @@
1
+ import { Component, Signal, inject } from '@angular/core';<% if (!hasViewProviderHelper) { %>
2
+ import { ControlContainer } from '@angular/forms';<% } %>
3
+ import { NgxfbBlockDirective } from '@ngx-formbar/core';
4
+ import { <%= classify(interfaceName) %> } from './<%= dasherize(interfaceName) %>.type';<% if (hasViewProviderHelper) { %>
5
+ import { <%= viewProviderIdentifier %> } from '<%= viewProviderHelperPath %>';<% } %><% if (hasHostDirectiveHelper) { %>
6
+ import { <%= hostDirectiveIdentifier %> } from '<%= hostDirectiveHelperPath %>';<% } %>
7
+
8
+ @Component({
9
+ selector: 'app-<%= dasherize(componentName) %>',
10
+ imports: [],
11
+ templateUrl: './<%= dasherize(componentName) %>.component.html',
12
+ viewProviders: <% if (hasViewProviderHelper) { %><%= viewProviderIdentifier %><% } else { %>[
13
+ {
14
+ provide: ControlContainer,
15
+ useFactory: () => inject(ControlContainer, { skipSelf: true }),
16
+ }
17
+ ]<% } %>,
18
+ hostDirectives: <% if (hasHostDirectiveHelper) { %>[<%= hostDirectiveIdentifier %>]<% } else { %>[
19
+ {
20
+ directive: NgxfbBlockDirective,
21
+ inputs: ['content', 'name'],
22
+ }
23
+ ]<% } %>,
24
+ })
25
+ export class <%= classify(componentClassName) %> {
26
+ private readonly block = inject(NgxfbBlockDirective<<%= classify(interfaceName) %>>);
27
+ readonly content: Signal<<%= classify(interfaceName) %>> = this.block.content;
28
+ }
29
+
@@ -0,0 +1,6 @@
1
+ import { NgxFbBlock } from '@ngx-formbar/core';
2
+
3
+ export interface <%= classify(interfaceName) %> extends NgxFbBlock {
4
+ type: '<%= key %>';
5
+ }
6
+
@@ -0,0 +1,3 @@
1
+ import { Rule } from '@angular-devkit/schematics';
2
+ import { Schema } from '../shared/schema';
3
+ export declare function block(options: Schema): Rule;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.block = block;
4
+ const schematics_1 = require("@angular-devkit/schematics");
5
+ const scaffold_and_register_rule_1 = require("../shared/rules/scaffold-and-register.rule");
6
+ function block(options) {
7
+ return () => {
8
+ return (0, schematics_1.chain)([(0, scaffold_and_register_rule_1.scaffoldAndRegister)(options, 'block')]);
9
+ };
10
+ }
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../projects/core/automation/schematics/block/index.ts"],"names":[],"mappings":";;AAIA,sBAIC;AARD,2DAAyD;AACzD,2FAAiF;AAGjF,SAAgB,KAAK,CAAC,OAAe;IACnC,OAAO,GAAG,EAAE;QACV,OAAO,IAAA,kBAAK,EAAC,CAAC,IAAA,gDAAmB,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,62 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "$id": "NgxFormbarBlock",
4
+ "title": "Scaffold Block",
5
+ "type": "object",
6
+ "properties": {
7
+ "name": {
8
+ "description": "The name of the component that this control will use. Defaults to the key if not provided.",
9
+ "type": "string"
10
+ },
11
+ "key": {
12
+ "description": "The name of the key that this control will be associated with.",
13
+ "type": "string"
14
+ },
15
+ "path": {
16
+ "type": "string",
17
+ "format": "path",
18
+ "description": "The path to create the component.",
19
+ "visible": false,
20
+ "$default": {
21
+ "$source": "workingDirectory"
22
+ }
23
+ },
24
+ "project": {
25
+ "type": "string",
26
+ "description": "The name of the project.",
27
+ "$default": {
28
+ "$source": "projectName"
29
+ }
30
+ },
31
+ "interfaceSuffix": {
32
+ "type": "string",
33
+ "description": "The suffix of the interface. Defaults to 'Control'",
34
+ "default": "Control"
35
+ },
36
+ "componentSuffix": {
37
+ "type": "string",
38
+ "description": "The suffix of the component. Defaults to 'Control'",
39
+ "default": "Control"
40
+ },
41
+ "hostDirectiveHelperPath": {
42
+ "type": "string",
43
+ "description": "Path to the hostDirective helper"
44
+ },
45
+ "skipRegistration": {
46
+ "type": "boolean",
47
+ "description": "Skip automatic registration"
48
+ },
49
+ "viewProviderHelperPath": {
50
+ "type": "string",
51
+ "description": "Path to the viewProvider helper"
52
+ },
53
+ "schematicsConfig": {
54
+ "type": "string",
55
+ "description": "Path of the configuration that is to be used by this schematic"
56
+ }
57
+ },
58
+ "required": [
59
+ "key"
60
+ ]
61
+ }
62
+
@@ -0,0 +1,31 @@
1
+ {
2
+ "$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json",
3
+ "schematics": {
4
+ "ng-add": {
5
+ "description": "Add ngx-formbar to the project.",
6
+ "factory": "./ng-add/index#ngAdd",
7
+ "schema": "./ng-add/schema.json",
8
+ "hidden": true
9
+ },
10
+ "control": {
11
+ "description": "Scaffolds a new control and registers it.",
12
+ "factory": "./control/index#control",
13
+ "schema": "./control/schema.json"
14
+ },
15
+ "group": {
16
+ "description": "Scaffolds a new group and registers it.",
17
+ "factory": "./group/index#group",
18
+ "schema": "./group/schema.json"
19
+ },
20
+ "block": {
21
+ "description": "Scaffolds a new block and registers it.",
22
+ "factory": "./block/index#block",
23
+ "schema": "./block/schema.json"
24
+ },
25
+ "register": {
26
+ "description": "Searches for all components and registers them",
27
+ "factory": "./register/index#register",
28
+ "schema": "./register/schema.json"
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,29 @@
1
+ import { Component, Signal, inject } from '@angular/core';
2
+ import { ReactiveFormsModule<% if (!hasViewProviderHelper) { %>, ControlContainer<% } %> } from '@angular/forms';
3
+ import { NgxfbControlDirective } from '@ngx-formbar/core';
4
+ import { <%= interfaceName %> } from './<%= dasherize(interfaceName) %>.type';<% if (hasViewProviderHelper) { %>
5
+ import { <%= viewProviderIdentifier %> } from '<%= viewProviderHelperPath %>';<% } %><% if (hasHostDirectiveHelper) { %>
6
+ import { <%= hostDirectiveIdentifier %> } from '<%= hostDirectiveHelperPath %>';<% } %>
7
+
8
+ @Component({
9
+ selector: 'app-<%= dasherize(componentName) %>',
10
+ imports: [ReactiveFormsModule],
11
+ templateUrl: './<%= dasherize(componentName) %>.component.html',
12
+ viewProviders: <% if (hasViewProviderHelper) { %><%= viewProviderIdentifier %><% } else { %>[
13
+ {
14
+ provide: ControlContainer,
15
+ useFactory: () => inject(ControlContainer, { skipSelf: true }),
16
+ }
17
+ ]<% } %>,
18
+ hostDirectives: <% if (hasHostDirectiveHelper) { %>[<%= hostDirectiveIdentifier %>]<% } else { %>[
19
+ {
20
+ directive: NgxfbControlDirective,
21
+ inputs: ['content', 'name'],
22
+ }
23
+ ]<% } %>,
24
+ })
25
+ export class <%= classify(componentClassName) %> {
26
+ private readonly control = inject(NgxfbControlDirective<<%= interfaceName %>>);
27
+ readonly content: Signal<<%= interfaceName %>> = this.control.content;
28
+ readonly name: Signal<string> = this.control.name;
29
+ }
@@ -0,0 +1,6 @@
1
+ import { NgxFbControl } from '@ngx-formbar/core';
2
+
3
+ export interface <%= classify(interfaceName) %> extends NgxFbControl {
4
+ type: '<%= key %>';
5
+ }
6
+
@@ -0,0 +1,3 @@
1
+ import { Rule } from '@angular-devkit/schematics';
2
+ import { Schema } from '../shared/schema';
3
+ export declare function control(options: Schema): Rule;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.control = control;
4
+ const schematics_1 = require("@angular-devkit/schematics");
5
+ const scaffold_and_register_rule_1 = require("../shared/rules/scaffold-and-register.rule");
6
+ function control(options) {
7
+ return () => {
8
+ return (0, schematics_1.chain)([(0, scaffold_and_register_rule_1.scaffoldAndRegister)(options, 'control')]);
9
+ };
10
+ }
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../projects/core/automation/schematics/control/index.ts"],"names":[],"mappings":";;AAIA,0BAIC;AARD,2DAAyD;AACzD,2FAAiF;AAGjF,SAAgB,OAAO,CAAC,OAAe;IACrC,OAAO,GAAG,EAAE;QACV,OAAO,IAAA,kBAAK,EAAC,CAAC,IAAA,gDAAmB,EAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,61 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "$id": "NgxFormbarControl",
4
+ "title": "Scaffold Control",
5
+ "type": "object",
6
+ "properties": {
7
+ "name": {
8
+ "description": "The name of the component that this control will use. Defaults to the key if not provided.",
9
+ "type": "string"
10
+ },
11
+ "key": {
12
+ "description": "The name of the key that this control will be associated with.",
13
+ "type": "string"
14
+ },
15
+ "path": {
16
+ "type": "string",
17
+ "format": "path",
18
+ "description": "The path to create the component.",
19
+ "visible": false,
20
+ "$default": {
21
+ "$source": "workingDirectory"
22
+ }
23
+ },
24
+ "project": {
25
+ "type": "string",
26
+ "description": "The name of the project.",
27
+ "$default": {
28
+ "$source": "projectName"
29
+ }
30
+ },
31
+ "interfaceSuffix": {
32
+ "type": "string",
33
+ "description": "The suffix of the interface. Defaults to 'Control'",
34
+ "default": "Control"
35
+ },
36
+ "componentSuffix": {
37
+ "type": "string",
38
+ "description": "The suffix of the component. Defaults to 'Control'",
39
+ "default": "Control"
40
+ },
41
+ "hostDirectiveHelperPath": {
42
+ "type": "string",
43
+ "description": "Path to the hostDirective helper"
44
+ },
45
+ "skipRegistration": {
46
+ "type": "boolean",
47
+ "description": "Skip automatic registration"
48
+ },
49
+ "viewProviderHelperPath": {
50
+ "type": "string",
51
+ "description": "Path to the viewProvider helper"
52
+ },
53
+ "schematicsConfig": {
54
+ "type": "string",
55
+ "description": "Path of the configuration that is to be used by this schematic"
56
+ }
57
+ },
58
+ "required": [
59
+ "key"
60
+ ]
61
+ }
@@ -0,0 +1,5 @@
1
+ <ng-container [formGroupName]="name()">
2
+ @for (content of controls(); track content[0]) {
3
+ <ng-template *ngxfbAbstractControl="content" />
4
+ }
5
+ </ng-container>