@acorex/platform 21.0.0-next.5 → 21.0.0-next.51

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 (124) hide show
  1. package/fesm2022/acorex-platform-auth.mjs +281 -23
  2. package/fesm2022/acorex-platform-auth.mjs.map +1 -1
  3. package/fesm2022/acorex-platform-common-common-settings.provider-Bi1RYif5.mjs +163 -0
  4. package/fesm2022/acorex-platform-common-common-settings.provider-Bi1RYif5.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-common.mjs +1047 -263
  6. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-core.mjs +1138 -510
  8. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-domain.mjs +557 -826
  10. package/fesm2022/acorex-platform-domain.mjs.map +1 -1
  11. package/fesm2022/acorex-platform-layout-builder.mjs +804 -186
  12. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  13. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs +121 -0
  14. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs.map +1 -0
  15. package/fesm2022/acorex-platform-layout-components.mjs +6208 -2344
  16. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  17. package/fesm2022/acorex-platform-layout-designer.mjs +456 -204
  18. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  19. package/fesm2022/acorex-platform-layout-entity.mjs +18632 -10286
  20. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  21. package/fesm2022/acorex-platform-layout-views.mjs +538 -168
  22. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  23. package/fesm2022/acorex-platform-layout-widget-core.mjs +720 -456
  24. package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
  25. package/fesm2022/{acorex-platform-layout-widgets-button-widget-designer.component-C3VoBb_b.mjs → acorex-platform-layout-widgets-button-widget-designer.component-Dy7jF-oD.mjs} +10 -10
  26. package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-Dy7jF-oD.mjs.map +1 -0
  27. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CDYAGBku.mjs +103 -0
  28. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CDYAGBku.mjs.map +1 -0
  29. package/fesm2022/{acorex-platform-layout-widgets-image-preview.popup-V31OpYah.mjs → acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs} +6 -7
  30. package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs.map +1 -0
  31. package/fesm2022/{acorex-platform-layout-widgets-page-widget-designer.component-BtZMBxYp.mjs → acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs} +12 -12
  32. package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs.map +1 -0
  33. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BGO75IMz.mjs +116 -0
  34. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BGO75IMz.mjs.map +1 -0
  35. package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-Ck7-wpT2.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-DmzNTYiS.mjs} +6 -6
  36. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-DmzNTYiS.mjs.map +1 -0
  37. package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-y8vjUiVs.mjs → acorex-platform-layout-widgets-tabular-data-view-popup.component-BNG_588B.mjs} +5 -5
  38. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-BNG_588B.mjs.map +1 -0
  39. package/fesm2022/{acorex-platform-layout-widgets-text-block-widget-designer.component-Df1BFkSa.mjs → acorex-platform-layout-widgets-text-block-widget-designer.component-Vo4fWHtX.mjs} +6 -6
  40. package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-Vo4fWHtX.mjs.map +1 -0
  41. package/fesm2022/acorex-platform-layout-widgets.mjs +8728 -4269
  42. package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
  43. package/fesm2022/acorex-platform-native.mjs +8 -7
  44. package/fesm2022/acorex-platform-native.mjs.map +1 -1
  45. package/fesm2022/acorex-platform-runtime.mjs +391 -166
  46. package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
  47. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Cx1lLUaR.mjs +160 -0
  48. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Cx1lLUaR.mjs.map +1 -0
  49. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-AOrcgjDF.mjs +120 -0
  50. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-AOrcgjDF.mjs.map +1 -0
  51. package/fesm2022/{acorex-platform-themes-default-entity-master-single-view.component-eMBby9k4.mjs → acorex-platform-themes-default-entity-master-single-view.component-BfCeUU5F.mjs} +19 -26
  52. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-BfCeUU5F.mjs.map +1 -0
  53. package/fesm2022/{acorex-platform-themes-default-error-401.component-cfREo88K.mjs → acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs} +4 -4
  54. package/fesm2022/acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs.map +1 -0
  55. package/fesm2022/{acorex-platform-themes-default-error-404.component-CdCV5ZoA.mjs → acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs} +4 -4
  56. package/fesm2022/acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs.map +1 -0
  57. package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs +19 -0
  58. package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs.map +1 -0
  59. package/fesm2022/acorex-platform-themes-default.mjs +1836 -67
  60. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  61. package/fesm2022/{acorex-platform-themes-shared-icon-chooser-column.component-C0EpfU2k.mjs → acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs} +6 -6
  62. package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs.map +1 -0
  63. package/fesm2022/{acorex-platform-themes-shared-icon-chooser-view.component-9W52W6Nu.mjs → acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs} +6 -6
  64. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs.map +1 -0
  65. package/fesm2022/{acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs → acorex-platform-themes-shared-settings.provider-DK6R87Lf.mjs} +24 -25
  66. package/fesm2022/acorex-platform-themes-shared-settings.provider-DK6R87Lf.mjs.map +1 -0
  67. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-D566Kdvy.mjs +94 -0
  68. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-D566Kdvy.mjs.map +1 -0
  69. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-D7-rCGl7.mjs +86 -0
  70. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-D7-rCGl7.mjs.map +1 -0
  71. package/fesm2022/acorex-platform-themes-shared.mjs +674 -573
  72. package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
  73. package/fesm2022/acorex-platform-workflow.mjs +1715 -535
  74. package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
  75. package/fesm2022/acorex-platform.mjs.map +1 -1
  76. package/package.json +37 -37
  77. package/{auth/index.d.ts → types/acorex-platform-auth.d.ts} +241 -4
  78. package/{common/index.d.ts → types/acorex-platform-common.d.ts} +598 -80
  79. package/{core/index.d.ts → types/acorex-platform-core.d.ts} +595 -132
  80. package/{domain/index.d.ts → types/acorex-platform-domain.d.ts} +744 -412
  81. package/{layout/builder/index.d.ts → types/acorex-platform-layout-builder.d.ts} +193 -48
  82. package/types/acorex-platform-layout-components.d.ts +2979 -0
  83. package/{layout/designer/index.d.ts → types/acorex-platform-layout-designer.d.ts} +96 -18
  84. package/{layout/entity/index.d.ts → types/acorex-platform-layout-entity.d.ts} +1601 -261
  85. package/{layout/views/index.d.ts → types/acorex-platform-layout-views.d.ts} +116 -55
  86. package/{layout/widget-core/index.d.ts → types/acorex-platform-layout-widget-core.d.ts} +272 -124
  87. package/{layout/widgets/index.d.ts → types/acorex-platform-layout-widgets.d.ts} +1055 -157
  88. package/{native/index.d.ts → types/acorex-platform-native.d.ts} +0 -7
  89. package/types/acorex-platform-runtime.d.ts +571 -0
  90. package/{themes/default/index.d.ts → types/acorex-platform-themes-default.d.ts} +122 -5
  91. package/{themes/shared/index.d.ts → types/acorex-platform-themes-shared.d.ts} +1 -1
  92. package/types/acorex-platform-workflow.d.ts +1884 -0
  93. package/fesm2022/acorex-platform-common-common-settings.provider-zhqNP3xb.mjs +0 -71
  94. package/fesm2022/acorex-platform-common-common-settings.provider-zhqNP3xb.mjs.map +0 -1
  95. package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-C3VoBb_b.mjs.map +0 -1
  96. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CxrsI6Hn.mjs +0 -135
  97. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CxrsI6Hn.mjs.map +0 -1
  98. package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-V31OpYah.mjs.map +0 -1
  99. package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-BtZMBxYp.mjs.map +0 -1
  100. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-Ck7-wpT2.mjs.map +0 -1
  101. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-y8vjUiVs.mjs.map +0 -1
  102. package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-Df1BFkSa.mjs.map +0 -1
  103. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs +0 -157
  104. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs.map +0 -1
  105. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-DyDa_hyd.mjs +0 -1542
  106. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-DyDa_hyd.mjs.map +0 -1
  107. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs +0 -101
  108. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs.map +0 -1
  109. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-eMBby9k4.mjs.map +0 -1
  110. package/fesm2022/acorex-platform-themes-default-error-401.component-cfREo88K.mjs.map +0 -1
  111. package/fesm2022/acorex-platform-themes-default-error-404.component-CdCV5ZoA.mjs.map +0 -1
  112. package/fesm2022/acorex-platform-themes-default-error-offline.component-E7SzBcAt.mjs +0 -19
  113. package/fesm2022/acorex-platform-themes-default-error-offline.component-E7SzBcAt.mjs.map +0 -1
  114. package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-C0EpfU2k.mjs.map +0 -1
  115. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-9W52W6Nu.mjs.map +0 -1
  116. package/fesm2022/acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs.map +0 -1
  117. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-DTnfRy5f.mjs +0 -65
  118. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-DTnfRy5f.mjs.map +0 -1
  119. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-DY0JtT1v.mjs +0 -64
  120. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-DY0JtT1v.mjs.map +0 -1
  121. package/layout/components/index.d.ts +0 -1669
  122. package/runtime/index.d.ts +0 -307
  123. package/workflow/index.d.ts +0 -1808
  124. /package/{index.d.ts → types/acorex-platform.d.ts} +0 -0
@@ -1,204 +1,39 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, makeEnvironmentProviders, inject, NgModule, Injectable } from '@angular/core';
3
- import { AXPEntityService } from '@acorex/platform/layout/entity';
4
- import { AXPCommandRegistry, AXPQueryRegistry, AXPRuntimeModule } from '@acorex/platform/runtime';
2
+ import { InjectionToken, inject, NgModule, Injectable, makeEnvironmentProviders } from '@angular/core';
3
+ import { AXPRuntimeModule } from '@acorex/platform/runtime';
5
4
 
5
+ /**
6
+ * Token for entity CRUD setup. Consumed by AXPDomainModule.
7
+ * The actual provider is provideEntity() from @acorex/platform/layout/entity
8
+ * to avoid circular dependency (domain must not depend on layout/entity).
9
+ */
6
10
  const AXP_ENTITY_CRUD_SETUP = new InjectionToken('AXP_ENTITY_CRUD_SETUP');
7
- function provideEntity(entityKeys) {
8
- return makeEnvironmentProviders([
9
- {
10
- provide: AXP_ENTITY_CRUD_SETUP,
11
- multi: true,
12
- useFactory: () => {
13
- const commandRegistry = inject(AXPCommandRegistry);
14
- const queryRegistry = inject(AXPQueryRegistry);
15
- const entityService = inject(AXPEntityService);
16
- for (const entityKey of entityKeys) {
17
- const dataAccessor = entityService.withEntity(entityKey).data();
18
- // Register Commands
19
- commandRegistry.register(`${entityKey}:Create`, async () => ({
20
- execute: async (input) => {
21
- try {
22
- const id = await dataAccessor.create(input);
23
- const entity = await dataAccessor.byKey(id);
24
- if (!entity) {
25
- throw new Error('Entity not found after creation');
26
- }
27
- return {
28
- success: true,
29
- data: entity,
30
- };
31
- }
32
- catch (error) {
33
- return {
34
- success: false,
35
- message: {
36
- text: error instanceof Error ? error.message : 'Failed to create entity',
37
- },
38
- };
39
- }
40
- }
41
- }));
42
- commandRegistry.register(`${entityKey}:Update`, async () => ({
43
- execute: async ({ id, ...rest }) => {
44
- try {
45
- const updated = await dataAccessor.update(id, rest);
46
- return {
47
- success: true,
48
- data: updated,
49
- };
50
- }
51
- catch (error) {
52
- return {
53
- success: false,
54
- message: {
55
- text: error instanceof Error ? error.message : 'Failed to update entity',
56
- },
57
- };
58
- }
59
- }
60
- }));
61
- commandRegistry.register(`${entityKey}:Delete`, async () => ({
62
- execute: async (id) => {
63
- try {
64
- await dataAccessor.delete(id);
65
- return {
66
- success: true,
67
- };
68
- }
69
- catch (error) {
70
- return {
71
- success: false,
72
- message: {
73
- text: error instanceof Error ? error.message : 'Failed to delete entity',
74
- },
75
- };
76
- }
77
- }
78
- }));
79
- // Register Queries
80
- queryRegistry.register(`${entityKey}:GetById`, async () => ({
81
- fetch: (id) => dataAccessor.byKey(id)
82
- }));
83
- queryRegistry.register(`${entityKey}:GetList`, async () => ({
84
- fetch: (request) => dataAccessor.query(request)
85
- }));
86
- // Implement getRoots, getChildren, and getByCategory using query with appropriate filters
87
- queryRegistry.register(`${entityKey}:GetRoots`, async () => ({
88
- fetch: async (request) => {
89
- return await dataAccessor.query({
90
- skip: 0,
91
- take: 1000,
92
- filter: {
93
- field: 'parentId',
94
- operator: {
95
- type: 'isEmpty',
96
- },
97
- value: true,
98
- },
99
- });
100
- }
101
- }));
102
- queryRegistry.register(`${entityKey}:GetChildren`, async () => ({
103
- fetch: async (request) => {
104
- const parentKey = request.parentKey ?? 'parentId';
105
- return await dataAccessor.query({
106
- skip: 0,
107
- take: 1000,
108
- filter: {
109
- field: parentKey,
110
- operator: {
111
- type: 'equal',
112
- },
113
- value: request.parentId,
114
- },
115
- });
116
- }
117
- }));
118
- queryRegistry.register(`${entityKey}:GetByCategory`, async () => ({
119
- fetch: async (request) => {
120
- const categoryKey = request.categoryKey ?? 'categoryIds';
121
- return await dataAccessor.query({
122
- skip: 0,
123
- take: 1000,
124
- filter: {
125
- field: categoryKey,
126
- operator: {
127
- type: 'contains',
128
- },
129
- value: request.categoryId,
130
- },
131
- });
132
- }
133
- }));
134
- }
135
- return true;
136
- }
137
- },
138
- // {
139
- // provide: AXP_PERMISSION_DEFINITION_PROVIDER,
140
- // multi: true,
141
- // useFactory: () => {
142
- // const provider: AXPPermissionDefinitionProvider = {
143
- // define: async (context) => {
144
- // for (const entityKey of entityKeys) {
145
- // const group = entityKey.split('.')[0];
146
- // context.addGroup(group, group)
147
- // .addPermission(entityKey, entityKey)
148
- // .addChild(`${entityKey}:Create`, `${entityKey}:Create`)
149
- // .addChild(`${entityKey}:Update`, `${entityKey}:Update`)
150
- // .addChild(`${entityKey}:Delete`, `${entityKey}:Delete`)
151
- // .endPermission()
152
- // .endGroup();
153
- // }
154
- // }
155
- // }
156
- // return provider;
157
- // }
158
- // },
159
- // {
160
- // provide: AXP_ENTITY_CRUD_SETUP,
161
- // multi: true,
162
- // useFactory: () => {
163
- // return true;
164
- // }
165
- // }
166
- ]);
167
- }
11
+
12
+ //#endregion
13
+ //#region ---- Injection Token ----
14
+ const AXP_ENTITY_DEFINITION_CRUD_SERVICE = new InjectionToken('AXP_ENTITY_DEFINITION_CRUD_SERVICE', {
15
+ providedIn: null,
16
+ factory: () => null,
17
+ });
18
+ //#endregion
168
19
 
169
20
  //#region ---- Dependency Injection Tokens ----
170
21
  /**
171
- * Injection token for schema-specific middleware extensions.
172
- *
173
- * Used for targeted middleware that applies only to schemas matching
174
- * specific patterns (name or regex). This enables fine-grained control
175
- * over which schemas receive which middleware.
22
+ * Targeted middleware extension (name or regex) for property resolution.
176
23
  */
177
- const AXP_SCHEMA_EXTENSION = new InjectionToken('AXP_SCHEMA_EXTENSION');
24
+ const AXP_PROPERTY_EXTENSION = new InjectionToken('AXP_PROPERTY_EXTENSION');
178
25
  /**
179
- * Injection token for schema setup initialization.
180
- *
181
- * Used during application bootstrap to register schemas that are
182
- * known at build time. Multiple providers can use this token to
183
- * contribute schemas to the registry.
26
+ * Bootstrap hook: register property definitions known at build time.
184
27
  */
185
- const AXP_SCHEMA_SETUP = new InjectionToken('AXP_SCHEMA_SETUP');
28
+ const AXP_PROPERTY_SETUP = new InjectionToken('AXP_PROPERTY_SETUP');
186
29
  /**
187
- * Injection token for schema middleware setup initialization.
188
- *
189
- * Used during application bootstrap to register global middleware
190
- * that applies to all schema resolutions. This enables centralized
191
- * schema processing logic.
30
+ * Bootstrap hook: register global middleware for every property resolution.
192
31
  */
193
- const AXP_SCHEMA_MIDDLEWARE_SETUP = new InjectionToken('AXP_SCHEMA_MIDDLEWARE_SETUP');
32
+ const AXP_PROPERTY_MIDDLEWARE_SETUP = new InjectionToken('AXP_PROPERTY_MIDDLEWARE_SETUP');
194
33
  /**
195
- * Injection token for schema loader setup initialization.
196
- *
197
- * Used during application bootstrap to register schema loaders
198
- * that can provide schemas on-demand when they're not found in
199
- * the registry.
34
+ * Bootstrap hook: register on-demand property loaders.
200
35
  */
201
- const AXP_SCHEMA_LOADER_SETUP = new InjectionToken('AXP_SCHEMA_LOADER_SETUP');
36
+ const AXP_PROPERTY_LOADER_SETUP = new InjectionToken('AXP_PROPERTY_LOADER_SETUP');
202
37
  //#endregion
203
38
 
204
39
  //#region ---- Dependency Injection Tokens ----
@@ -240,15 +75,11 @@ class AXPDomainModule {
240
75
  constructor() {
241
76
  this._commandSetup = inject(AXP_ENTITY_CRUD_SETUP, { optional: true });
242
77
  /**
243
- * Injection token for schema setup initialization.
244
- *
245
- * Used during application bootstrap to register global middleware
246
- * that applies to all schema resolutions. This enables centralized
247
- * schema processing logic.
78
+ * Optional bootstrap hooks for registered property definitions (see {@link AXP_PROPERTY_SETUP} and related tokens).
248
79
  */
249
- this._schemaSetup = inject(AXP_SCHEMA_SETUP, { optional: true });
250
- this._schemaMiddlewareSetup = inject(AXP_SCHEMA_MIDDLEWARE_SETUP, { optional: true });
251
- this._schemaLoaderSetup = inject(AXP_SCHEMA_LOADER_SETUP, { optional: true });
80
+ this._propertySetup = inject(AXP_PROPERTY_SETUP, { optional: true });
81
+ this._propertyMiddlewareSetup = inject(AXP_PROPERTY_MIDDLEWARE_SETUP, { optional: true });
82
+ this._propertyLoaderSetup = inject(AXP_PROPERTY_LOADER_SETUP, { optional: true });
252
83
  /**
253
84
  * Injection token for domain loader setup initialization.
254
85
  *
@@ -260,11 +91,11 @@ class AXPDomainModule {
260
91
  this._domainMiddlewareSetup = inject(AXP_DOMAIN_MIDDLEWARE_SETUP, { optional: true });
261
92
  this._domainSetup = inject(AXP_DOMAIN_SETUP, { optional: true });
262
93
  }
263
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDomainModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
264
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.12", ngImport: i0, type: AXPDomainModule, imports: [AXPRuntimeModule] }); }
265
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDomainModule, imports: [AXPRuntimeModule] }); }
94
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDomainModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
95
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: AXPDomainModule, imports: [AXPRuntimeModule] }); }
96
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDomainModule, imports: [AXPRuntimeModule] }); }
266
97
  }
267
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDomainModule, decorators: [{
98
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDomainModule, decorators: [{
268
99
  type: NgModule,
269
100
  args: [{
270
101
  imports: [
@@ -273,6 +104,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
273
104
  }]
274
105
  }] });
275
106
 
107
+ var AXPDomainActionSide;
108
+ (function (AXPDomainActionSide) {
109
+ AXPDomainActionSide["Client"] = "client";
110
+ AXPDomainActionSide["Server"] = "server";
111
+ AXPDomainActionSide["Both"] = "both";
112
+ })(AXPDomainActionSide || (AXPDomainActionSide = {}));
276
113
  var AXPEntityCommandScope;
277
114
  (function (AXPEntityCommandScope) {
278
115
  AXPEntityCommandScope["TypeLevel"] = "typeLevel";
@@ -303,221 +140,31 @@ var AXPRelationshipCardinality;
303
140
  AXPRelationshipCardinality[AXPRelationshipCardinality["ManyToMany"] = 2] = "ManyToMany";
304
141
  })(AXPRelationshipCardinality || (AXPRelationshipCardinality = {}));
305
142
 
306
- //#region ---- AXPRelationModel ----
307
- /**
308
- * Runtime model for relation definitions with parent references and helper methods
309
- */
310
- class AXPRelationModel {
311
- constructor(definition, parent) {
312
- console.log('Relation Model Constructor', definition, parent);
313
- this.type = definition.type;
314
- this.kind = definition.kind;
315
- this.target = { ...definition.target };
316
- this.source = { ...definition.source };
317
- this.isRequired = definition.isRequired;
318
- this.parent = parent;
319
- }
320
- //#endregion
321
- //#region ---- Cardinality Methods ----
322
- /**
323
- * Check if relation is one-to-one
324
- */
325
- isOneToOne() {
326
- return this.type === AXPRelationshipCardinality.OneToOne;
327
- }
328
- /**
329
- * Check if relation is one-to-many
330
- */
331
- isOneToMany() {
332
- return this.type === AXPRelationshipCardinality.OneToMany;
333
- }
334
- /**
335
- * Check if relation is many-to-many
336
- */
337
- isManyToMany() {
338
- return this.type === AXPRelationshipCardinality.ManyToMany;
339
- }
340
- //#endregion
341
- //#region ---- Kind Methods ----
342
- /**
343
- * Check if relation is association
344
- */
345
- isAssociation() {
346
- return this.kind === AXPRelationshipKind.Association;
347
- }
348
- /**
349
- * Check if relation is composition
350
- */
351
- isComposition() {
352
- return this.kind === AXPRelationshipKind.Composition;
353
- }
354
- /**
355
- * Check if relation is aggregation
356
- */
357
- isAggregation() {
358
- return this.kind === AXPRelationshipKind.Aggregation;
359
- }
360
- //#endregion
361
- //#region ---- Navigation Methods ----
362
- /**
363
- * Get parent aggregate
364
- */
365
- getAggregate() {
366
- return this.parent;
367
- }
368
- /**
369
- * Get parent module
370
- */
371
- getModule() {
372
- return this.parent?.parent;
373
- }
374
- /**
375
- * Get full path (module.aggregate.relation)
376
- */
377
- getPath() {
378
- return `${this.parent.parent.name}.${this.parent.name}.${this.source.entity}->${this.target.entity}`;
379
- }
380
- //#endregion
381
- //#region ---- Query Methods ----
382
- /**
383
- * Get relation description
384
- */
385
- getDescription() {
386
- const cardinalityDesc = this.getCardinalityDescription();
387
- const kindDesc = this.getKindDescription();
388
- const requiredDesc = this.isRequired ? 'required' : 'optional';
389
- return `${cardinalityDesc} ${kindDesc} (${requiredDesc})`;
390
- }
391
- /**
392
- * Get cardinality description
393
- */
394
- getCardinalityDescription() {
395
- switch (this.type) {
396
- case AXPRelationshipCardinality.OneToOne:
397
- return 'one-to-one';
398
- case AXPRelationshipCardinality.OneToMany:
399
- return 'one-to-many';
400
- case AXPRelationshipCardinality.ManyToMany:
401
- return 'many-to-many';
402
- default:
403
- return 'unknown';
404
- }
405
- }
406
- /**
407
- * Get kind description
408
- */
409
- getKindDescription() {
410
- switch (this.kind) {
411
- case AXPRelationshipKind.Association:
412
- return 'association';
413
- case AXPRelationshipKind.Composition:
414
- return 'composition';
415
- case AXPRelationshipKind.Aggregation:
416
- return 'aggregation';
417
- default:
418
- return 'unknown';
419
- }
420
- }
421
- /**
422
- * Get relation summary
423
- */
424
- getSummary() {
425
- return `${this.source.entity}.${this.source.key} -> ${this.target.aggregate}.${this.target.entity}.${this.target.key}`;
426
- }
427
- //#endregion
428
- //#region ---- Validation Methods ----
429
- /**
430
- * Validate the relation structure
431
- */
432
- validate() {
433
- const errors = [];
434
- // Validate source
435
- if (!this.source.entity)
436
- errors.push('Source entity is required');
437
- if (!this.source.key)
438
- errors.push('Source key is required');
439
- // Validate target
440
- if (!this.target.aggregate)
441
- errors.push('Target aggregate is required');
442
- if (!this.target.entity)
443
- errors.push('Target entity is required');
444
- if (!this.target.key)
445
- errors.push('Target key is required');
446
- return errors;
447
- }
448
- //#endregion
449
- //#region ---- Utility Methods ----
450
- /**
451
- * Get relation characteristics
452
- */
453
- getCharacteristics() {
454
- return {
455
- type: this.getCardinalityDescription(),
456
- kind: this.getKindDescription(),
457
- required: this.isRequired,
458
- isOwning: this.isComposition(),
459
- isNavigable: !this.isComposition() || this.isOneToOne()
460
- };
461
- }
462
- /**
463
- * Check if relation involves entity
464
- */
465
- involvesEntity(entityName) {
466
- return this.source.entity === entityName || this.target.entity === entityName;
467
- }
468
- /**
469
- * Check if relation targets aggregate
470
- */
471
- targetsAggregate(aggregateName) {
472
- return this.target.aggregate === aggregateName;
473
- }
474
- /**
475
- * Get the other entity in the relation
476
- */
477
- getOtherEntity(entityName) {
478
- if (this.source.entity === entityName) {
479
- return this.target.entity;
480
- }
481
- else if (this.target.entity === entityName) {
482
- return this.source.entity;
483
- }
484
- return null;
485
- }
486
- /**
487
- * Convert back to interface definition
488
- */
489
- toDefinition() {
490
- return {
491
- type: this.type,
492
- kind: this.kind,
493
- target: { ...this.target },
494
- source: { ...this.source },
495
- isRequired: this.isRequired
496
- };
497
- }
498
- }
143
+ //#region ---- Serializable menu definition (storage / CRUD contract) ----
144
+ //#endregion
145
+
146
+ //#region ---- Serializable permission definition (storage / CRUD contract) ----
147
+ //#endregion
148
+
149
+ //#endregion
150
+
151
+ //#endregion
152
+
153
+ //#region ---- Widget catalog persisted record ----
154
+ //#endregion
499
155
 
500
156
  //#region ---- AXPAggregateModel ----
501
157
  /**
502
158
  * Simple runtime model for aggregate definitions with parent references and navigation helpers.
503
- *
504
- * This model is a pure data structure that provides:
505
- * - Access to aggregate properties and metadata
506
- * - Navigation helpers for finding relations and entity references
507
- * - Parent module reference for hierarchy navigation
508
- *
509
- * All loading and resolution logic has been moved to AXPDomainRegistry.
159
+ * Relations are stored in a separate collection; join when needed.
510
160
  */
511
161
  class AXPAggregateModel {
512
162
  constructor(definition, parent) {
513
- this.relations = [];
514
163
  this.name = definition.name;
515
164
  this.title = definition.title;
516
165
  this.validations = definition.validations || [];
517
166
  this.actions = definition.actions || [];
518
167
  this.parent = parent;
519
- // Initialize relations with parent reference
520
- this.relations = (definition.relations || []).map(relationDef => new AXPRelationModel(relationDef, this));
521
168
  // Extract entity references - convert all formats to simple string map
522
169
  this.entityReferences = this.extractEntityReferences(definition.entities);
523
170
  }
@@ -585,27 +232,6 @@ class AXPAggregateModel {
585
232
  hasEntity(entityName) {
586
233
  return entityName in this.entityReferences;
587
234
  }
588
- /**
589
- * Find relation by source and target entities
590
- *
591
- * @param sourceEntity Source entity name
592
- * @param targetEntity Target entity name
593
- * @returns Relation model or undefined if not found
594
- */
595
- findRelation(sourceEntity, targetEntity) {
596
- return this.relations.find(relation => relation.source.entity === sourceEntity &&
597
- relation.target.entity === targetEntity);
598
- }
599
- /**
600
- * Get all relations for a specific entity
601
- *
602
- * @param entityName Entity name
603
- * @returns Array of relations involving the entity
604
- */
605
- getEntityRelations(entityName) {
606
- return this.relations.filter(relation => relation.source.entity === entityName ||
607
- relation.target.entity === entityName);
608
- }
609
235
  //#endregion
610
236
  //#region ---- Parent Navigation ----
611
237
  /**
@@ -634,7 +260,6 @@ class AXPAggregateModel {
634
260
  getStatistics() {
635
261
  return {
636
262
  entityCount: Object.keys(this.entityReferences).length,
637
- relationCount: this.relations.length,
638
263
  actionCount: this.actions.length,
639
264
  validationCount: this.validations.length
640
265
  };
@@ -649,7 +274,6 @@ class AXPAggregateModel {
649
274
  name: this.name,
650
275
  title: this.title,
651
276
  entities: this.entityReferences, // Return as reference map
652
- relations: this.relations.map(relation => relation.toDefinition()),
653
277
  validations: this.validations,
654
278
  actions: this.actions
655
279
  };
@@ -668,13 +292,6 @@ class AXPAggregateModel {
668
292
  errors.push('Aggregate name is required');
669
293
  if (!this.title)
670
294
  errors.push('Aggregate title is required');
671
- // Validate relations
672
- this.relations.forEach(relation => {
673
- const relationErrors = relation.validate();
674
- if (relationErrors.length > 0) {
675
- errors.push(...relationErrors.map(err => `Relation: ${err}`));
676
- }
677
- });
678
295
  // Validate entity references
679
296
  for (const [entityName, entityRef] of Object.entries(this.entityReferences)) {
680
297
  if (!entityRef || typeof entityRef !== 'string') {
@@ -795,18 +412,11 @@ class AXPModuleModel {
795
412
  return allReferences;
796
413
  }
797
414
  /**
798
- * Get all relations across all aggregates
799
- *
800
- * @returns Array of all relation models
415
+ * Relations are stored in a separate collection. Use relation queries for join when needed.
416
+ * @deprecated Relations are no longer nested in aggregates.
801
417
  */
802
418
  getAllRelations() {
803
- const allRelations = [];
804
- for (const aggregate of this.aggregates) {
805
- for (const relation of aggregate.relations) {
806
- allRelations.push({ aggregate, relation });
807
- }
808
- }
809
- return allRelations;
419
+ return [];
810
420
  }
811
421
  //#endregion
812
422
  //#region ---- Validation Methods ----
@@ -837,135 +447,274 @@ class AXPModuleModel {
837
447
  }
838
448
  return errors;
839
449
  }
840
- //#endregion
841
- //#region ---- Utility Methods ----
450
+ //#endregion
451
+ //#region ---- Utility Methods ----
452
+ /**
453
+ * Get module statistics
454
+ *
455
+ * @returns Statistics object
456
+ */
457
+ getStatistics() {
458
+ const aggregateStats = this.aggregates.map(agg => agg.getStatistics());
459
+ return {
460
+ aggregateCount: this.aggregates.length,
461
+ entityCount: aggregateStats.reduce((sum, stat) => sum + stat.entityCount, 0),
462
+ actionCount: aggregateStats.reduce((sum, stat) => sum + stat.actionCount, 0),
463
+ validationCount: aggregateStats.reduce((sum, stat) => sum + stat.validationCount, 0)
464
+ };
465
+ }
466
+ /**
467
+ * Convert back to interface definition
468
+ *
469
+ * @returns Module definition
470
+ */
471
+ toDefinition() {
472
+ return {
473
+ name: this.name,
474
+ title: this.title,
475
+ aggregates: this.aggregates.map(agg => agg.toDefinition())
476
+ };
477
+ }
478
+ }
479
+ //#endregion
480
+
481
+ //#region ---- AXPPropertyModel ----
482
+ /**
483
+ * Runtime model for a {@link AXPPropertyDefinition} with helper methods.
484
+ */
485
+ class AXPPropertyModel {
486
+ constructor(definition) {
487
+ this.name = definition.name;
488
+ this.title = definition.title;
489
+ this.interface = definition.interface;
490
+ this.disabled = definition.disabled;
491
+ this.dataType = definition.dataType ?? 'string';
492
+ this.validations = definition.validations ?? [];
493
+ this.features = definition.features ?? {};
494
+ this.metadata = definition.metadata;
495
+ this.description = definition.description;
496
+ this.icon = definition.icon;
497
+ this.defaultValue = definition.defaultValue;
498
+ }
499
+ //#endregion
500
+ /**
501
+ * Get widget options
502
+ */
503
+ getWidgetOptions() {
504
+ return this.interface.options;
505
+ }
506
+ /**
507
+ * Check if the property is disabled
508
+ */
509
+ isDisabled() {
510
+ return this.disabled ?? false;
511
+ }
512
+ //#endregion
513
+ //#region ---- Feature Methods ----
514
+ /**
515
+ * Check if searchable
516
+ */
517
+ isSearchable() {
518
+ return this.features.searchable?.enabled ?? false;
519
+ }
520
+ /**
521
+ * Check if full text searchable
522
+ */
523
+ isFullTextSearchable() {
524
+ return this.features.searchable?.fullText ?? false;
525
+ }
526
+ /**
527
+ * Check if filterable
528
+ */
529
+ isFilterable() {
530
+ return this.features.filterable?.enabled ?? false;
531
+ }
532
+ /**
533
+ * Check if inline filterable
534
+ */
535
+ isInlineFilterable() {
536
+ return this.features.filterable?.inline ?? false;
537
+ }
538
+ /**
539
+ * Check if sortable
540
+ */
541
+ isSortable() {
542
+ return this.features.sortable?.enabled ?? false;
543
+ }
544
+ /**
545
+ * Check if auditable
546
+ */
547
+ isAuditable() {
548
+ return this.features.auditable?.enabled ?? false;
549
+ }
550
+ //#endregion
551
+ //#region ---- Validation Methods ----
552
+ /**
553
+ * Validate the property definition structure
554
+ */
555
+ async validate() {
556
+ const errors = [];
557
+ // Validate interface
558
+ if (!this.interface.name) {
559
+ errors.push('Widget type is required');
560
+ }
561
+ return errors;
562
+ }
563
+ //#endregion
564
+ //#region ---- Utility Methods ----
565
+ /**
566
+ * Get property capabilities
567
+ */
568
+ getCapabilities() {
569
+ return {
570
+ searchable: this.isSearchable(),
571
+ fullTextSearchable: this.isFullTextSearchable(),
572
+ filterable: this.isFilterable(),
573
+ inlineFilterable: this.isInlineFilterable(),
574
+ sortable: this.isSortable(),
575
+ auditable: this.isAuditable(),
576
+ disabled: this.isDisabled()
577
+ };
578
+ }
842
579
  /**
843
- * Get module statistics
844
- *
845
- * @returns Statistics object
580
+ * Get property summary
846
581
  */
847
- getStatistics() {
848
- const aggregateStats = this.aggregates.map(agg => agg.getStatistics());
582
+ getSummary() {
583
+ const capabilities = this.getCapabilities();
584
+ const capabilityCount = Object.values(capabilities).filter(Boolean).length;
849
585
  return {
850
- aggregateCount: this.aggregates.length,
851
- entityCount: aggregateStats.reduce((sum, stat) => sum + stat.entityCount, 0),
852
- relationCount: aggregateStats.reduce((sum, stat) => sum + stat.relationCount, 0),
853
- actionCount: aggregateStats.reduce((sum, stat) => sum + stat.actionCount, 0),
854
- validationCount: aggregateStats.reduce((sum, stat) => sum + stat.validationCount, 0)
586
+ widget: this.interface.name,
587
+ hasOptions: !!this.interface.options,
588
+ hasMetadata: !!this.metadata,
589
+ hasValidations: !!this.validations && this.validations.length > 0,
590
+ capabilityCount
855
591
  };
856
592
  }
857
593
  /**
858
594
  * Convert back to interface definition
859
- *
860
- * @returns Module definition
861
595
  */
862
596
  toDefinition() {
863
597
  return {
864
598
  name: this.name,
865
599
  title: this.title,
866
- aggregates: this.aggregates.map(agg => agg.toDefinition())
600
+ description: this.description,
601
+ icon: this.icon,
602
+ dataType: this.dataType,
603
+ defaultValue: this.defaultValue,
604
+ disabled: this.disabled,
605
+ interface: this.interface,
606
+ validations: this.validations,
607
+ features: this.features,
608
+ metadata: this.metadata
867
609
  };
868
610
  }
869
611
  }
870
- //#endregion
871
612
 
613
+ //#region ---- Property definition helpers ----
614
+ /**
615
+ * Strips entity-only fields so the payload matches {@link AXPPropertyDefinition}.
616
+ */
617
+ function toPropertyDefinition(def) {
618
+ const { actions, fieldFeatures, ...propertyDefinition } = def;
619
+ return propertyDefinition;
620
+ }
621
+ //#endregion
872
622
  //#region ---- AXPEntityFieldModel ----
873
623
  /**
874
624
  * Runtime model for entity field definitions with parent references and helper methods
875
625
  */
876
626
  class AXPEntityFieldModel {
877
- constructor(definition, parent, schemaService) {
627
+ constructor(definition, parent, propertyService) {
628
+ this.entityPropertyDefinition = definition;
878
629
  this.name = definition.name;
879
630
  this.title = definition.title;
880
631
  this.description = definition.description;
881
632
  this.validations = definition.validations;
882
633
  this.actions = definition.actions;
883
- this.features = definition.features;
634
+ this.fieldFeatures = definition.fieldFeatures;
884
635
  this.defaultValue = definition.defaultValue;
885
636
  this.parent = parent;
886
- this.schemaService = schemaService;
887
- // Store schema name for toDefinition
888
- this.schemaName = definition.schema;
889
- // Resolve schema by name from schema service
890
- this.schema = schemaService.resolveSync(definition.schema);
637
+ this.propertyService = propertyService;
638
+ this.property = new AXPPropertyModel(toPropertyDefinition(definition));
639
+ this.propertyName = definition.name;
891
640
  }
892
- //#endregion
893
641
  //#region ---- Feature Check Methods ----
894
642
  /**
895
643
  * Check if field is nullable
896
644
  */
897
645
  isNullable() {
898
- return this.features?.nullable ?? false;
646
+ return this.fieldFeatures?.nullable ?? false;
899
647
  }
900
648
  /**
901
649
  * Check if field is readonly
902
650
  */
903
651
  isReadonly() {
904
- return this.features?.readOnly ?? false;
652
+ return this.fieldFeatures?.readOnly ?? false;
905
653
  }
906
654
  /**
907
655
  * Check if field is required (has required validation)
908
656
  */
909
657
  isRequired() {
910
- return this.validations?.some(validation => validation.rule === 'required') ?? false;
658
+ return this.validations?.some((validation) => validation.rule === "required") ?? false;
911
659
  }
912
660
  /**
913
661
  * Check if field is searchable
914
662
  */
915
663
  isSearchable() {
916
- return this.schema.features?.searchable?.enabled ?? false;
664
+ return this.property.features?.searchable?.enabled ?? false;
917
665
  }
918
666
  /**
919
667
  * Check if field supports full text search
920
668
  */
921
669
  isFullTextSearchable() {
922
- return this.schema.features?.searchable?.fullText ?? false;
670
+ return this.property.features?.searchable?.fullText ?? false;
923
671
  }
924
672
  /**
925
673
  * Check if field is filterable
926
674
  */
927
675
  isFilterable() {
928
- return this.schema.features?.filterable?.enabled ?? false;
676
+ return this.property.features?.filterable?.enabled ?? false;
929
677
  }
930
678
  /**
931
679
  * Check if field has inline filtering
932
680
  */
933
681
  hasInlineFiltering() {
934
- return this.schema.features?.filterable?.inline ?? false;
682
+ return this.property.features?.filterable?.inline ?? false;
935
683
  }
936
684
  /**
937
685
  * Check if field is sortable
938
686
  */
939
687
  isSortable() {
940
- return this.schema.features?.sortable?.enabled ?? false;
688
+ return this.property.features?.sortable?.enabled ?? false;
941
689
  }
942
690
  /**
943
691
  * Check if field is auditable
944
692
  */
945
693
  isAuditable() {
946
- return this.schema.features?.auditable?.enabled ?? false;
694
+ return this.property.features?.auditable?.enabled ?? false;
947
695
  }
948
696
  //#endregion
949
- //#region ---- Schema Methods ----
697
+ //#region ---- Property info ----
950
698
  /**
951
- * Get the schema name
699
+ * Registered property name (same as entity field name in the embedded model).
952
700
  */
953
- getSchemaName() {
954
- return this.schemaName;
701
+ getPropertyName() {
702
+ return this.propertyName;
955
703
  }
956
704
  /**
957
- * Get schema info from registry
705
+ * Registration metadata when this field's definition name is registered; otherwise embedded summary.
958
706
  */
959
- getSchemaInfo() {
960
- return this.schemaService.getSchemaInfo(this.schemaName);
707
+ getPropertyInfo() {
708
+ if (this.propertyService.isRegistered(this.property.name)) {
709
+ return this.propertyService.getRegisteredProperty(this.property.name);
710
+ }
711
+ return this.property.getSummary();
961
712
  }
962
713
  /**
963
- * Re-resolve schema from registry (useful after schema updates)
714
+ * Rebuild the property model from embedded definition (e.g. after definition updates).
964
715
  */
965
- refreshSchema() {
966
- const newSchema = this.schemaService.resolveSync(this.schemaName);
967
- this.schema = newSchema;
968
- this.schema.parent = this;
716
+ refreshProperty() {
717
+ this.property = new AXPPropertyModel(toPropertyDefinition(this.entityPropertyDefinition));
969
718
  }
970
719
  //#endregion
971
720
  //#region ---- Navigation Methods ----
@@ -1000,25 +749,17 @@ class AXPEntityFieldModel {
1000
749
  */
1001
750
  async validate() {
1002
751
  const errors = [];
1003
- // Validate field structure
1004
752
  if (!this.name)
1005
- errors.push('Field name is required');
753
+ errors.push("Field name is required");
1006
754
  if (!this.title)
1007
- errors.push('Field title is required');
1008
- // Validate schema name
1009
- if (!this.schemaName) {
1010
- errors.push('Schema name is required');
1011
- }
1012
- else {
1013
- if (!this.schemaService.isRegistered(this.schemaName)) {
1014
- errors.push(`Schema '${this.schemaName}' is not registered`);
1015
- }
1016
- }
1017
- // Validate schema if it exists
1018
- if (this.schema) {
1019
- const schemaErrors = await this.schema.validate();
1020
- if (schemaErrors.length > 0) {
1021
- errors.push(...schemaErrors.map(err => `Schema: ${err}`));
755
+ errors.push("Field title is required");
756
+ if (!this.property.interface?.name) {
757
+ errors.push("Widget type (interface.name) is required");
758
+ }
759
+ if (this.property) {
760
+ const propertyErrors = await this.property.validate();
761
+ if (propertyErrors.length > 0) {
762
+ errors.push(...propertyErrors.map((err) => `Property: ${err}`));
1022
763
  }
1023
764
  }
1024
765
  return errors;
@@ -1032,10 +773,10 @@ class AXPEntityFieldModel {
1032
773
  return {
1033
774
  hasValidations: !!this.validations && this.validations.length > 0,
1034
775
  hasActions: !!this.actions && this.actions.length > 0,
1035
- hasFeatures: !!this.features,
776
+ hasFieldFeatures: !!this.fieldFeatures,
1036
777
  hasDefaultValue: this.defaultValue !== undefined,
1037
778
  validationCount: this.validations?.length ?? 0,
1038
- actionCount: this.actions?.length ?? 0
779
+ actionCount: this.actions?.length ?? 0,
1039
780
  };
1040
781
  }
1041
782
  /**
@@ -1049,7 +790,7 @@ class AXPEntityFieldModel {
1049
790
  auditable: this.isAuditable(),
1050
791
  nullable: this.isNullable(),
1051
792
  readonly: this.isReadonly(),
1052
- required: this.isRequired()
793
+ required: this.isRequired(),
1053
794
  };
1054
795
  }
1055
796
  /**
@@ -1057,32 +798,28 @@ class AXPEntityFieldModel {
1057
798
  */
1058
799
  toDefinition() {
1059
800
  return {
1060
- name: this.name,
1061
- title: this.title,
1062
- description: this.description,
1063
- validations: this.validations,
801
+ ...this.property.toDefinition(),
1064
802
  actions: this.actions,
1065
- features: this.features,
1066
- defaultValue: this.defaultValue,
1067
- schema: this.schemaName
803
+ fieldFeatures: this.fieldFeatures,
1068
804
  };
1069
805
  }
1070
806
  }
807
+ //#endregion
1071
808
 
1072
809
  //#region ---- AXPEntityModel ----
1073
810
  /**
1074
811
  * Runtime model for entity definitions with parent references and helper methods
1075
812
  */
1076
813
  class AXPEntityModel {
1077
- constructor(definition, parent, schemaService) {
814
+ constructor(definition, parent, propertyService) {
1078
815
  this.fields = [];
1079
816
  this.name = definition.name;
1080
817
  this.title = definition.title;
1081
818
  this.type = definition.type;
1082
819
  this.parent = parent;
1083
- this.schemaService = schemaService;
1084
- // Initialize fields with parent reference and schema service
1085
- this.fields = definition.fields.map(fieldDef => new AXPEntityFieldModel(fieldDef, this, schemaService));
820
+ this.propertyService = propertyService;
821
+ // Initialize fields with parent reference and property service
822
+ this.fields = definition.fields.map(fieldDef => new AXPEntityFieldModel(fieldDef, this, propertyService));
1086
823
  }
1087
824
  //#endregion
1088
825
  //#region ---- Query Methods ----
@@ -1098,12 +835,6 @@ class AXPEntityModel {
1098
835
  getAllFields() {
1099
836
  return [...this.fields];
1100
837
  }
1101
- /**
1102
- * Get fields by data type
1103
- */
1104
- getFieldsByType(dataType) {
1105
- return this.fields.filter(field => field.schema.dataType === dataType);
1106
- }
1107
838
  /**
1108
839
  * Get required fields
1109
840
  */
@@ -1223,181 +954,196 @@ class AXPEntityModel {
1223
954
  }
1224
955
  }
1225
956
 
1226
- //#region ---- AXPSchemaModel ----
957
+ //#region ---- AXPRelationModel ----
1227
958
  /**
1228
- * Runtime model for schema definitions with helper methods
959
+ * Runtime model for standalone relation definitions.
960
+ * Relations live in their own collection; join when needed.
1229
961
  */
1230
- class AXPSchemaModel {
1231
- constructor(definition) {
1232
- this.name = definition.name;
1233
- this.dataType = definition.dataType;
1234
- this.interface = definition.interface;
1235
- this.validations = definition.validations ?? [];
1236
- this.features = definition.features ?? {};
1237
- this.metadata = definition.metadata;
962
+ class AXPRelationModel {
963
+ constructor(definition, parent) {
964
+ this.type = definition.type;
965
+ this.kind = definition.kind;
966
+ this.target = { ...definition.target };
967
+ this.source = { ...definition.source };
968
+ this.isRequired = definition.isRequired;
969
+ this.parent = parent;
1238
970
  }
1239
971
  //#endregion
1240
- //#region ---- Data Type Methods ----
1241
- /**
1242
- * Check if schema is for string data
1243
- */
1244
- isString() {
1245
- return this.dataType === 'string';
1246
- }
972
+ //#region ---- Cardinality Methods ----
1247
973
  /**
1248
- * Check if schema is for number data
974
+ * Check if relation is one-to-one
1249
975
  */
1250
- isNumber() {
1251
- return this.dataType === 'number';
976
+ isOneToOne() {
977
+ return this.type === AXPRelationshipCardinality.OneToOne;
1252
978
  }
1253
979
  /**
1254
- * Check if schema is for boolean data
980
+ * Check if relation is one-to-many
1255
981
  */
1256
- isBoolean() {
1257
- return this.dataType === 'boolean';
982
+ isOneToMany() {
983
+ return this.type === AXPRelationshipCardinality.OneToMany;
1258
984
  }
1259
985
  /**
1260
- * Check if schema is for date data
986
+ * Check if relation is many-to-many
1261
987
  */
1262
- isDate() {
1263
- return this.dataType === 'date';
988
+ isManyToMany() {
989
+ return this.type === AXPRelationshipCardinality.ManyToMany;
1264
990
  }
991
+ //#endregion
992
+ //#region ---- Kind Methods ----
1265
993
  /**
1266
- * Check if schema is for object data
994
+ * Check if relation is association
1267
995
  */
1268
- isObject() {
1269
- return this.dataType === 'object';
996
+ isAssociation() {
997
+ return this.kind === AXPRelationshipKind.Association;
1270
998
  }
1271
999
  /**
1272
- * Check if schema is for array data
1000
+ * Check if relation is composition
1273
1001
  */
1274
- isArray() {
1275
- return this.dataType === 'array';
1002
+ isComposition() {
1003
+ return this.kind === AXPRelationshipKind.Composition;
1276
1004
  }
1277
1005
  /**
1278
- * Check if schema is for blob data
1006
+ * Check if relation is aggregation
1279
1007
  */
1280
- isBlob() {
1281
- return this.dataType === 'blob';
1008
+ isAggregation() {
1009
+ return this.kind === AXPRelationshipKind.Aggregation;
1282
1010
  }
1283
1011
  //#endregion
1284
- //#region ---- Interface Methods ----
1012
+ //#region ---- Navigation Methods ----
1285
1013
  /**
1286
- * Get widget type
1014
+ * Get parent aggregate
1287
1015
  */
1288
- getWidgetType() {
1289
- return this.interface.widget;
1016
+ getAggregate() {
1017
+ return this.parent;
1290
1018
  }
1291
1019
  /**
1292
- * Get widget options
1020
+ * Get parent module
1293
1021
  */
1294
- getWidgetOptions() {
1295
- return this.interface.options;
1022
+ getModule() {
1023
+ return this.parent?.parent;
1296
1024
  }
1297
1025
  /**
1298
- * Check if interface is disabled
1026
+ * Get full path (module.aggregate.relation)
1299
1027
  */
1300
- isDisabled() {
1301
- return this.interface.disabled ?? false;
1028
+ getPath() {
1029
+ return `${this.parent.parent.name}.${this.parent.name}.${this.source.entity}->${this.target.entity}`;
1302
1030
  }
1303
1031
  //#endregion
1304
- //#region ---- Feature Methods ----
1305
- /**
1306
- * Check if searchable
1307
- */
1308
- isSearchable() {
1309
- return this.features.searchable?.enabled ?? false;
1310
- }
1311
- /**
1312
- * Check if full text searchable
1313
- */
1314
- isFullTextSearchable() {
1315
- return this.features.searchable?.fullText ?? false;
1316
- }
1032
+ //#region ---- Query Methods ----
1317
1033
  /**
1318
- * Check if filterable
1034
+ * Get relation description
1319
1035
  */
1320
- isFilterable() {
1321
- return this.features.filterable?.enabled ?? false;
1036
+ getDescription() {
1037
+ const cardinalityDesc = this.getCardinalityDescription();
1038
+ const kindDesc = this.getKindDescription();
1039
+ const requiredDesc = this.isRequired ? 'required' : 'optional';
1040
+ return `${cardinalityDesc} ${kindDesc} (${requiredDesc})`;
1322
1041
  }
1323
1042
  /**
1324
- * Check if inline filterable
1043
+ * Get cardinality description
1325
1044
  */
1326
- isInlineFilterable() {
1327
- return this.features.filterable?.inline ?? false;
1045
+ getCardinalityDescription() {
1046
+ switch (this.type) {
1047
+ case AXPRelationshipCardinality.OneToOne:
1048
+ return 'one-to-one';
1049
+ case AXPRelationshipCardinality.OneToMany:
1050
+ return 'one-to-many';
1051
+ case AXPRelationshipCardinality.ManyToMany:
1052
+ return 'many-to-many';
1053
+ default:
1054
+ return 'unknown';
1055
+ }
1328
1056
  }
1329
1057
  /**
1330
- * Check if sortable
1058
+ * Get kind description
1331
1059
  */
1332
- isSortable() {
1333
- return this.features.sortable?.enabled ?? false;
1060
+ getKindDescription() {
1061
+ switch (this.kind) {
1062
+ case AXPRelationshipKind.Association:
1063
+ return 'association';
1064
+ case AXPRelationshipKind.Composition:
1065
+ return 'composition';
1066
+ case AXPRelationshipKind.Aggregation:
1067
+ return 'aggregation';
1068
+ default:
1069
+ return 'unknown';
1070
+ }
1334
1071
  }
1335
1072
  /**
1336
- * Check if auditable
1073
+ * Get relation summary
1337
1074
  */
1338
- isAuditable() {
1339
- return this.features.auditable?.enabled ?? false;
1075
+ getSummary() {
1076
+ return `${this.source.entity}.${this.source.key} -> ${this.target.aggregate}.${this.target.entity}.${this.target.key}`;
1340
1077
  }
1341
1078
  //#endregion
1342
1079
  //#region ---- Validation Methods ----
1343
1080
  /**
1344
- * Validate the schema structure
1081
+ * Validate the relation structure
1345
1082
  */
1346
- async validate() {
1083
+ validate() {
1347
1084
  const errors = [];
1348
- // Validate data type
1349
- const validDataTypes = ['string', 'number', 'boolean', 'date', 'object', 'array', 'blob'];
1350
- if (!validDataTypes.includes(this.dataType)) {
1351
- errors.push(`Invalid data type: ${this.dataType}`);
1352
- }
1353
- // Validate interface
1354
- if (!this.interface.widget) {
1355
- errors.push('Widget type is required');
1356
- }
1085
+ // Validate source
1086
+ if (!this.source.entity)
1087
+ errors.push('Source entity is required');
1088
+ if (!this.source.key)
1089
+ errors.push('Source key is required');
1090
+ // Validate target
1091
+ if (!this.target.aggregate)
1092
+ errors.push('Target aggregate is required');
1093
+ if (!this.target.entity)
1094
+ errors.push('Target entity is required');
1095
+ if (!this.target.key)
1096
+ errors.push('Target key is required');
1357
1097
  return errors;
1358
1098
  }
1359
1099
  //#endregion
1360
1100
  //#region ---- Utility Methods ----
1361
1101
  /**
1362
- * Get schema capabilities
1102
+ * Get relation characteristics
1363
1103
  */
1364
- getCapabilities() {
1104
+ getCharacteristics() {
1365
1105
  return {
1366
- searchable: this.isSearchable(),
1367
- fullTextSearchable: this.isFullTextSearchable(),
1368
- filterable: this.isFilterable(),
1369
- inlineFilterable: this.isInlineFilterable(),
1370
- sortable: this.isSortable(),
1371
- auditable: this.isAuditable(),
1372
- disabled: this.isDisabled()
1106
+ type: this.getCardinalityDescription(),
1107
+ kind: this.getKindDescription(),
1108
+ required: this.isRequired,
1109
+ isOwning: this.isComposition(),
1110
+ isNavigable: !this.isComposition() || this.isOneToOne()
1373
1111
  };
1374
1112
  }
1375
1113
  /**
1376
- * Get schema summary
1114
+ * Check if relation involves entity
1377
1115
  */
1378
- getSummary() {
1379
- const capabilities = this.getCapabilities();
1380
- const capabilityCount = Object.values(capabilities).filter(Boolean).length;
1381
- return {
1382
- dataType: this.dataType,
1383
- widget: this.getWidgetType(),
1384
- hasOptions: !!this.interface.options,
1385
- hasMetadata: !!this.metadata,
1386
- hasValidations: !!this.validations && this.validations.length > 0,
1387
- capabilityCount
1388
- };
1116
+ involvesEntity(entityName) {
1117
+ return this.source.entity === entityName || this.target.entity === entityName;
1389
1118
  }
1390
1119
  /**
1391
- * Convert back to interface definition
1120
+ * Check if relation targets aggregate
1121
+ */
1122
+ targetsAggregate(aggregateName) {
1123
+ return this.target.aggregate === aggregateName;
1124
+ }
1125
+ /**
1126
+ * Get the other entity in the relation
1127
+ */
1128
+ getOtherEntity(entityName) {
1129
+ if (this.source.entity === entityName) {
1130
+ return this.target.entity;
1131
+ }
1132
+ else if (this.target.entity === entityName) {
1133
+ return this.source.entity;
1134
+ }
1135
+ return null;
1136
+ }
1137
+ /**
1138
+ * Convert back to interface definition (AXPRelationDefinition with full source/target)
1392
1139
  */
1393
1140
  toDefinition() {
1394
1141
  return {
1395
- name: this.name,
1396
- dataType: this.dataType,
1397
- interface: this.interface,
1398
- validations: this.validations,
1399
- features: this.features,
1400
- metadata: this.metadata
1142
+ type: this.type,
1143
+ kind: this.kind,
1144
+ target: { ...this.target },
1145
+ source: { ...this.source },
1146
+ isRequired: this.isRequired
1401
1147
  };
1402
1148
  }
1403
1149
  }
@@ -1471,10 +1217,10 @@ class AXPModuleHelper {
1471
1217
  return [];
1472
1218
  }
1473
1219
  /**
1474
- * @deprecated Use AXPDomainService with field schema queries instead
1220
+ * @deprecated Use AXPDomainService with registered property name queries instead
1475
1221
  */
1476
- static findFieldsBySchema(module, schemaName) {
1477
- console.warn('AXPModuleHelper.findFieldsBySchema is deprecated. Use AXPDomainService instead.');
1222
+ static findFieldsByRegisteredPropertyName(module, propertyName) {
1223
+ console.warn('AXPModuleHelper.findFieldsByRegisteredPropertyName is deprecated. Use AXPDomainService instead.');
1478
1224
  return [];
1479
1225
  }
1480
1226
  /**
@@ -1545,23 +1291,23 @@ class AXPModuleHelper {
1545
1291
  * }
1546
1292
  * ```
1547
1293
  */
1548
- class AXPSchemaMiddlewareContext {
1549
- constructor(schema) {
1550
- // Deep clone to avoid mutating the original schema
1551
- this._schema = JSON.parse(JSON.stringify(schema));
1294
+ class AXPPropertyMiddlewareContext {
1295
+ constructor(definition) {
1296
+ // Deep clone to avoid mutating the original definition
1297
+ this._definition = JSON.parse(JSON.stringify(definition));
1552
1298
  }
1553
1299
  //#region ---- Schema Access Properties ----
1554
1300
  /**
1555
1301
  * Get the current schema definition (readonly access)
1556
1302
  */
1557
- get schema() {
1558
- return this._schema;
1303
+ get definition() {
1304
+ return this._definition;
1559
1305
  }
1560
1306
  /**
1561
1307
  * Get the schema name for conditional logic
1562
1308
  */
1563
1309
  get name() {
1564
- return this._schema.name;
1310
+ return this._definition.name;
1565
1311
  }
1566
1312
  //#endregion
1567
1313
  //#region ---- Default Value Management ----
@@ -1570,18 +1316,18 @@ class AXPSchemaMiddlewareContext {
1570
1316
  * @param defaultValue The default value to set
1571
1317
  */
1572
1318
  withDefaultValue(defaultValue) {
1573
- if (!this._schema.interface.options) {
1574
- this._schema.interface.options = {};
1319
+ if (!this._definition.interface.options) {
1320
+ this._definition.interface.options = {};
1575
1321
  }
1576
- this._schema.interface.options['defaultValue'] = defaultValue;
1322
+ this._definition.interface.options['defaultValue'] = defaultValue;
1577
1323
  return this;
1578
1324
  }
1579
1325
  /**
1580
1326
  * Remove the default value from the widget
1581
1327
  */
1582
1328
  removeDefaultValue() {
1583
- if (this._schema.interface.options) {
1584
- delete this._schema.interface.options['defaultValue'];
1329
+ if (this._definition.interface.options) {
1330
+ delete this._definition.interface.options['defaultValue'];
1585
1331
  }
1586
1332
  return this;
1587
1333
  }
@@ -1592,10 +1338,10 @@ class AXPSchemaMiddlewareContext {
1592
1338
  * @param rules Array of validation rules to add
1593
1339
  */
1594
1340
  withValidation(rules) {
1595
- if (!this._schema.validations) {
1596
- this._schema.validations = [];
1341
+ if (!this._definition.validations) {
1342
+ this._definition.validations = [];
1597
1343
  }
1598
- this._schema.validations.push(...rules);
1344
+ this._definition.validations.push(...rules);
1599
1345
  return this;
1600
1346
  }
1601
1347
  /**
@@ -1603,10 +1349,10 @@ class AXPSchemaMiddlewareContext {
1603
1349
  * @param rule The validation rule to add
1604
1350
  */
1605
1351
  addValidation(rule) {
1606
- if (!this._schema.validations) {
1607
- this._schema.validations = [];
1352
+ if (!this._definition.validations) {
1353
+ this._definition.validations = [];
1608
1354
  }
1609
- this._schema.validations.push(rule);
1355
+ this._definition.validations.push(rule);
1610
1356
  return this;
1611
1357
  }
1612
1358
  /**
@@ -1620,7 +1366,7 @@ class AXPSchemaMiddlewareContext {
1620
1366
  * Remove all validation rules from the schema
1621
1367
  */
1622
1368
  clearValidations() {
1623
- this._schema.validations = [];
1369
+ this._definition.validations = [];
1624
1370
  return this;
1625
1371
  }
1626
1372
  /**
@@ -1628,8 +1374,8 @@ class AXPSchemaMiddlewareContext {
1628
1374
  * @param ruleName The name of the rule to remove (e.g., 'required', 'email')
1629
1375
  */
1630
1376
  removeValidation(ruleName) {
1631
- if (this._schema.validations) {
1632
- this._schema.validations = this._schema.validations.filter(v => v.rule !== ruleName);
1377
+ if (this._definition.validations) {
1378
+ this._definition.validations = this._definition.validations.filter((v) => v.rule !== ruleName);
1633
1379
  }
1634
1380
  return this;
1635
1381
  }
@@ -1640,8 +1386,9 @@ class AXPSchemaMiddlewareContext {
1640
1386
  * @param options Object containing widget-specific options to merge
1641
1387
  */
1642
1388
  withWidgetOptions(options) {
1643
- this._schema.interface.options = {
1644
- ...this._schema.interface.options,
1389
+ const current = this._definition.interface.options ?? {};
1390
+ this._definition.interface.options = {
1391
+ ...current,
1645
1392
  ...options
1646
1393
  };
1647
1394
  return this;
@@ -1651,8 +1398,8 @@ class AXPSchemaMiddlewareContext {
1651
1398
  * @param optionKey The key of the option to remove
1652
1399
  */
1653
1400
  removeWidgetOption(optionKey) {
1654
- if (this._schema.interface.options) {
1655
- delete this._schema.interface.options[optionKey];
1401
+ if (this._definition.interface.options) {
1402
+ delete this._definition.interface.options[optionKey];
1656
1403
  }
1657
1404
  return this;
1658
1405
  }
@@ -1661,7 +1408,7 @@ class AXPSchemaMiddlewareContext {
1661
1408
  * @param widgetType The new widget type identifier
1662
1409
  */
1663
1410
  withWidgetType(widgetType) {
1664
- this._schema.interface.widget = widgetType;
1411
+ this._definition.interface.name = widgetType;
1665
1412
  return this;
1666
1413
  }
1667
1414
  //#endregion
@@ -1671,8 +1418,8 @@ class AXPSchemaMiddlewareContext {
1671
1418
  * @param features Object containing feature configurations to merge
1672
1419
  */
1673
1420
  withFeatures(features) {
1674
- this._schema.features = {
1675
- ...this._schema.features,
1421
+ this._definition.features = {
1422
+ ...this._definition.features,
1676
1423
  ...features
1677
1424
  };
1678
1425
  return this;
@@ -1683,10 +1430,10 @@ class AXPSchemaMiddlewareContext {
1683
1430
  * @param fullText Whether full-text search is enabled
1684
1431
  */
1685
1432
  searchable(enabled = true, fullText = false) {
1686
- if (!this._schema.features) {
1687
- this._schema.features = {};
1433
+ if (!this._definition.features) {
1434
+ this._definition.features = {};
1688
1435
  }
1689
- this._schema.features.searchable = { enabled, fullText };
1436
+ this._definition.features.searchable = { enabled, fullText };
1690
1437
  return this;
1691
1438
  }
1692
1439
  /**
@@ -1695,10 +1442,10 @@ class AXPSchemaMiddlewareContext {
1695
1442
  * @param inline Whether inline filtering is supported
1696
1443
  */
1697
1444
  filterable(enabled = true, inline = false) {
1698
- if (!this._schema.features) {
1699
- this._schema.features = {};
1445
+ if (!this._definition.features) {
1446
+ this._definition.features = {};
1700
1447
  }
1701
- this._schema.features.filterable = { enabled, inline };
1448
+ this._definition.features.filterable = { enabled, inline };
1702
1449
  return this;
1703
1450
  }
1704
1451
  /**
@@ -1706,10 +1453,10 @@ class AXPSchemaMiddlewareContext {
1706
1453
  * @param enabled Whether sorting is enabled
1707
1454
  */
1708
1455
  sortable(enabled = true) {
1709
- if (!this._schema.features) {
1710
- this._schema.features = {};
1456
+ if (!this._definition.features) {
1457
+ this._definition.features = {};
1711
1458
  }
1712
- this._schema.features.sortable = { enabled };
1459
+ this._definition.features.sortable = { enabled };
1713
1460
  return this;
1714
1461
  }
1715
1462
  //#endregion
@@ -1719,8 +1466,8 @@ class AXPSchemaMiddlewareContext {
1719
1466
  * @param metadata Object containing metadata to merge
1720
1467
  */
1721
1468
  withMetadata(metadata) {
1722
- this._schema.metadata = {
1723
- ...this._schema.metadata,
1469
+ this._definition.metadata = {
1470
+ ...this._definition.metadata,
1724
1471
  ...metadata
1725
1472
  };
1726
1473
  return this;
@@ -1730,29 +1477,19 @@ class AXPSchemaMiddlewareContext {
1730
1477
  * @param key The metadata key to remove
1731
1478
  */
1732
1479
  removeMetadata(key) {
1733
- if (this._schema.metadata) {
1734
- delete this._schema.metadata[key];
1480
+ if (this._definition.metadata) {
1481
+ delete this._definition.metadata[key];
1735
1482
  }
1736
1483
  return this;
1737
1484
  }
1738
1485
  //#endregion
1739
- //#region ---- Schema Properties ----
1740
- /**
1741
- * Set the data type for this schema
1742
- * @param dataType The new data type (string, number, boolean, etc.)
1743
- */
1744
- withDataType(dataType) {
1745
- this._schema.dataType = dataType;
1746
- return this;
1747
- }
1748
- //#endregion
1749
1486
  //#region ---- UI State Management ----
1750
1487
  /**
1751
1488
  * Set the disabled state of the widget
1752
1489
  * @param isDisabled Whether the widget should be disabled
1753
1490
  */
1754
1491
  disabled(isDisabled = true) {
1755
- this._schema.interface.disabled = isDisabled;
1492
+ this._definition.disabled = isDisabled;
1756
1493
  return this;
1757
1494
  }
1758
1495
  /**
@@ -1760,10 +1497,10 @@ class AXPSchemaMiddlewareContext {
1760
1497
  * @param visible Whether the widget should be visible
1761
1498
  */
1762
1499
  withVisibility(visible) {
1763
- if (!this._schema.interface.options) {
1764
- this._schema.interface.options = {};
1500
+ if (!this._definition.interface.options) {
1501
+ this._definition.interface.options = {};
1765
1502
  }
1766
- this._schema.interface.options['visible'] = visible;
1503
+ this._definition.interface.options['visible'] = visible;
1767
1504
  return this;
1768
1505
  }
1769
1506
  /**
@@ -1771,10 +1508,10 @@ class AXPSchemaMiddlewareContext {
1771
1508
  * @param isReadonly Whether the widget should be readonly
1772
1509
  */
1773
1510
  readonly(isReadonly = true) {
1774
- if (!this._schema.interface.options) {
1775
- this._schema.interface.options = {};
1511
+ if (!this._definition.interface.options) {
1512
+ this._definition.interface.options = {};
1776
1513
  }
1777
- this._schema.interface.options['readonly'] = isReadonly;
1514
+ this._definition.interface.options['readonly'] = isReadonly;
1778
1515
  return this;
1779
1516
  }
1780
1517
  }
@@ -1792,9 +1529,9 @@ class AXPSchemaMiddlewareContext {
1792
1529
  * - On-demand schema loading
1793
1530
  * - Caching and performance optimization
1794
1531
  */
1795
- class AXPSchemaRegistry {
1532
+ class AXPPropertyRegistry {
1796
1533
  constructor() {
1797
- this._schemas = new Map();
1534
+ this._registrations = new Map();
1798
1535
  this._globalMiddleware = [];
1799
1536
  this._modelCache = new Map();
1800
1537
  this._loaders = null;
@@ -1805,7 +1542,7 @@ class AXPSchemaRegistry {
1805
1542
  */
1806
1543
  register(definition, options = {}) {
1807
1544
  if (!definition.name || definition.name.trim() === '') {
1808
- throw new Error('Schema name is required and cannot be empty');
1545
+ throw new Error('Property name is required and cannot be empty');
1809
1546
  }
1810
1547
  const registered = {
1811
1548
  name: definition.name,
@@ -1813,23 +1550,22 @@ class AXPSchemaRegistry {
1813
1550
  options,
1814
1551
  registeredAt: new Date()
1815
1552
  };
1816
- this._schemas.set(definition.name, registered);
1553
+ this._registrations.set(definition.name, registered);
1817
1554
  this.invalidateCache(definition.name);
1818
- console.log(`Schema '${definition.name}' registered successfully`);
1819
1555
  }
1820
1556
  /**
1821
1557
  * Register multiple schemas at once for batch operations
1822
1558
  */
1823
- registerBatch(schemas) {
1824
- for (const schema of schemas) {
1825
- this.register(schema.definition, schema.options || {});
1559
+ registerBatch(entries) {
1560
+ for (const entry of entries) {
1561
+ this.register(entry.definition, entry.options || {});
1826
1562
  }
1827
1563
  }
1828
1564
  /**
1829
1565
  * Remove a schema from the registry
1830
1566
  */
1831
1567
  unregister(name) {
1832
- const removed = this._schemas.delete(name);
1568
+ const removed = this._registrations.delete(name);
1833
1569
  if (removed) {
1834
1570
  this.invalidateCache(name);
1835
1571
  }
@@ -1839,7 +1575,7 @@ class AXPSchemaRegistry {
1839
1575
  * Check if a schema is currently registered
1840
1576
  */
1841
1577
  isRegistered(name) {
1842
- return this._schemas.has(name);
1578
+ return this._registrations.has(name);
1843
1579
  }
1844
1580
  //#endregion
1845
1581
  //#region ---- Resolution Methods ----
@@ -1853,7 +1589,7 @@ class AXPSchemaRegistry {
1853
1589
  return this._modelCache.get(name);
1854
1590
  }
1855
1591
  // Try to get from registered schemas first
1856
- let registered = this._schemas.get(name);
1592
+ let registered = this._registrations.get(name);
1857
1593
  // If not found, attempt on-demand loading
1858
1594
  if (!registered) {
1859
1595
  const definition = await this.loadFromLoaders(name);
@@ -1864,27 +1600,27 @@ class AXPSchemaRegistry {
1864
1600
  options: {},
1865
1601
  registeredAt: new Date()
1866
1602
  };
1867
- this._schemas.set(name, registered);
1603
+ this._registrations.set(name, registered);
1868
1604
  }
1869
1605
  else {
1870
- throw new Error(`Schema '${name}' is not registered and no loader can provide it`);
1606
+ throw new Error(`Property '${name}' is not registered and no loader can provide it`);
1871
1607
  }
1872
1608
  }
1873
1609
  // Clone and process through middleware pipeline
1874
- const schema = this.cloneDefinition(registered.definition);
1875
- const context = new AXPSchemaMiddlewareContext(schema);
1610
+ const definition = this.cloneDefinition(registered.definition);
1611
+ const context = new AXPPropertyMiddlewareContext(definition);
1876
1612
  // Apply global middleware first
1877
1613
  for (const middleware of this._globalMiddleware) {
1878
1614
  await middleware(context);
1879
1615
  }
1880
- // Apply schema-specific middleware
1616
+ // Apply registration-specific middleware
1881
1617
  if (registered.options.middleware) {
1882
1618
  for (const middleware of registered.options.middleware) {
1883
1619
  await middleware(context);
1884
1620
  }
1885
1621
  }
1886
1622
  // Create final model and cache it
1887
- const model = new AXPSchemaModel(context.schema);
1623
+ const model = new AXPPropertyModel(context.definition);
1888
1624
  this._modelCache.set(name, model);
1889
1625
  return model;
1890
1626
  }
@@ -1893,11 +1629,11 @@ class AXPSchemaRegistry {
1893
1629
  * Use only when middleware is not needed for performance.
1894
1630
  */
1895
1631
  resolveSync(name) {
1896
- const registered = this._schemas.get(name);
1632
+ const registered = this._registrations.get(name);
1897
1633
  if (!registered) {
1898
- throw new Error(`Schema '${name}' is not registered`);
1634
+ throw new Error(`Property '${name}' is not registered`);
1899
1635
  }
1900
- return new AXPSchemaModel(this.cloneDefinition(registered.definition));
1636
+ return new AXPPropertyModel(this.cloneDefinition(registered.definition));
1901
1637
  }
1902
1638
  //#endregion
1903
1639
  //#region ---- Middleware Management ----
@@ -1944,52 +1680,52 @@ class AXPSchemaRegistry {
1944
1680
  * Get all registered schema names
1945
1681
  */
1946
1682
  getRegisteredNames() {
1947
- return Array.from(this._schemas.keys());
1683
+ return Array.from(this._registrations.keys());
1948
1684
  }
1949
1685
  /**
1950
1686
  * Get detailed registration information for a schema
1951
1687
  */
1952
- getSchemaInfo(name) {
1953
- return this._schemas.get(name);
1688
+ getRegisteredProperty(name) {
1689
+ return this._registrations.get(name);
1954
1690
  }
1955
1691
  /**
1956
- * Get all registered schemas with their metadata
1692
+ * Get all registered properties with their metadata
1957
1693
  */
1958
- getAllSchemas() {
1959
- return Array.from(this._schemas.values());
1694
+ getAllRegisteredProperties() {
1695
+ return Array.from(this._registrations.values());
1960
1696
  }
1961
1697
  /**
1962
- * Find schemas by tag for categorization
1698
+ * Find registered properties by tag for categorization
1963
1699
  */
1964
1700
  findByTag(tag) {
1965
- return Array.from(this._schemas.values()).filter(schema => schema.options.tags?.includes(tag));
1701
+ return Array.from(this._registrations.values()).filter((registration) => registration.options.tags?.includes(tag));
1966
1702
  }
1967
1703
  /**
1968
- * Find schemas by widget type for widget-specific operations
1704
+ * Find registered properties by widget type for widget-specific operations
1969
1705
  */
1970
1706
  findByWidget(widgetType) {
1971
- return Array.from(this._schemas.values()).filter(schema => schema.definition.interface.widget === widgetType);
1707
+ return Array.from(this._registrations.values()).filter((registration) => registration.definition.interface.name === widgetType);
1972
1708
  }
1973
1709
  /**
1974
1710
  * Get comprehensive registry statistics
1975
1711
  */
1976
1712
  getStatistics() {
1977
- const schemasByWidget = {};
1978
- const schemasByTag = {};
1979
- for (const schema of this._schemas.values()) {
1980
- const widget = schema.definition.interface.widget;
1981
- schemasByWidget[widget] = (schemasByWidget[widget] || 0) + 1;
1982
- if (schema.options.tags) {
1983
- for (const tag of schema.options.tags) {
1984
- schemasByTag[tag] = (schemasByTag[tag] || 0) + 1;
1713
+ const propertiesByWidget = {};
1714
+ const propertiesByTag = {};
1715
+ for (const registration of this._registrations.values()) {
1716
+ const widget = registration.definition.interface.name;
1717
+ propertiesByWidget[widget] = (propertiesByWidget[widget] || 0) + 1;
1718
+ if (registration.options.tags) {
1719
+ for (const tag of registration.options.tags) {
1720
+ propertiesByTag[tag] = (propertiesByTag[tag] || 0) + 1;
1985
1721
  }
1986
1722
  }
1987
1723
  }
1988
1724
  return {
1989
- schemaCount: this._schemas.size,
1725
+ propertyCount: this._registrations.size,
1990
1726
  globalMiddlewareCount: this._globalMiddleware.length,
1991
- schemasByWidget,
1992
- schemasByTag
1727
+ propertiesByWidget,
1728
+ propertiesByTag
1993
1729
  };
1994
1730
  }
1995
1731
  //#endregion
@@ -2010,7 +1746,7 @@ class AXPSchemaRegistry {
2010
1746
  * Clear all registered schemas, middleware, and cached models
2011
1747
  */
2012
1748
  clear() {
2013
- this._schemas.clear();
1749
+ this._registrations.clear();
2014
1750
  this._globalMiddleware.length = 0;
2015
1751
  this._modelCache.clear();
2016
1752
  this._loaders = null;
@@ -2027,7 +1763,7 @@ class AXPSchemaRegistry {
2027
1763
  try {
2028
1764
  const definition = await loader.load(name);
2029
1765
  if (definition) {
2030
- console.log(`Schema '${name}' loaded from ${loader.constructor.name}`);
1766
+ console.log(`Property '${name}' loaded from ${loader.constructor.name}`);
2031
1767
  return definition;
2032
1768
  }
2033
1769
  }
@@ -2053,7 +1789,7 @@ class AXPSchemaRegistry {
2053
1789
  });
2054
1790
  }
2055
1791
  catch (error) {
2056
- console.warn('Failed to initialize schema loaders:', error);
1792
+ console.warn('Failed to initialize property loaders:', error);
2057
1793
  this._loaders = [];
2058
1794
  }
2059
1795
  }
@@ -2065,90 +1801,89 @@ class AXPSchemaRegistry {
2065
1801
  cloneDefinition(definition) {
2066
1802
  return JSON.parse(JSON.stringify(definition));
2067
1803
  }
2068
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPSchemaRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2069
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPSchemaRegistry, providedIn: 'root' }); }
1804
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPropertyRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1805
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPropertyRegistry, providedIn: 'root' }); }
2070
1806
  }
2071
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPSchemaRegistry, decorators: [{
1807
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPropertyRegistry, decorators: [{
2072
1808
  type: Injectable,
2073
1809
  args: [{ providedIn: 'root' }]
2074
1810
  }], ctorParameters: () => [] });
2075
1811
 
2076
- //#region ---- Schema Service ----
1812
+ //#region ---- Property Service ----
2077
1813
  /**
2078
- * High-level facade service for schema operations.
1814
+ * High-level facade for registered property definitions ({@link AXPPropertyDefinition}).
2079
1815
  *
2080
- * Provides a simplified interface to the schema registry with additional
2081
- * business logic and convenience methods for common operations.
1816
+ * Wraps {@link AXPPropertyRegistry} with convenience methods for resolution and discovery.
2082
1817
  */
2083
- class AXPSchemaService {
1818
+ class AXPPropertyService {
2084
1819
  constructor() {
2085
- this.registry = inject(AXPSchemaRegistry);
1820
+ this.registry = inject(AXPPropertyRegistry);
2086
1821
  }
2087
- //#region ---- Core Schema Management ----
1822
+ //#region ---- Registration ----
2088
1823
  /**
2089
- * Register a schema with optional configuration
1824
+ * Register a property definition with optional configuration
2090
1825
  */
2091
1826
  register(definition, options) {
2092
1827
  this.registry.register(definition, options);
2093
1828
  }
2094
1829
  /**
2095
- * Register multiple schemas at once
1830
+ * Register multiple property definitions at once
2096
1831
  */
2097
- registerBatch(schemas) {
2098
- this.registry.registerBatch(schemas);
1832
+ registerBatch(entries) {
1833
+ this.registry.registerBatch(entries);
2099
1834
  }
2100
1835
  /**
2101
- * Remove a schema from the registry
1836
+ * Remove a property definition from the registry
2102
1837
  */
2103
1838
  unregister(name) {
2104
1839
  return this.registry.unregister(name);
2105
1840
  }
2106
1841
  /**
2107
- * Check if a schema is registered
1842
+ * Check if a property definition is registered by name
2108
1843
  */
2109
1844
  isRegistered(name) {
2110
1845
  return this.registry.isRegistered(name);
2111
1846
  }
2112
1847
  /**
2113
- * Get all registered schema names
1848
+ * Get all registered property names
2114
1849
  */
2115
1850
  getRegisteredNames() {
2116
1851
  return this.registry.getRegisteredNames();
2117
1852
  }
2118
1853
  /**
2119
- * Clear all schemas and reset the registry
1854
+ * Clear all registrations and reset the registry
2120
1855
  */
2121
1856
  clear() {
2122
1857
  this.registry.clear();
2123
1858
  }
2124
1859
  //#endregion
2125
- //#region ---- Schema Resolution ----
1860
+ //#region ---- Resolution ----
2126
1861
  /**
2127
- * Resolve a schema with full middleware processing
1862
+ * Resolve a registered property by name with full middleware processing
2128
1863
  */
2129
1864
  async resolve(name) {
2130
1865
  return this.registry.resolve(name);
2131
1866
  }
2132
1867
  /**
2133
- * Resolve schema synchronously without middleware (for performance)
1868
+ * Resolve synchronously without middleware (for performance)
2134
1869
  */
2135
1870
  resolveSync(name) {
2136
1871
  return this.registry.resolveSync(name);
2137
1872
  }
2138
1873
  /**
2139
- * Resolve multiple schemas for form building and batch operations
1874
+ * Resolve multiple registered properties for form building and batch operations
2140
1875
  */
2141
1876
  async resolveMultiple(fieldConfigs) {
2142
1877
  const resolvedFields = await Promise.all(fieldConfigs.map(async (config) => ({
2143
1878
  name: config.name,
2144
- schema: await this.resolve(config.schemaName)
1879
+ property: await this.resolve(config.propertyName),
2145
1880
  })));
2146
1881
  return resolvedFields;
2147
1882
  }
2148
1883
  //#endregion
2149
1884
  //#region ---- Middleware Management ----
2150
1885
  /**
2151
- * Add global middleware that applies to all schema resolutions
1886
+ * Add global middleware that applies to all property resolutions
2152
1887
  */
2153
1888
  addGlobalMiddleware(middleware) {
2154
1889
  this.registry.addGlobalMiddleware(middleware);
@@ -2168,25 +1903,25 @@ class AXPSchemaService {
2168
1903
  //#endregion
2169
1904
  //#region ---- Query and Discovery ----
2170
1905
  /**
2171
- * Get detailed information about a registered schema
1906
+ * Get detailed information about a registered property definition
2172
1907
  */
2173
- getSchemaInfo(name) {
2174
- return this.registry.getSchemaInfo(name);
1908
+ getRegisteredProperty(name) {
1909
+ return this.registry.getRegisteredProperty(name);
2175
1910
  }
2176
1911
  /**
2177
- * Get all registered schemas with their metadata
1912
+ * Get all registered property definitions with their metadata
2178
1913
  */
2179
- getAllSchemas() {
2180
- return this.registry.getAllSchemas();
1914
+ getAllRegisteredProperties() {
1915
+ return this.registry.getAllRegisteredProperties();
2181
1916
  }
2182
1917
  /**
2183
- * Find schemas by tag for categorization and grouping
1918
+ * Find registered properties by tag for categorization and grouping
2184
1919
  */
2185
1920
  findByTag(tag) {
2186
1921
  return this.registry.findByTag(tag);
2187
1922
  }
2188
1923
  /**
2189
- * Find schemas by widget type for widget-specific operations
1924
+ * Find registered properties by widget type for widget-specific operations
2190
1925
  */
2191
1926
  findByWidget(widgetType) {
2192
1927
  return this.registry.findByWidget(widgetType);
@@ -2197,11 +1932,11 @@ class AXPSchemaService {
2197
1932
  getStatistics() {
2198
1933
  const stats = this.registry.getStatistics();
2199
1934
  // Enhance with top-used analytics
2200
- const mostUsedWidgets = Object.entries(stats.schemasByWidget)
1935
+ const mostUsedWidgets = Object.entries(stats.propertiesByWidget)
2201
1936
  .sort(([, a], [, b]) => b - a)
2202
1937
  .slice(0, 5)
2203
1938
  .map(([widget]) => widget);
2204
- const mostUsedTags = Object.entries(stats.schemasByTag)
1939
+ const mostUsedTags = Object.entries(stats.propertiesByTag)
2205
1940
  .sort(([, a], [, b]) => b - a)
2206
1941
  .slice(0, 5)
2207
1942
  .map(([tag]) => tag);
@@ -2214,24 +1949,24 @@ class AXPSchemaService {
2214
1949
  //#endregion
2215
1950
  //#region ---- Validation and Analysis ----
2216
1951
  /**
2217
- * Validate that all referenced schemas exist in the registry
1952
+ * Validate that all referenced property names exist in the registry
2218
1953
  */
2219
- validateSchemaReferences(schemaNames) {
2220
- const missingSchemas = [];
2221
- for (const schemaName of schemaNames) {
2222
- if (!this.isRegistered(schemaName)) {
2223
- missingSchemas.push(schemaName);
1954
+ validatePropertyReferences(propertyNames) {
1955
+ const missingPropertyNames = [];
1956
+ for (const propertyName of propertyNames) {
1957
+ if (!this.isRegistered(propertyName)) {
1958
+ missingPropertyNames.push(propertyName);
2224
1959
  }
2225
1960
  }
2226
1961
  return {
2227
- valid: missingSchemas.length === 0,
2228
- missingSchemas
1962
+ valid: missingPropertyNames.length === 0,
1963
+ missingPropertyNames,
2229
1964
  };
2230
1965
  }
2231
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPSchemaService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2232
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPSchemaService, providedIn: 'root' }); }
1966
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPropertyService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1967
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPropertyService, providedIn: 'root' }); }
2233
1968
  }
2234
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPSchemaService, decorators: [{
1969
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPropertyService, decorators: [{
2235
1970
  type: Injectable,
2236
1971
  args: [{ providedIn: 'root' }]
2237
1972
  }] });
@@ -2256,24 +1991,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
2256
1991
  * @example
2257
1992
  * ```typescript
2258
1993
  * // Simple loader registration
2259
- * provideSchemaLoaders([
1994
+ * providePropertyLoaders([
2260
1995
  * HttpSchemaLoader,
2261
1996
  * FileSystemSchemaLoader
2262
1997
  * ])
2263
1998
  *
2264
1999
  * // With priority configuration
2265
- * provideSchemaLoaders([
2000
+ * providePropertyLoaders([
2266
2001
  * { loader: HttpSchemaLoader, priority: 10 },
2267
2002
  * { loader: FileSystemSchemaLoader, priority: 5 }
2268
2003
  * ])
2269
2004
  * ```
2270
2005
  */
2271
- function provideSchemaLoaders(loaders) {
2006
+ function providePropertyLoaders(loaders) {
2272
2007
  return makeEnvironmentProviders([
2273
2008
  {
2274
- provide: AXP_SCHEMA_LOADER_SETUP,
2009
+ provide: AXP_PROPERTY_LOADER_SETUP,
2275
2010
  useFactory: async () => {
2276
- const registry = inject(AXPSchemaRegistry);
2011
+ const registry = inject(AXPPropertyRegistry);
2277
2012
  // Register each loader with the registry
2278
2013
  for (const loader of loaders) {
2279
2014
  const loaderClass = typeof loader === 'function' ? loader : loader.loader;
@@ -2300,7 +2035,7 @@ function provideSchemaLoaders(loaders) {
2300
2035
  *
2301
2036
  * @example
2302
2037
  * ```typescript
2303
- * provideSchemaSetups([
2038
+ * providePropertySetups([
2304
2039
  * {
2305
2040
  * definition: emailSchema,
2306
2041
  * options: {
@@ -2315,15 +2050,14 @@ function provideSchemaLoaders(loaders) {
2315
2050
  * ])
2316
2051
  * ```
2317
2052
  */
2318
- function provideSchemaSetups(schemas) {
2053
+ function providePropertySetups(entries) {
2319
2054
  return makeEnvironmentProviders([
2320
2055
  {
2321
- provide: AXP_SCHEMA_SETUP,
2056
+ provide: AXP_PROPERTY_SETUP,
2322
2057
  useFactory: () => {
2323
- const registry = inject(AXPSchemaRegistry);
2324
- // Register all schemas with their options
2325
- for (const schema of schemas) {
2326
- registry.register(schema.definition, schema.options);
2058
+ const registry = inject(AXPPropertyRegistry);
2059
+ for (const entry of entries) {
2060
+ registry.register(entry.definition, entry.options);
2327
2061
  }
2328
2062
  return true;
2329
2063
  },
@@ -2343,14 +2077,14 @@ function provideSchemaSetups(schemas) {
2343
2077
  *
2344
2078
  * @example
2345
2079
  * ```typescript
2346
- * provideSchema(emailSchema, {
2080
+ * provideProperty(emailSchema, {
2347
2081
  * tags: ['user', 'contact'],
2348
2082
  * description: 'User email field'
2349
2083
  * })
2350
2084
  * ```
2351
2085
  */
2352
- function provideSchema(definition, options) {
2353
- return provideSchemaSetups([{ definition, options }]);
2086
+ function provideProperty(definition, options) {
2087
+ return providePropertySetups([{ definition, options }]);
2354
2088
  }
2355
2089
  /**
2356
2090
  * Provide schema setups from a factory function for dynamic registration.
@@ -2363,7 +2097,7 @@ function provideSchema(definition, options) {
2363
2097
  *
2364
2098
  * @example
2365
2099
  * ```typescript
2366
- * provideSchemasFromFactory(async () => {
2100
+ * providePropertiesFromFactory(async () => {
2367
2101
  * const config = await loadConfiguration();
2368
2102
  * return config.schemas.map(schema => ({
2369
2103
  * definition: schema,
@@ -2372,16 +2106,15 @@ function provideSchema(definition, options) {
2372
2106
  * })
2373
2107
  * ```
2374
2108
  */
2375
- function provideSchemasFromFactory(schemaFactory) {
2109
+ function providePropertiesFromFactory(factory) {
2376
2110
  return makeEnvironmentProviders([
2377
2111
  {
2378
- provide: AXP_SCHEMA_SETUP,
2112
+ provide: AXP_PROPERTY_SETUP,
2379
2113
  useFactory: async () => {
2380
- const registry = inject(AXPSchemaRegistry);
2381
- const schemas = await schemaFactory();
2382
- // Register all factory-generated schemas
2383
- for (const schema of schemas) {
2384
- registry.register(schema.definition, schema.options);
2114
+ const registry = inject(AXPPropertyRegistry);
2115
+ const entries = await factory();
2116
+ for (const entry of entries) {
2117
+ registry.register(entry.definition, entry.options);
2385
2118
  }
2386
2119
  return true;
2387
2120
  },
@@ -2405,16 +2138,16 @@ function provideSchemasFromFactory(schemaFactory) {
2405
2138
  * @example
2406
2139
  * ```typescript
2407
2140
  * // Global middleware
2408
- * provideSchemaMiddleware([
2141
+ * providePropertyMiddleware([
2409
2142
  * (context) => {
2410
- * if (context.schema.dataType === 'string') {
2143
+ * if (context.definition.dataType === 'string') {
2411
2144
  * context.searchable(true);
2412
2145
  * }
2413
2146
  * }
2414
2147
  * ])
2415
2148
  *
2416
2149
  * // Targeted middleware
2417
- * provideSchemaMiddleware([
2150
+ * providePropertyMiddleware([
2418
2151
  * {
2419
2152
  * target: /^user_/,
2420
2153
  * middleware: (context) => context.withMetadata({ category: 'user' })
@@ -2422,7 +2155,7 @@ function provideSchemasFromFactory(schemaFactory) {
2422
2155
  * ])
2423
2156
  * ```
2424
2157
  */
2425
- function provideSchemaMiddleware(middleware) {
2158
+ function providePropertyMiddleware(middleware) {
2426
2159
  const global = [];
2427
2160
  const targeted = [];
2428
2161
  // Separate global and targeted middleware for different processing
@@ -2437,9 +2170,9 @@ function provideSchemaMiddleware(middleware) {
2437
2170
  return makeEnvironmentProviders([
2438
2171
  // Setup global middleware that applies to all schemas
2439
2172
  ...(global.length > 0 ? [{
2440
- provide: AXP_SCHEMA_MIDDLEWARE_SETUP,
2173
+ provide: AXP_PROPERTY_MIDDLEWARE_SETUP,
2441
2174
  useFactory: () => {
2442
- const registry = inject(AXPSchemaRegistry);
2175
+ const registry = inject(AXPPropertyRegistry);
2443
2176
  for (const mw of global) {
2444
2177
  registry.addGlobalMiddleware(mw);
2445
2178
  }
@@ -2449,7 +2182,7 @@ function provideSchemaMiddleware(middleware) {
2449
2182
  }] : []),
2450
2183
  // Register targeted middleware entries for future extension support
2451
2184
  ...targeted.map(entry => ({
2452
- provide: AXP_SCHEMA_EXTENSION,
2185
+ provide: AXP_PROPERTY_EXTENSION,
2453
2186
  useValue: entry,
2454
2187
  multi: true
2455
2188
  }))
@@ -2457,8 +2190,7 @@ function provideSchemaMiddleware(middleware) {
2457
2190
  }
2458
2191
  //#endregion
2459
2192
 
2460
- //#region ---- Core Schema Registry ----
2461
- // Core registry and service classes
2193
+ //#region ---- Property registry core ----
2462
2194
  //#endregion
2463
2195
 
2464
2196
  //#region ---- Domain Middleware Context ----
@@ -2587,7 +2319,7 @@ class AXPDomainRegistry {
2587
2319
  // Registered loaders for on-demand loading
2588
2320
  this._loaders = [];
2589
2321
  // Injected dependencies
2590
- this.schemaService = inject(AXPSchemaService);
2322
+ this.propertyService = inject(AXPPropertyService);
2591
2323
  }
2592
2324
  //#region ---- Main Resolution Method ----
2593
2325
  /**
@@ -2772,7 +2504,6 @@ class AXPDomainRegistry {
2772
2504
  name: pathInfo.aggregate,
2773
2505
  title: pathInfo.aggregate || '',
2774
2506
  entities: [definition],
2775
- relations: [],
2776
2507
  validations: [],
2777
2508
  actions: []
2778
2509
  };
@@ -2783,7 +2514,7 @@ class AXPDomainRegistry {
2783
2514
  };
2784
2515
  const entityModule = new AXPModuleModel(entityModuleDefinition);
2785
2516
  const entityAggregate = new AXPAggregateModel(entityAggregateDefinition, entityModule);
2786
- return new AXPEntityModel(definition, entityAggregate, this.schemaService);
2517
+ return new AXPEntityModel(definition, entityAggregate, this.propertyService);
2787
2518
  default:
2788
2519
  throw new Error(`Unknown domain type: ${pathInfo.type}`);
2789
2520
  }
@@ -2813,10 +2544,10 @@ class AXPDomainRegistry {
2813
2544
  paths: Array.from(this._definitionCache.keys())
2814
2545
  };
2815
2546
  }
2816
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDomainRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2817
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDomainRegistry, providedIn: 'root' }); }
2547
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDomainRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2548
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDomainRegistry, providedIn: 'root' }); }
2818
2549
  }
2819
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDomainRegistry, decorators: [{
2550
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDomainRegistry, decorators: [{
2820
2551
  type: Injectable,
2821
2552
  args: [{ providedIn: 'root' }]
2822
2553
  }] });
@@ -3118,10 +2849,10 @@ class AXPDomainService {
3118
2849
  return module;
3119
2850
  }
3120
2851
  }
3121
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDomainService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3122
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDomainService, providedIn: 'root' }); }
2852
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDomainService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2853
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDomainService, providedIn: 'root' }); }
3123
2854
  }
3124
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDomainService, decorators: [{
2855
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDomainService, decorators: [{
3125
2856
  type: Injectable,
3126
2857
  args: [{ providedIn: 'root' }]
3127
2858
  }] });
@@ -3502,5 +3233,5 @@ function provideDomainMiddleware(config) {
3502
3233
  * Generated bundle index. Do not edit.
3503
3234
  */
3504
3235
 
3505
- export { AXPAggregateModel, AXPDomainMiddlewareContext, AXPDomainModule, AXPDomainRegistry, AXPDomainService, AXPEntityCommandScope, AXPEntityFieldModel, AXPEntityModel, AXPEntityType, AXPModuleHelper, AXPModuleModel, AXPRelationModel, AXPRelationshipCardinality, AXPRelationshipKind, AXPSchemaMiddlewareContext, AXPSchemaModel, AXPSchemaRegistry, AXPSchemaService, AXP_AGGREGATE_MIDDLEWARE_SETUP, AXP_ENTITY_CRUD_SETUP, AXP_ENTITY_MIDDLEWARE_SETUP, AXP_MODULE_MIDDLEWARE_SETUP, AXP_SCHEMA_EXTENSION, AXP_SCHEMA_LOADER_SETUP, AXP_SCHEMA_MIDDLEWARE_SETUP, AXP_SCHEMA_SETUP, provideAggregateMiddleware, provideDomainLoader, provideDomainLoaders, provideDomainMiddleware, provideEntity, provideEntityMiddleware, provideModuleMiddleware, provideSchema, provideSchemaLoaders, provideSchemaMiddleware, provideSchemaSetups, provideSchemasFromFactory };
3236
+ export { AXPAggregateModel, AXPDomainActionSide, AXPDomainMiddlewareContext, AXPDomainModule, AXPDomainRegistry, AXPDomainService, AXPEntityCommandScope, AXPEntityFieldModel, AXPEntityModel, AXPEntityType, AXPModuleHelper, AXPModuleModel, AXPPropertyMiddlewareContext, AXPPropertyModel, AXPPropertyRegistry, AXPPropertyService, AXPRelationModel, AXPRelationshipCardinality, AXPRelationshipKind, AXP_AGGREGATE_MIDDLEWARE_SETUP, AXP_ENTITY_CRUD_SETUP, AXP_ENTITY_DEFINITION_CRUD_SERVICE, AXP_ENTITY_MIDDLEWARE_SETUP, AXP_MODULE_MIDDLEWARE_SETUP, AXP_PROPERTY_EXTENSION, AXP_PROPERTY_LOADER_SETUP, AXP_PROPERTY_MIDDLEWARE_SETUP, AXP_PROPERTY_SETUP, provideAggregateMiddleware, provideDomainLoader, provideDomainLoaders, provideDomainMiddleware, provideEntityMiddleware, provideModuleMiddleware, providePropertiesFromFactory, provideProperty, providePropertyLoaders, providePropertyMiddleware, providePropertySetups, toPropertyDefinition };
3506
3237
  //# sourceMappingURL=acorex-platform-domain.mjs.map