ngx-dynamic-entity 1.0.0 → 1.2.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 (62) hide show
  1. package/README.md +129 -139
  2. package/esm2022/lib/field-types/array-field.component.mjs +112 -104
  3. package/esm2022/lib/field-types/boolean-field.component.mjs +62 -61
  4. package/esm2022/lib/field-types/checkbox-field.component.mjs +48 -47
  5. package/esm2022/lib/field-types/currency-field.component.mjs +54 -53
  6. package/esm2022/lib/field-types/date-field.component.mjs +46 -45
  7. package/esm2022/lib/field-types/dropdown-field.component.mjs +89 -87
  8. package/esm2022/lib/field-types/email-field.component.mjs +64 -63
  9. package/esm2022/lib/field-types/entity-ref-field.component.mjs +85 -71
  10. package/esm2022/lib/field-types/field-component.contract.mjs +2 -0
  11. package/esm2022/lib/field-types/file-field.component.mjs +88 -87
  12. package/esm2022/lib/field-types/group-field.component.mjs +50 -50
  13. package/esm2022/lib/field-types/image-field.component.mjs +92 -91
  14. package/esm2022/lib/field-types/month-year-field.component.mjs +80 -79
  15. package/esm2022/lib/field-types/multi-select-field.component.mjs +66 -65
  16. package/esm2022/lib/field-types/number-field.component.mjs +71 -75
  17. package/esm2022/lib/field-types/password-field.component.mjs +68 -67
  18. package/esm2022/lib/field-types/radio-field.component.mjs +66 -65
  19. package/esm2022/lib/field-types/text-field.component.mjs +81 -74
  20. package/esm2022/lib/field-types/textarea-field.component.mjs +48 -47
  21. package/esm2022/lib/form/dynamic-field/dynamic-field.component.mjs +53 -6
  22. package/esm2022/lib/form/dynamic-form.component.mjs +309 -20
  23. package/esm2022/lib/form/dynamic-record-form.component.mjs +36 -11
  24. package/esm2022/lib/providers/provide-field-types.mjs +1 -1
  25. package/esm2022/lib/providers/provide-ngx-dynamic-entity.mjs +8 -2
  26. package/esm2022/lib/services/cascade-data.service.mjs +2 -2
  27. package/esm2022/lib/services/entity-ref-cache.mjs +1 -1
  28. package/esm2022/lib/services/entity-ref-registry.service.mjs +2 -2
  29. package/esm2022/lib/services/entity-ref-selection.service.mjs +1 -1
  30. package/esm2022/lib/services/entity-reference.service.mjs +1 -1
  31. package/esm2022/lib/services/field-registry.service.mjs +1 -1
  32. package/esm2022/lib/services/file-upload.service.mjs +1 -1
  33. package/esm2022/lib/services/lookup-registry.service.mjs +2 -2
  34. package/esm2022/lib/services/rbac.service.mjs +1 -1
  35. package/esm2022/lib/services/validation-messages.service.mjs +56 -0
  36. package/esm2022/lib/services/validator-registry.service.mjs +35 -2
  37. package/esm2022/lib/tokens/injection-tokens.mjs +35 -6
  38. package/esm2022/public-api.mjs +23 -2
  39. package/fesm2022/ngx-dynamic-entity.mjs +1754 -1236
  40. package/fesm2022/ngx-dynamic-entity.mjs.map +1 -1
  41. package/lib/field-types/array-field.component.d.ts +7 -1
  42. package/lib/field-types/dropdown-field.component.d.ts +2 -1
  43. package/lib/field-types/entity-ref-field.component.d.ts +12 -2
  44. package/lib/field-types/field-component.contract.d.ts +49 -0
  45. package/lib/field-types/group-field.component.d.ts +1 -1
  46. package/lib/field-types/multi-select-field.component.d.ts +1 -1
  47. package/lib/field-types/number-field.component.d.ts +1 -0
  48. package/lib/field-types/radio-field.component.d.ts +1 -1
  49. package/lib/field-types/text-field.component.d.ts +10 -2
  50. package/lib/form/dynamic-field/dynamic-field.component.d.ts +39 -4
  51. package/lib/form/dynamic-form.component.d.ts +155 -8
  52. package/lib/form/dynamic-record-form.component.d.ts +13 -2
  53. package/lib/providers/provide-ngx-dynamic-entity.d.ts +25 -3
  54. package/lib/services/cascade-data.service.d.ts +1 -1
  55. package/lib/services/entity-ref-registry.service.d.ts +1 -1
  56. package/lib/services/lookup-registry.service.d.ts +1 -1
  57. package/lib/services/validation-messages.service.d.ts +43 -0
  58. package/lib/services/validator-registry.service.d.ts +13 -1
  59. package/lib/tokens/injection-tokens.d.ts +42 -7
  60. package/package.json +17 -18
  61. package/public-api.d.ts +12 -0
  62. package/styles.css +579 -0
@@ -1,4 +1,4 @@
1
- import { ValidatorFn } from '@angular/forms';
1
+ import { AsyncValidatorFn, ValidatorFn } from '@angular/forms';
2
2
  import type { FieldValidators } from '@dynamic-entity/core';
3
3
  import * as i0 from "@angular/core";
4
4
  /**
@@ -6,6 +6,7 @@ import * as i0 from "@angular/core";
6
6
  */
7
7
  export declare class ValidatorRegistryService {
8
8
  private readonly consumerRegistry;
9
+ private readonly asyncRegistry;
9
10
  /**
10
11
  * Resolve a validator key string to a ValidatorFn.
11
12
  * Supports parameterized built-ins like 'min:0', 'maxLength:255'.
@@ -15,6 +16,17 @@ export declare class ValidatorRegistryService {
15
16
  resolveAll(validatorKeys?: string[]): ValidatorFn[];
16
17
  /** Resolve a FieldValidators object or string[] into ValidatorFn[] */
17
18
  resolveFromConfig(config?: FieldValidators | string[]): ValidatorFn[];
19
+ /**
20
+ * Resolve the async validators a field names, in `validators.customAsync`.
21
+ *
22
+ * Async validators are deliberately a separate registry and a separate config key: Angular
23
+ * attaches them through `setAsyncValidators`, runs them only once the synchronous ones
24
+ * pass, and holds the control in `pending` until they settle. Mixing them into the
25
+ * synchronous list would silently never run them.
26
+ *
27
+ * An unknown name is skipped rather than throwing, matching the synchronous behaviour.
28
+ */
29
+ resolveAsyncFromConfig(config?: FieldValidators | string[]): AsyncValidatorFn[];
18
30
  static ɵfac: i0.ɵɵFactoryDeclaration<ValidatorRegistryService, never>;
19
31
  static ɵprov: i0.ɵɵInjectableDeclaration<ValidatorRegistryService>;
20
32
  }
@@ -1,8 +1,7 @@
1
1
  import { InjectionToken } from '@angular/core';
2
2
  import type { Type } from '@angular/core';
3
- import type { CommonModuleEntry, EntityReferenceLoader, FileUploadHandler, LookupListSource } from '@dynamic-entity/core';
4
3
  import { type EntityRefCacheStore } from '../services/entity-ref-cache';
5
- /** Roles that see XXXXXXXXX for masked fields (ADR-003) */
4
+ /** Roles that see XXXXXXXXX for masked fields. Presentational only — enforce authz server-side. */
6
5
  export declare const MASKED_ROLES: InjectionToken<string[]>;
7
6
  /**
8
7
  * Consumer **overrides**: fieldType string → Angular component class.
@@ -43,10 +42,50 @@ export declare const ENTITY_REF_REGISTRY: InjectionToken<Map<string, EntityRefer
43
42
  * })
44
43
  */
45
44
  export declare const LOOKUP_REGISTRY: InjectionToken<Map<string, LookupListSource>>;
45
+ /**
46
+ * Ordered steps that move a saved record forward when a config's `version` increases.
47
+ *
48
+ * Without these, `EntityFormConfig.version` and `VersionedRecord._configVersion` are
49
+ * declarations nothing acts on: a schema can be edited freely while records keep their old
50
+ * shape, and nothing reconciles the two. Registering migrations makes the version numbers
51
+ * mean something.
52
+ *
53
+ * @example
54
+ * provideNgxDynamicEntity({
55
+ * migrations: [
56
+ * { from: 1, to: 2, description: 'split name', migrate: r => ({ ...r, firstName: r['name'] }) },
57
+ * ],
58
+ * })
59
+ */
60
+ export declare const RECORD_MIGRATIONS: InjectionToken<RecordMigration[]>;
61
+ /**
62
+ * Overrides for the messages shown under an invalid field, keyed by Angular error key
63
+ * (`required`, `minlength`, `pattern`, …) plus a few field-specific keys.
64
+ *
65
+ * The built-in messages are English literals. Registering here is what makes a non-English
66
+ * form possible without re-implementing every field component; unlisted keys keep their
67
+ * default, so overriding one does not mean supplying them all.
68
+ */
69
+ export declare const VALIDATION_MESSAGES: InjectionToken<Record<string, any>>;
46
70
  /** Registry: validator key → ValidatorFn */
47
71
  export declare const VALIDATOR_REGISTRY: InjectionToken<Map<string, any>>;
72
+ /**
73
+ * Registry: validator key → AsyncValidatorFn.
74
+ *
75
+ * Kept separate from VALIDATOR_REGISTRY because Angular applies the two differently: an async
76
+ * validator runs only once the synchronous ones pass, and puts the control into `pending`
77
+ * while it does. Name them from a schema with `validators: { customAsync: ['uniqueEmail'] }`.
78
+ */
79
+ export declare const ASYNC_VALIDATOR_REGISTRY: InjectionToken<Map<string, any>>;
80
+ /**
81
+ * A registered hook: receives the payload, returns it (or a replacement), sync or async.
82
+ *
83
+ * Spelled out rather than typed as `Function`, which accepts class declarations and any
84
+ * arity and gives a consumer no signature to write against.
85
+ */
86
+ export type HookFn = (data: any, context?: unknown) => unknown | Promise<unknown>;
48
87
  /** Registry: hook key → async (data, context) => data */
49
- export declare const HOOK_REGISTRY: InjectionToken<Map<string, Function>>;
88
+ export declare const HOOK_REGISTRY: InjectionToken<Map<string, HookFn>>;
50
89
  /**
51
90
  * Consumer-registered list of common module tabs (documents, audit, tasks, etc.).
52
91
  * The library ships no built-in implementations. Consumers provide their own list
@@ -82,10 +121,6 @@ export declare const UPLOAD_HANDLER: InjectionToken<FileUploadHandler>;
82
121
  * { provide: ENTITY_REF_CACHE_STORE, useClass: SessionStorageRefCache }
83
122
  */
84
123
  export declare const ENTITY_REF_CACHE_STORE: InjectionToken<EntityRefCacheStore>;
85
- /**
86
- * Consumer-provided predicate function to check whether user roles can edit system default tabs or fields.
87
- * Defaults to allowing edits if not provided.
88
- */
89
124
  /**
90
125
  * Consumer-provided predicate function to check whether user roles can edit system default tabs or fields.
91
126
  * Defaults to allowing edits if not provided.
package/package.json CHANGED
@@ -1,35 +1,34 @@
1
1
  {
2
2
  "name": "ngx-dynamic-entity",
3
- "version": "1.0.0",
4
- "description": "Angular 17 standalone UI library for dynamic entity forms and tables.",
3
+ "version": "1.2.0",
4
+ "description": "Angular standalone UI library for rendering dynamic entity forms.",
5
+ "//typings": "Local workspace resolution only: ng-packagr overwrites this with the correct in-tarball path ('index.d.ts') when generating dist/package.json. Do NOT add a 'main' field here — ng-packagr does not generate one, so it would be copied verbatim and resolve to dist/dist/... in the published package.",
5
6
  "typings": "index.d.ts",
6
- "main": "./dist/fesm2022/ngx-dynamic-entity.mjs",
7
7
  "peerDependencies": {
8
- "@angular/cdk": "^17.0.0",
9
- "@angular/common": "^17.0.0",
10
- "@angular/core": "^17.0.0",
11
- "@angular/forms": "^17.0.0",
12
- "@angular/material": "^17.0.0",
13
- "@dynamic-entity/core": "^1.0.0",
8
+ "@angular/common": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
9
+ "@angular/core": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
10
+ "@angular/forms": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
11
+ "@dynamic-entity/core": "^1.2.0",
14
12
  "rxjs": "^7.0.0"
15
13
  },
16
- "peerDependenciesMeta": {
17
- "@angular/cdk": {
18
- "optional": true
19
- },
20
- "@angular/material": {
21
- "optional": true
22
- }
23
- },
24
14
  "keywords": [
25
15
  "angular",
26
16
  "dynamic-entity",
27
17
  "dynamic-forms",
28
- "dynamic-table",
29
18
  "rbac"
30
19
  ],
31
20
  "license": "MIT",
32
21
  "sideEffects": false,
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/berserker5619/Dynamic-Entity.git",
25
+ "directory": "packages/ngx-dynamic-entity"
26
+ },
27
+ "homepage": "https://github.com/berserker5619/Dynamic-Entity/tree/main/packages/ngx-dynamic-entity#readme",
28
+ "bugs": {
29
+ "url": "https://github.com/berserker5619/Dynamic-Entity/issues"
30
+ },
31
+ "author": "Nizamudeen",
33
32
  "module": "fesm2022/ngx-dynamic-entity.mjs",
34
33
  "exports": {
35
34
  "./package.json": {
package/public-api.d.ts CHANGED
@@ -13,16 +13,28 @@ export * from './lib/services/lookup-registry.service';
13
13
  export * from './lib/services/rbac.service';
14
14
  export * from './lib/services/rules-evaluation.service';
15
15
  export * from './lib/services/config-source.service';
16
+ export * from './lib/services/validation-messages.service';
16
17
  export * from './lib/form/dynamic-form.component';
17
18
  export * from './lib/form/dynamic-record-form.component';
18
19
  export * from './lib/form/dynamic-field/dynamic-field.component';
20
+ export * from './lib/field-types/field-component.contract';
19
21
  export * from './lib/field-types/text-field.component';
20
22
  export * from './lib/field-types/textarea-field.component';
21
23
  export * from './lib/field-types/number-field.component';
24
+ export * from './lib/field-types/currency-field.component';
25
+ export * from './lib/field-types/email-field.component';
26
+ export * from './lib/field-types/password-field.component';
22
27
  export * from './lib/field-types/checkbox-field.component';
28
+ export * from './lib/field-types/boolean-field.component';
23
29
  export * from './lib/field-types/date-field.component';
30
+ export * from './lib/field-types/month-year-field.component';
24
31
  export * from './lib/field-types/dropdown-field.component';
32
+ export * from './lib/field-types/radio-field.component';
25
33
  export * from './lib/field-types/multi-select-field.component';
26
34
  export * from './lib/field-types/entity-ref-field.component';
35
+ export * from './lib/field-types/group-field.component';
36
+ export * from './lib/field-types/array-field.component';
37
+ export * from './lib/field-types/image-field.component';
38
+ export * from './lib/field-types/file-field.component';
27
39
  export { resolveLabel, resolveOptionLabel, resolveOptionValue, formatDisplayValue, valuesMatch, normalizeOption, normalizeConfig, } from '@dynamic-entity/core';
28
40
  export type { EntityFormConfig, NestedTabConfig, NestedFieldConfig, FieldTableConfig, RichFieldType, LocalizedText, DropdownOption, VersionedRecord, EntityPermissions, RbacContext, FieldValidators, EntityReferenceConfig, EntityReferenceLoader, ReferenceOption, ReferenceLoaderContext, AutoPatchConfig, PatchOnTrueMapping, FileRef, FormRule, RuleCondition, RuleAction, RuleEvaluationResult, CommonModuleEntry, } from '@dynamic-entity/core';