@intellegens/cornerstone-client 0.0.9999-alpha-8 → 0.0.9999-alpha-10

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 (227) hide show
  1. package/demo/index.ts +29 -0
  2. package/demo/public_html/favicon.ico +0 -0
  3. package/demo/public_html/index.html +106 -0
  4. package/demo/public_html/websettings.json +3 -0
  5. package/{adapters → dist/adapters}/CollectionViewAdapter/index.d.ts +0 -0
  6. package/{adapters → dist/adapters}/CollectionViewAdapter/index.js +0 -0
  7. package/{adapters → dist/adapters}/index.d.ts +0 -0
  8. package/{adapters → dist/adapters}/index.js +0 -0
  9. package/{data → dist/data}/api/dto/PropertyPathDto.d.ts +0 -0
  10. package/{data → dist/data}/api/dto/PropertyPathDto.js +0 -0
  11. package/{data → dist/data}/api/dto/ReadOptionsDto.d.ts +0 -0
  12. package/{data → dist/data}/api/dto/ReadOptionsDto.js +0 -0
  13. package/{data → dist/data}/api/dto/ReadResultDto.d.ts +0 -0
  14. package/{data → dist/data}/api/dto/ReadResultDto.js +0 -0
  15. package/{data → dist/data}/api/dto/ReadResultMetadataDto.d.ts +0 -0
  16. package/{data → dist/data}/api/dto/ReadResultMetadataDto.js +0 -0
  17. package/{data → dist/data}/api/dto/crud/CrudMetadataDto.d.ts +0 -0
  18. package/{data → dist/data}/api/dto/crud/CrudMetadataDto.js +0 -0
  19. package/{data → dist/data}/api/dto/crud/index.d.ts +0 -0
  20. package/{data → dist/data}/api/dto/crud/index.js +0 -0
  21. package/{data → dist/data}/api/dto/index.d.ts +0 -0
  22. package/{data → dist/data}/api/dto/index.js +0 -0
  23. package/{data → dist/data}/api/dto/read/ReadMetadataDto.d.ts +0 -0
  24. package/{data → dist/data}/api/dto/read/ReadMetadataDto.js +0 -0
  25. package/{data → dist/data}/api/dto/read/ReadSelectedDefinitionDto.d.ts +0 -0
  26. package/{data → dist/data}/api/dto/read/ReadSelectedDefinitionDto.js +0 -0
  27. package/{data → dist/data}/api/dto/read/ReadSelectedOrderingDefinitionDto.d.ts +0 -0
  28. package/{data → dist/data}/api/dto/read/ReadSelectedOrderingDefinitionDto.js +0 -0
  29. package/{data → dist/data}/api/dto/read/ReadSelectedOrderingPropertyDefinitionDto.d.ts +0 -0
  30. package/{data → dist/data}/api/dto/read/ReadSelectedOrderingPropertyDefinitionDto.js +0 -0
  31. package/{data → dist/data}/api/dto/read/ReadSelectedPaginationDefinitionDto.d.ts +0 -0
  32. package/{data → dist/data}/api/dto/read/ReadSelectedPaginationDefinitionDto.js +0 -0
  33. package/{data → dist/data}/api/dto/read/ReadSelectedSearchDefinitionDto.d.ts +0 -0
  34. package/{data → dist/data}/api/dto/read/ReadSelectedSearchDefinitionDto.js +0 -0
  35. package/{data → dist/data}/api/dto/read/ReadSelectedSearchPropertyDefinitionDto.d.ts +0 -0
  36. package/{data → dist/data}/api/dto/read/ReadSelectedSearchPropertyDefinitionDto.js +0 -0
  37. package/{data → dist/data}/api/dto/read/index.d.ts +0 -0
  38. package/{data → dist/data}/api/dto/read/index.js +0 -0
  39. package/{data → dist/data}/api/dto/response/ApiErrorDto.d.ts +0 -0
  40. package/{data → dist/data}/api/dto/response/ApiErrorDto.js +0 -0
  41. package/{data → dist/data}/api/dto/response/ApiResponseDto.d.ts +0 -0
  42. package/{data → dist/data}/api/dto/response/ApiResponseDto.js +0 -0
  43. package/{data → dist/data}/api/dto/response/ApiSuccessResponseDto.d.ts +0 -0
  44. package/{data → dist/data}/api/dto/response/ApiSuccessResponseDto.js +0 -0
  45. package/{data → dist/data}/api/dto/response/EmptyMetadataDto.d.ts +0 -0
  46. package/{data → dist/data}/api/dto/response/EmptyMetadataDto.js +0 -0
  47. package/{data → dist/data}/api/dto/response/index.d.ts +0 -0
  48. package/{data → dist/data}/api/dto/response/index.js +0 -0
  49. package/{data → dist/data}/api/enum/index.d.ts +0 -0
  50. package/{data → dist/data}/api/enum/index.js +0 -0
  51. package/{data → dist/data}/api/enum/read/ReadSelectedComparisonOperator.d.ts +0 -0
  52. package/{data → dist/data}/api/enum/read/ReadSelectedComparisonOperator.js +0 -0
  53. package/{data → dist/data}/api/enum/read/ReadSelectedLogicalOperator.d.ts +0 -0
  54. package/{data → dist/data}/api/enum/read/ReadSelectedLogicalOperator.js +0 -0
  55. package/{data → dist/data}/api/enum/read/ReadSelectedOrderingDirection.d.ts +0 -0
  56. package/{data → dist/data}/api/enum/read/ReadSelectedOrderingDirection.js +0 -0
  57. package/{data → dist/data}/api/enum/read/ReadSelectedPropertyType.d.ts +0 -0
  58. package/{data → dist/data}/api/enum/read/ReadSelectedPropertyType.js +0 -0
  59. package/{data → dist/data}/api/enum/read/index.d.ts +0 -0
  60. package/{data → dist/data}/api/enum/read/index.js +0 -0
  61. package/{data → dist/data}/api/enum/response/ApiErrorCodes.d.ts +0 -0
  62. package/{data → dist/data}/api/enum/response/ApiErrorCodes.js +0 -0
  63. package/{data → dist/data}/api/enum/response/index.d.ts +0 -0
  64. package/{data → dist/data}/api/enum/response/index.js +0 -0
  65. package/{data → dist/data}/api/index.d.ts +0 -0
  66. package/{data → dist/data}/api/index.js +0 -0
  67. package/{data → dist/data}/api/interface/IConcurrencySafe.d.ts +0 -0
  68. package/{data → dist/data}/api/interface/IConcurrencySafe.js +0 -0
  69. package/{data → dist/data}/api/interface/IIdentifiable.d.ts +0 -0
  70. package/{data → dist/data}/api/interface/IIdentifiable.js +0 -0
  71. package/{data → dist/data}/api/interface/IIdentifiableSecondary.d.ts +0 -0
  72. package/{data → dist/data}/api/interface/IIdentifiableSecondary.js +0 -0
  73. package/{data → dist/data}/api/interface/index.d.ts +0 -0
  74. package/{data → dist/data}/api/interface/index.js +0 -0
  75. package/{data → dist/data}/auth/dto/ClaimDto.d.ts +0 -0
  76. package/{data → dist/data}/auth/dto/ClaimDto.js +0 -0
  77. package/{data → dist/data}/auth/dto/RegisterRequestDto.d.ts +0 -0
  78. package/{data → dist/data}/auth/dto/RegisterRequestDto.js +0 -0
  79. package/{data → dist/data}/auth/dto/RoleDto.d.ts +0 -0
  80. package/{data → dist/data}/auth/dto/RoleDto.js +0 -0
  81. package/{data → dist/data}/auth/dto/SignInRequestDto.d.ts +0 -0
  82. package/{data → dist/data}/auth/dto/SignInRequestDto.js +0 -0
  83. package/{data → dist/data}/auth/dto/TokensDto.d.ts +0 -0
  84. package/{data → dist/data}/auth/dto/TokensDto.js +0 -0
  85. package/{data → dist/data}/auth/dto/UserDto.d.ts +0 -0
  86. package/{data → dist/data}/auth/dto/UserDto.js +0 -0
  87. package/{data → dist/data}/auth/dto/UserInfoDto.d.ts +0 -0
  88. package/{data → dist/data}/auth/dto/UserInfoDto.js +0 -0
  89. package/{data → dist/data}/auth/dto/index.d.ts +0 -0
  90. package/{data → dist/data}/auth/dto/index.js +0 -0
  91. package/{data → dist/data}/auth/index.d.ts +0 -0
  92. package/{data → dist/data}/auth/index.js +0 -0
  93. package/{data → dist/data}/index.d.ts +0 -0
  94. package/{data → dist/data}/index.js +0 -0
  95. package/{index.d.ts → dist/index.d.ts} +0 -0
  96. package/{index.js → dist/index.js} +0 -0
  97. package/{services → dist/services}/api/ApiCrudControllerClient/index.d.ts +0 -0
  98. package/{services → dist/services}/api/ApiCrudControllerClient/index.js +0 -0
  99. package/{services → dist/services}/api/ApiInitializationService/index.d.ts +0 -0
  100. package/{services → dist/services}/api/ApiInitializationService/index.js +0 -0
  101. package/{services → dist/services}/api/ApiReadControllerClient/index.d.ts +0 -0
  102. package/{services → dist/services}/api/ApiReadControllerClient/index.js +0 -0
  103. package/{services → dist/services}/api/HttpService/FetchHttpService.d.ts +0 -0
  104. package/{services → dist/services}/api/HttpService/FetchHttpService.js +0 -0
  105. package/{services → dist/services}/api/HttpService/HttpRequestConfig.d.ts +0 -0
  106. package/{services → dist/services}/api/HttpService/HttpRequestConfig.js +0 -0
  107. package/{services → dist/services}/api/HttpService/HttpResponse.d.ts +0 -0
  108. package/{services → dist/services}/api/HttpService/HttpResponse.js +0 -0
  109. package/{services → dist/services}/api/HttpService/IHttpService.d.ts +0 -0
  110. package/{services → dist/services}/api/HttpService/IHttpService.js +0 -0
  111. package/{services → dist/services}/api/HttpService/index.d.ts +0 -0
  112. package/{services → dist/services}/api/HttpService/index.js +0 -0
  113. package/{services → dist/services}/api/UserManagementControllerClient/index.d.ts +0 -0
  114. package/{services → dist/services}/api/UserManagementControllerClient/index.js +0 -0
  115. package/{services → dist/services}/api/index.d.ts +0 -0
  116. package/{services → dist/services}/api/index.js +0 -0
  117. package/{services → dist/services}/auth/client/AuthService/index.d.ts +0 -0
  118. package/{services → dist/services}/auth/client/AuthService/index.js +0 -0
  119. package/{services → dist/services}/auth/client/AuthorizationManagementControllerClient/index.d.ts +0 -0
  120. package/{services → dist/services}/auth/client/AuthorizationManagementControllerClient/index.js +0 -0
  121. package/{services → dist/services}/auth/client/index.d.ts +0 -0
  122. package/{services → dist/services}/auth/client/index.js +0 -0
  123. package/{services → dist/services}/auth/index.d.ts +0 -0
  124. package/{services → dist/services}/auth/index.js +0 -0
  125. package/{services → dist/services}/index.d.ts +0 -0
  126. package/{services → dist/services}/index.js +0 -0
  127. package/{utils → dist/utils}/index.d.ts +0 -0
  128. package/{utils → dist/utils}/index.js +0 -0
  129. package/jest.config.js +29 -0
  130. package/package.json +24 -24
  131. package/src/adapters/CollectionViewAdapter/index.ts +390 -0
  132. package/src/adapters/index.ts +1 -0
  133. package/src/data/api/dto/PropertyPathDto.ts +4 -0
  134. package/src/data/api/dto/ReadOptionsDto.ts +8 -0
  135. package/src/data/api/dto/ReadResultDto.ts +13 -0
  136. package/src/data/api/dto/ReadResultMetadataDto.ts +8 -0
  137. package/src/data/api/dto/crud/CrudMetadataDto.ts +4 -0
  138. package/src/data/api/dto/crud/index.ts +1 -0
  139. package/src/data/api/dto/index.ts +4 -0
  140. package/src/data/api/dto/read/ReadMetadataDto.ts +8 -0
  141. package/src/data/api/dto/read/ReadSelectedDefinitionDto.ts +21 -0
  142. package/src/data/api/dto/read/ReadSelectedNestedCollectionCriteriaDto.ts +25 -0
  143. package/src/data/api/dto/read/ReadSelectedNestedCriteriaDto.ts +20 -0
  144. package/src/data/api/dto/read/ReadSelectedOrderingDefinitionDto.ts +8 -0
  145. package/src/data/api/dto/read/ReadSelectedOrderingPropertyDefinitionDto.ts +16 -0
  146. package/src/data/api/dto/read/ReadSelectedPaginationDefinitionDto.ts +13 -0
  147. package/src/data/api/dto/read/ReadSelectedSearchDefinitionDto.ts +43 -0
  148. package/src/data/api/dto/read/ReadSelectedSearchPropertyDefinitionDto.ts +186 -0
  149. package/src/data/api/dto/read/index.ts +9 -0
  150. package/src/data/api/dto/response/ApiErrorDto.ts +21 -0
  151. package/src/data/api/dto/response/ApiErrorResponseDto.ts +13 -0
  152. package/src/data/api/dto/response/ApiResponseDto.ts +7 -0
  153. package/src/data/api/dto/response/ApiSuccessResponseDto.ts +13 -0
  154. package/src/data/api/dto/response/MetadataDto.ts +24 -0
  155. package/src/data/api/dto/response/index.ts +5 -0
  156. package/src/data/api/enum/index.ts +2 -0
  157. package/src/data/api/enum/read/ReadSelectedCollectionOperator.ts +17 -0
  158. package/src/data/api/enum/read/ReadSelectedComparisonOperator.ts +96 -0
  159. package/src/data/api/enum/read/ReadSelectedLogicalOperator.ts +16 -0
  160. package/src/data/api/enum/read/ReadSelectedOrderingDirection.ts +13 -0
  161. package/src/data/api/enum/read/ReadSelectedPropertyType.ts +86 -0
  162. package/src/data/api/enum/read/index.ts +5 -0
  163. package/src/data/api/enum/response/ErrorCode.ts +13 -0
  164. package/src/data/api/enum/response/index.ts +1 -0
  165. package/src/data/api/index.ts +3 -0
  166. package/src/data/api/interface/IConcurrencySafe.ts +9 -0
  167. package/src/data/api/interface/IIdentifiable.ts +12 -0
  168. package/src/data/api/interface/IIdentifiableSecondary.ts +9 -0
  169. package/src/data/api/interface/index.ts +3 -0
  170. package/src/data/auth/dto/ClaimDto.ts +4 -0
  171. package/src/data/auth/dto/RegisterRequestDto.ts +4 -0
  172. package/src/data/auth/dto/RoleDto.ts +6 -0
  173. package/src/data/auth/dto/SignInRequestDto.ts +4 -0
  174. package/src/data/auth/dto/TokensDto.ts +4 -0
  175. package/src/data/auth/dto/UserDto.ts +18 -0
  176. package/src/data/auth/dto/UserInfoDto.ts +15 -0
  177. package/src/data/auth/dto/index.ts +4 -0
  178. package/src/data/auth/index.ts +2 -0
  179. package/src/data/auth/policy.ts +63 -0
  180. package/src/data/index.ts +2 -0
  181. package/src/index.ts +4 -0
  182. package/src/services/api/ApiCrudControllerClient/index.ts +129 -0
  183. package/src/services/api/ApiInitializationService/index.ts +254 -0
  184. package/src/services/api/ApiReadControllerClient/index.ts +137 -0
  185. package/src/services/api/HttpService/FetchHttpService.ts +34 -0
  186. package/src/services/api/HttpService/HttpRequestConfig.ts +10 -0
  187. package/src/services/api/HttpService/HttpResponse.ts +14 -0
  188. package/src/services/api/HttpService/IHttpService.ts +17 -0
  189. package/src/services/api/HttpService/README.md +106 -0
  190. package/src/services/api/HttpService/index.ts +12 -0
  191. package/src/services/api/UserManagementControllerClient/index.ts +160 -0
  192. package/src/services/api/index.ts +5 -0
  193. package/src/services/auth/client/AuthService/index.ts +187 -0
  194. package/src/services/auth/client/AuthorizationManagementControllerClient/index.ts +165 -0
  195. package/src/services/auth/client/index.ts +2 -0
  196. package/src/services/auth/index.ts +1 -0
  197. package/src/services/index.ts +2 -0
  198. package/src/utils/authorization/index.ts +47 -0
  199. package/src/utils/index.ts +2 -0
  200. package/src/utils/result/index.ts +25 -0
  201. package/src/utils/search/index.ts +150 -0
  202. package/tests/ApiClients.test.ts +284 -0
  203. package/tests/CollectionViewAdapter.test.ts +392 -0
  204. package/tests/HttpService.test.ts +303 -0
  205. package/tests/setup.ts +76 -0
  206. package/tsconfig.json +19 -0
  207. package/LICENSE.md +0 -7
  208. /package/{data → dist/data}/api/dto/read/ReadSelectedNestedCollectionCriteriaDto.d.ts +0 -0
  209. /package/{data → dist/data}/api/dto/read/ReadSelectedNestedCollectionCriteriaDto.js +0 -0
  210. /package/{data → dist/data}/api/dto/read/ReadSelectedNestedCriteriaDto.d.ts +0 -0
  211. /package/{data → dist/data}/api/dto/read/ReadSelectedNestedCriteriaDto.js +0 -0
  212. /package/{data → dist/data}/api/dto/response/ApiErrorResponseDto.d.ts +0 -0
  213. /package/{data → dist/data}/api/dto/response/ApiErrorResponseDto.js +0 -0
  214. /package/{data → dist/data}/api/dto/response/MetadataDto.d.ts +0 -0
  215. /package/{data → dist/data}/api/dto/response/MetadataDto.js +0 -0
  216. /package/{data → dist/data}/api/enum/read/ReadSelectedCollectionOperator.d.ts +0 -0
  217. /package/{data → dist/data}/api/enum/read/ReadSelectedCollectionOperator.js +0 -0
  218. /package/{data → dist/data}/api/enum/response/ErrorCode.d.ts +0 -0
  219. /package/{data → dist/data}/api/enum/response/ErrorCode.js +0 -0
  220. /package/{data → dist/data}/auth/policy.d.ts +0 -0
  221. /package/{data → dist/data}/auth/policy.js +0 -0
  222. /package/{utils → dist/utils}/authorization/index.d.ts +0 -0
  223. /package/{utils → dist/utils}/authorization/index.js +0 -0
  224. /package/{utils → dist/utils}/result/index.d.ts +0 -0
  225. /package/{utils → dist/utils}/result/index.js +0 -0
  226. /package/{utils → dist/utils}/search/index.d.ts +0 -0
  227. /package/{utils → dist/utils}/search/index.js +0 -0
@@ -0,0 +1,2 @@
1
+ export * from './result';
2
+ export * from './search';
@@ -0,0 +1,25 @@
1
+ type TResultBase = { readonly ok: boolean };
2
+
3
+ /**
4
+ * Represents a result of an operation.
5
+ * It can be either a success or an error.
6
+ */
7
+ export type Result<TSuccess extends TResultBase, TError extends TResultBase> = TSuccess | TError;
8
+
9
+ /**
10
+ * Creates a success result from the given argument.
11
+ * @param arg - The argument to create a success result from.
12
+ * @returns A success result.
13
+ */
14
+ export function ok<TSuccess extends TResultBase, TError extends TResultBase>(arg?: Omit<TSuccess, 'ok'>): Result<TSuccess, TError> {
15
+ return {ok: true, ...arg} as TSuccess;
16
+ }
17
+
18
+ /**
19
+ * Creates an error result from the given argument.
20
+ * @param arg - The argument to create an error result from.
21
+ * @returns An error result.
22
+ */
23
+ export function fail<TSuccess extends TResultBase, TError extends TResultBase>(arg: Omit<TError, 'ok'>): Result<TSuccess, TError> {
24
+ return {ok: false, ...arg} as TError;
25
+ }
@@ -0,0 +1,150 @@
1
+ import {
2
+ ReadSelectedComparisonOperator,
3
+ ReadSelectedLogicalOperator,
4
+ ReadSelectedPropertyType,
5
+ ReadSelectedSearchDefinitionDto,
6
+ ReadSelectedSearchPropertyDefinitionDto,
7
+ } from '@data';
8
+
9
+ /**
10
+ * Creates a ReadSelectedSearchDefinitionDto ready to be used with the CollectionViewAdapter
11
+ *
12
+ * @param logicalOperator - specify `ReadSelectedLogicalOperator` that will apply to all ReadSelectedSearchPropertyDefinitionDto property definitions included in this search definition
13
+ * @param conditions - Variable number of condition objects containing:
14
+ * - propertyName: The property name from the DTO to search on
15
+ * - operator: The `ReadSelectedComparisonOperator` enum
16
+ * - value: The value to compare against
17
+ * - valueType: The `ReadSelectedPropertyType` being compared
18
+ */
19
+ export function condition<T>(
20
+ logicalOperator: ReadSelectedLogicalOperator,
21
+ ...conditions: Array<{
22
+ propertyName: keyof T;
23
+ operator: ReadSelectedComparisonOperator;
24
+ value: unknown;
25
+ valueType: ReadSelectedPropertyType;
26
+ }>
27
+ ): ReadSelectedSearchDefinitionDto<T> {
28
+ return {
29
+ logicalOperator: logicalOperator,
30
+ propertyCriteria: conditions.map(
31
+ condition =>
32
+ ({
33
+ propertyName: toPascalCase(condition.propertyName),
34
+ comparisonOperator: condition.operator,
35
+ valueType: condition.valueType,
36
+ value: condition.value,
37
+ }) as ReadSelectedSearchPropertyDefinitionDto<T, keyof T>,
38
+ ),
39
+ };
40
+ }
41
+
42
+ /**
43
+ * Combines multiple ReadSelectedSearchDefinitionDto with AND logic
44
+ */
45
+ export function and<T>(...definitions: ReadSelectedSearchDefinitionDto<T>[]): ReadSelectedSearchDefinitionDto<T> {
46
+ return {
47
+ logicalOperator: ReadSelectedLogicalOperator.And,
48
+ searches: definitions,
49
+ };
50
+ }
51
+
52
+ /**
53
+ * Combines multiple ReadSelectedSearchDefinitionDto with OR logic
54
+ */
55
+ export function or<T>(...definitions: ReadSelectedSearchDefinitionDto<T>[]): ReadSelectedSearchDefinitionDto<T> {
56
+ return {
57
+ logicalOperator: ReadSelectedLogicalOperator.Or,
58
+ searches: definitions,
59
+ };
60
+ }
61
+
62
+ /**
63
+ * Preset implementation for filtering by searchTerm. String types will search by provided `textSearchableProperties` with `ReadSelectedComparisonOperator.Contains`. Numeric types will search by provided `numericSearchableProperties`, `parseInt` the search term and use `ReadSelectedComparisonOperator.Equal`.
64
+ */
65
+ export function searchTerm<T>(
66
+ searchTerm: string,
67
+ textSearchableProperties: (keyof T)[],
68
+ numericSearchableProperties: (keyof T)[],
69
+ ): void | ReadSelectedSearchDefinitionDto<T> {
70
+ let comparisonOperator: ReadSelectedComparisonOperator;
71
+ let valueType: ReadSelectedPropertyType;
72
+ let searchableProperties: (keyof T)[];
73
+ let searchValue: string | number;
74
+ try {
75
+ const numericValue = parseInt(searchTerm);
76
+
77
+ if (!Number.isNaN(numericValue) && String(numericValue) === searchTerm.trim()) {
78
+ comparisonOperator = ReadSelectedComparisonOperator.Equal;
79
+ valueType = ReadSelectedPropertyType.Int;
80
+ searchableProperties = numericSearchableProperties;
81
+ searchValue = numericValue;
82
+ } else {
83
+ comparisonOperator = ReadSelectedComparisonOperator.Contains;
84
+ valueType = ReadSelectedPropertyType.String;
85
+ searchableProperties = textSearchableProperties;
86
+ searchValue = searchTerm;
87
+ }
88
+
89
+ const searchConditions = searchableProperties.map(propertyName => ({
90
+ propertyName: toPascalCase(propertyName),
91
+ operator: comparisonOperator,
92
+ value: searchValue,
93
+ valueType: valueType,
94
+ }));
95
+
96
+ return condition(ReadSelectedLogicalOperator.Or, ...searchConditions);
97
+ } catch {
98
+ return;
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Preset implementation for filtering a date range. User may select desired `ReadSelectedComparisonOperator` and `ReadSelectedPropertyType` for the from and to dates. Valid object property must be provided for `searchableProperty`.
104
+ */
105
+ export function dateInterval<T>(
106
+ fromDate: Date,
107
+ toDate: Date,
108
+ fromDateComparisonOperator: ReadSelectedComparisonOperator,
109
+ toDateComparisonOperator: ReadSelectedComparisonOperator,
110
+ valueType: ReadSelectedPropertyType,
111
+ searchableProperty: keyof T,
112
+ ): void | ReadSelectedSearchDefinitionDto<T> {
113
+ try {
114
+ if (
115
+ !(
116
+ valueType === ReadSelectedPropertyType.DateOnly ||
117
+ valueType === ReadSelectedPropertyType.DateTime ||
118
+ valueType === ReadSelectedPropertyType.DateTimeOffset
119
+ )
120
+ ) {
121
+ return;
122
+ }
123
+
124
+ return condition(
125
+ ReadSelectedLogicalOperator.And,
126
+ {
127
+ propertyName: toPascalCase(searchableProperty),
128
+ operator: fromDateComparisonOperator,
129
+ value: fromDate,
130
+ valueType: valueType,
131
+ },
132
+ {
133
+ propertyName: toPascalCase(searchableProperty),
134
+ operator: toDateComparisonOperator,
135
+ value: toDate,
136
+ valueType: valueType,
137
+ },
138
+ );
139
+ } catch {
140
+ return;
141
+ }
142
+ }
143
+
144
+ export function toPascalCase<T>(str: keyof T): keyof T {
145
+ if (typeof str !== 'string') {
146
+ return str;
147
+ }
148
+
149
+ return (str.charAt(0).toUpperCase() + str.slice(1)) as keyof T;
150
+ }
@@ -0,0 +1,284 @@
1
+ import { ApiReadControllerClient, ApiCrudControllerClient, UserManagementControllerClient, IHttpService, HttpResponse } from '../src';
2
+ import { jest } from '@jest/globals';
3
+ import { ReadSelectedLogicalOperator } from '../src/data';
4
+
5
+ // Mock HTTP Service for testing
6
+ class MockHttpService implements IHttpService {
7
+ private mockResponses = new Map<string, HttpResponse>();
8
+ public requestLog: Array<{ url: string; config?: any }> = [];
9
+
10
+ setMockResponse(url: string, response: HttpResponse) {
11
+ this.mockResponses.set(url, response);
12
+ }
13
+
14
+ clearMockResponses() {
15
+ this.mockResponses.clear();
16
+ this.requestLog = [];
17
+ }
18
+
19
+ async request<T = any>(url: string, config?: any): Promise<HttpResponse<T>> {
20
+ this.requestLog.push({ url, config });
21
+
22
+ const mockResponse = this.mockResponses.get(url);
23
+ if (mockResponse) {
24
+ return mockResponse as HttpResponse<T>;
25
+ }
26
+
27
+ // Default successful response
28
+ return {
29
+ ok: true,
30
+ status: 200,
31
+ statusText: 'OK',
32
+ headers: {},
33
+ json: async () => ({ success: true }) as T,
34
+ text: async () => '{"success":true}',
35
+ };
36
+ }
37
+ }
38
+
39
+ // Mock API Initialization Service
40
+ jest.unstable_mockModule('../src/services/api/ApiInitializationService/index', () => ({
41
+ apiInitializationService: {
42
+ getApiUrl: jest.fn((...paths: string[]) => Promise.resolve(`https://api.example.com${paths.join('')}`)),
43
+ },
44
+ }));
45
+
46
+ describe('API Clients with HTTP Service Abstraction', () => {
47
+ let mockHttpService: MockHttpService;
48
+
49
+ beforeEach(() => {
50
+ mockHttpService = new MockHttpService();
51
+ jest.clearAllMocks();
52
+ });
53
+
54
+ describe('ApiReadControllerClient', () => {
55
+ let client: ApiReadControllerClient<number, any>;
56
+
57
+ beforeEach(() => {
58
+ client = new ApiReadControllerClient('/api/test', mockHttpService);
59
+ });
60
+
61
+ it('should use injected HTTP service for readAll', async () => {
62
+ const mockData = [
63
+ { id: 1, name: 'Test' },
64
+ { id: 2, name: 'Test2' },
65
+ ];
66
+ mockHttpService.setMockResponse('https://api.example.com/api/test/ReadAll', {
67
+ ok: true,
68
+ status: 200,
69
+ statusText: 'OK',
70
+ headers: {},
71
+ json: async () => ({ success: true, result: mockData, metadata: {} }),
72
+ text: async () => JSON.stringify({ result: mockData, metadata: {} }),
73
+ });
74
+
75
+ const result = await client.readAll();
76
+
77
+ expect(result).toEqual({ result: mockData, metadata: {} });
78
+ expect(mockHttpService.requestLog.length).toBe(1);
79
+ expect(mockHttpService.requestLog[0].url).toBe('https://api.example.com/api/test/ReadAll');
80
+ expect(mockHttpService.requestLog[0].config?.method).toBe('GET');
81
+ });
82
+
83
+ it('should use injected HTTP service for readSingle', async () => {
84
+ const mockData = { id: 1, name: 'Test' };
85
+ mockHttpService.setMockResponse('https://api.example.com/api/test/ReadSingle?id=1', {
86
+ ok: true,
87
+ status: 200,
88
+ statusText: 'OK',
89
+ headers: {},
90
+ json: async () => ({ success: true, result: mockData, metadata: {} }),
91
+ text: async () => JSON.stringify({ result: mockData, metadata: {} }),
92
+ });
93
+
94
+ const result = await client.readSingle(1);
95
+
96
+ expect(result).toEqual({ result: mockData, metadata: {} });
97
+ expect(mockHttpService.requestLog.length).toBe(1);
98
+ expect(mockHttpService.requestLog[0].url).toBe('https://api.example.com/api/test/ReadSingle?id=1');
99
+ });
100
+
101
+ it('should use injected HTTP service for readSelected', async () => {
102
+ const mockData = [{ id: 1, name: 'Test' }];
103
+ const definition = {
104
+ searchDefinition: {
105
+ searches: [],
106
+ logicalOperator: ReadSelectedLogicalOperator.And,
107
+ },
108
+ };
109
+
110
+ mockHttpService.setMockResponse('https://api.example.com/api/test/ReadSelected', {
111
+ ok: true,
112
+ status: 200,
113
+ statusText: 'OK',
114
+ headers: {},
115
+ json: async () => ({ success: true, result: mockData, metadata: {} }),
116
+ text: async () => JSON.stringify({ result: mockData, metadata: {} }),
117
+ });
118
+
119
+ const result = await client.readSelected(definition);
120
+
121
+ expect(result).toEqual({ result: mockData, metadata: {} });
122
+ expect(mockHttpService.requestLog.length).toBe(1);
123
+ expect(mockHttpService.requestLog[0].url).toBe('https://api.example.com/api/test/ReadSelected');
124
+ expect(mockHttpService.requestLog[0].config?.method).toBe('POST');
125
+ expect(mockHttpService.requestLog[0].config?.body).toBe(JSON.stringify(definition));
126
+ });
127
+
128
+ it('should handle HTTP errors properly', async () => {
129
+ mockHttpService.setMockResponse('https://api.example.com/api/test/ReadAll', {
130
+ ok: false,
131
+ status: 500,
132
+ statusText: 'Internal Server Error',
133
+ headers: {},
134
+ json: async () => ({ error: 'Server error' }),
135
+ text: async () => '{"error":"Server error"}',
136
+ });
137
+
138
+ try {
139
+ await client.readAll();
140
+ fail('Should have thrown an error');
141
+ } catch (error: any) {
142
+ expect(error.message).toContain('Unknown error fetching all records');
143
+ }
144
+ });
145
+ });
146
+
147
+ describe('ApiCrudControllerClient', () => {
148
+ let client: ApiCrudControllerClient<number, any>;
149
+
150
+ beforeEach(() => {
151
+ client = new ApiCrudControllerClient('/api/crud', mockHttpService);
152
+ });
153
+
154
+ it('should use injected HTTP service for create', async () => {
155
+ const newItem = { id: 0, name: 'New Item' };
156
+ const createdItem = { id: 1, name: 'New Item' };
157
+
158
+ mockHttpService.setMockResponse('https://api.example.com/api/crud/Create', {
159
+ ok: true,
160
+ status: 201,
161
+ statusText: 'Created',
162
+ headers: {},
163
+ json: async () => ({ success: true, result: createdItem, metadata: {} }),
164
+ text: async () => JSON.stringify({ result: createdItem, metadata: {} }),
165
+ });
166
+
167
+ const result = await client.create(newItem);
168
+
169
+ expect(result).toEqual({ result: createdItem, metadata: {} });
170
+ expect(mockHttpService.requestLog.length).toBe(1);
171
+ expect(mockHttpService.requestLog[0].url).toBe('https://api.example.com/api/crud/Create');
172
+ expect(mockHttpService.requestLog[0].config?.method).toBe('POST');
173
+ expect(mockHttpService.requestLog[0].config?.body).toBe(JSON.stringify(newItem));
174
+ });
175
+
176
+ it('should use injected HTTP service for update', async () => {
177
+ const updateItem = { id: 1, name: 'Updated Item' };
178
+
179
+ mockHttpService.setMockResponse('https://api.example.com/api/crud/Update?id=1', {
180
+ ok: true,
181
+ status: 200,
182
+ statusText: 'OK',
183
+ headers: {},
184
+ json: async () => ({ success: true, result: updateItem, metadata: {} }),
185
+ text: async () => JSON.stringify({ result: updateItem, metadata: {} }),
186
+ });
187
+
188
+ const result = await client.update(1, updateItem);
189
+
190
+ expect(result).toEqual({ result: updateItem, metadata: {} });
191
+ expect(mockHttpService.requestLog.length).toBe(1);
192
+ expect(mockHttpService.requestLog[0].url).toBe('https://api.example.com/api/crud/Update?id=1');
193
+ expect(mockHttpService.requestLog[0].config?.method).toBe('PUT');
194
+ });
195
+
196
+ it('should use injected HTTP service for delete', async () => {
197
+ mockHttpService.setMockResponse('https://api.example.com/api/crud/Delete?id=1', {
198
+ ok: true,
199
+ status: 204,
200
+ statusText: 'No Content',
201
+ headers: {},
202
+ json: async () => ({}),
203
+ text: async () => '',
204
+ });
205
+
206
+ await client.delete(1);
207
+
208
+ expect(mockHttpService.requestLog.length).toBe(1);
209
+ expect(mockHttpService.requestLog[0].url).toBe('https://api.example.com/api/crud/Delete?id=1');
210
+ expect(mockHttpService.requestLog[0].config?.method).toBe('DELETE');
211
+ });
212
+ });
213
+
214
+ describe('UserManagementControllerClient', () => {
215
+ let client: UserManagementControllerClient<number, any>;
216
+
217
+ beforeEach(() => {
218
+ client = new UserManagementControllerClient('/api/users', mockHttpService);
219
+ });
220
+
221
+ it('should use injected HTTP service for getUserRoles', async () => {
222
+ const mockRoles = ['admin', 'user'];
223
+
224
+ mockHttpService.setMockResponse('https://api.example.com/api/users/GetUserRoles/1', {
225
+ ok: true,
226
+ status: 200,
227
+ statusText: 'OK',
228
+ headers: {},
229
+ json: async () => ({ success: true, result: mockRoles, metadata: {} }),
230
+ text: async () => JSON.stringify({ result: mockRoles, metadata: {} }),
231
+ });
232
+
233
+ const result = await client.getUserRoles(1);
234
+
235
+ expect(result).toEqual({ result: mockRoles, metadata: {} });
236
+ expect(mockHttpService.requestLog.length).toBe(1);
237
+ expect(mockHttpService.requestLog[0].url).toBe('https://api.example.com/api/users/GetUserRoles/1');
238
+ expect(mockHttpService.requestLog[0].config?.method).toBe('GET');
239
+ });
240
+
241
+ it('should use injected HTTP service for getUserClaims', async () => {
242
+ const mockClaims = [
243
+ { type: 'role', value: 'admin' },
244
+ { type: 'department', value: 'IT' },
245
+ ];
246
+
247
+ mockHttpService.setMockResponse('https://api.example.com/api/users/GetUserClaims/1', {
248
+ ok: true,
249
+ status: 200,
250
+ statusText: 'OK',
251
+ headers: {},
252
+ json: async () => ({ success: true, result: mockClaims, metadata: {} }),
253
+ text: async () => JSON.stringify({ result: mockClaims, metadata: {} }),
254
+ });
255
+
256
+ const result = await client.getUserClaims(1);
257
+
258
+ expect(result).toEqual({ result: mockClaims, metadata: {} });
259
+ expect(mockHttpService.requestLog.length).toBe(1);
260
+ expect(mockHttpService.requestLog[0].url).toBe('https://api.example.com/api/users/GetUserClaims/1');
261
+ expect(mockHttpService.requestLog[0].config?.method).toBe('GET');
262
+ });
263
+
264
+ it('should use injected HTTP service for getAllRoles', async () => {
265
+ const mockRoles = ['admin', 'user', 'moderator'];
266
+
267
+ mockHttpService.setMockResponse('https://api.example.com/api/users/GetAllRoles', {
268
+ ok: true,
269
+ status: 200,
270
+ statusText: 'OK',
271
+ headers: {},
272
+ json: async () => ({ success: true, result: mockRoles, metadata: {} }),
273
+ text: async () => JSON.stringify({ result: mockRoles, metadata: {} }),
274
+ });
275
+
276
+ const result = await client.getAllRoles();
277
+
278
+ expect(result).toEqual({ result: mockRoles, metadata: {} });
279
+ expect(mockHttpService.requestLog.length).toBe(1);
280
+ expect(mockHttpService.requestLog[0].url).toBe('https://api.example.com/api/users/GetAllRoles');
281
+ expect(mockHttpService.requestLog[0].config?.method).toBe('GET');
282
+ });
283
+ });
284
+ });