@intellegens/cornerstone-client 0.0.0-experimental-upgrade-20260302-1

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 (251) hide show
  1. package/README.md +256 -0
  2. package/demo/index.ts +29 -0
  3. package/demo/public_html/favicon.ico +0 -0
  4. package/demo/public_html/index.html +106 -0
  5. package/demo/public_html/websettings.json +3 -0
  6. package/dist/adapters/CollectionViewAdapter/index.d.ts +198 -0
  7. package/dist/adapters/CollectionViewAdapter/index.integration.test.d.ts +1 -0
  8. package/dist/adapters/CollectionViewAdapter/index.integration.test.js +163 -0
  9. package/dist/adapters/CollectionViewAdapter/index.js +381 -0
  10. package/dist/adapters/SearchAdapter/index.d.ts +55 -0
  11. package/dist/adapters/SearchAdapter/index.js +233 -0
  12. package/dist/adapters/index.d.ts +2 -0
  13. package/dist/adapters/index.js +2 -0
  14. package/dist/data/api/dto/PropertyPathDto.d.ts +4 -0
  15. package/dist/data/api/dto/PropertyPathDto.js +1 -0
  16. package/dist/data/api/dto/ReadOptionsDto.d.ts +8 -0
  17. package/dist/data/api/dto/ReadOptionsDto.js +1 -0
  18. package/dist/data/api/dto/ReadResultDto.d.ts +12 -0
  19. package/dist/data/api/dto/ReadResultDto.js +1 -0
  20. package/dist/data/api/dto/ReadResultMetadataDto.d.ts +8 -0
  21. package/dist/data/api/dto/ReadResultMetadataDto.js +1 -0
  22. package/dist/data/api/dto/crud/CrudMetadataDto.d.ts +4 -0
  23. package/dist/data/api/dto/crud/CrudMetadataDto.js +1 -0
  24. package/dist/data/api/dto/crud/index.d.ts +1 -0
  25. package/dist/data/api/dto/crud/index.js +1 -0
  26. package/dist/data/api/dto/index.d.ts +4 -0
  27. package/dist/data/api/dto/index.js +4 -0
  28. package/dist/data/api/dto/read/ReadMetadataDto.d.ts +8 -0
  29. package/dist/data/api/dto/read/ReadMetadataDto.js +1 -0
  30. package/dist/data/api/dto/read/ReadSelectedDefinitionDto.d.ts +18 -0
  31. package/dist/data/api/dto/read/ReadSelectedDefinitionDto.js +1 -0
  32. package/dist/data/api/dto/read/ReadSelectedNestedCollectionCriteriaDto.d.ts +22 -0
  33. package/dist/data/api/dto/read/ReadSelectedNestedCollectionCriteriaDto.js +1 -0
  34. package/dist/data/api/dto/read/ReadSelectedNestedCriteriaDto.d.ts +18 -0
  35. package/dist/data/api/dto/read/ReadSelectedNestedCriteriaDto.js +1 -0
  36. package/dist/data/api/dto/read/ReadSelectedOrderingDefinitionDto.d.ts +7 -0
  37. package/dist/data/api/dto/read/ReadSelectedOrderingDefinitionDto.js +1 -0
  38. package/dist/data/api/dto/read/ReadSelectedOrderingPropertyDefinitionDto.d.ts +14 -0
  39. package/dist/data/api/dto/read/ReadSelectedOrderingPropertyDefinitionDto.js +1 -0
  40. package/dist/data/api/dto/read/ReadSelectedPaginationDefinitionDto.d.ts +13 -0
  41. package/dist/data/api/dto/read/ReadSelectedPaginationDefinitionDto.js +1 -0
  42. package/dist/data/api/dto/read/ReadSelectedSearchDefinitionBuilder.d.ts +167 -0
  43. package/dist/data/api/dto/read/ReadSelectedSearchDefinitionBuilder.js +267 -0
  44. package/dist/data/api/dto/read/ReadSelectedSearchDefinitionDto.d.ts +33 -0
  45. package/dist/data/api/dto/read/ReadSelectedSearchDefinitionDto.js +1 -0
  46. package/dist/data/api/dto/read/ReadSelectedSearchPropertyDefinitionDto.d.ts +114 -0
  47. package/dist/data/api/dto/read/ReadSelectedSearchPropertyDefinitionDto.js +1 -0
  48. package/dist/data/api/dto/read/index.d.ts +10 -0
  49. package/dist/data/api/dto/read/index.js +10 -0
  50. package/dist/data/api/dto/response/ApiErrorDto.d.ts +17 -0
  51. package/dist/data/api/dto/response/ApiErrorDto.js +1 -0
  52. package/dist/data/api/dto/response/ApiErrorResponseDto.d.ts +11 -0
  53. package/dist/data/api/dto/response/ApiErrorResponseDto.js +1 -0
  54. package/dist/data/api/dto/response/ApiResponseDto.d.ts +3 -0
  55. package/dist/data/api/dto/response/ApiResponseDto.js +1 -0
  56. package/dist/data/api/dto/response/ApiSuccessResponseDto.d.ts +13 -0
  57. package/dist/data/api/dto/response/ApiSuccessResponseDto.js +1 -0
  58. package/dist/data/api/dto/response/EmptyMetadataDto.d.ts +4 -0
  59. package/dist/data/api/dto/response/EmptyMetadataDto.js +1 -0
  60. package/dist/data/api/dto/response/MetadataDto.d.ts +25 -0
  61. package/dist/data/api/dto/response/MetadataDto.js +1 -0
  62. package/dist/data/api/dto/response/index.d.ts +5 -0
  63. package/dist/data/api/dto/response/index.js +5 -0
  64. package/dist/data/api/enum/index.d.ts +2 -0
  65. package/dist/data/api/enum/index.js +2 -0
  66. package/dist/data/api/enum/read/ReadSelectedCollectionOperator.d.ts +16 -0
  67. package/dist/data/api/enum/read/ReadSelectedCollectionOperator.js +17 -0
  68. package/dist/data/api/enum/read/ReadSelectedComparisonOperator.d.ts +69 -0
  69. package/dist/data/api/enum/read/ReadSelectedComparisonOperator.js +76 -0
  70. package/dist/data/api/enum/read/ReadSelectedLogicalOperator.d.ts +15 -0
  71. package/dist/data/api/enum/read/ReadSelectedLogicalOperator.js +16 -0
  72. package/dist/data/api/enum/read/ReadSelectedOrderingDirection.d.ts +13 -0
  73. package/dist/data/api/enum/read/ReadSelectedOrderingDirection.js +14 -0
  74. package/dist/data/api/enum/read/ReadSelectedPropertyType.d.ts +66 -0
  75. package/dist/data/api/enum/read/ReadSelectedPropertyType.js +75 -0
  76. package/dist/data/api/enum/read/index.d.ts +5 -0
  77. package/dist/data/api/enum/read/index.js +5 -0
  78. package/dist/data/api/enum/response/ApiErrorCodes.d.ts +7 -0
  79. package/dist/data/api/enum/response/ApiErrorCodes.js +8 -0
  80. package/dist/data/api/enum/response/ErrorCode.d.ts +13 -0
  81. package/dist/data/api/enum/response/ErrorCode.js +14 -0
  82. package/dist/data/api/enum/response/index.d.ts +1 -0
  83. package/dist/data/api/enum/response/index.js +1 -0
  84. package/dist/data/api/index.d.ts +3 -0
  85. package/dist/data/api/index.js +3 -0
  86. package/dist/data/api/interface/ICommonIdentifiable.d.ts +7 -0
  87. package/dist/data/api/interface/ICommonIdentifiable.js +1 -0
  88. package/dist/data/api/interface/IConcurrencySafe.d.ts +9 -0
  89. package/dist/data/api/interface/IConcurrencySafe.js +2 -0
  90. package/dist/data/api/interface/IIdentifiable.d.ts +11 -0
  91. package/dist/data/api/interface/IIdentifiable.js +1 -0
  92. package/dist/data/api/interface/IIdentifiableSecondary.d.ts +9 -0
  93. package/dist/data/api/interface/IIdentifiableSecondary.js +1 -0
  94. package/dist/data/api/interface/index.d.ts +3 -0
  95. package/dist/data/api/interface/index.js +3 -0
  96. package/dist/data/auth/dto/ClaimDto.d.ts +4 -0
  97. package/dist/data/auth/dto/ClaimDto.js +1 -0
  98. package/dist/data/auth/dto/RegisterRequestDto.d.ts +4 -0
  99. package/dist/data/auth/dto/RegisterRequestDto.js +1 -0
  100. package/dist/data/auth/dto/RoleDto.d.ts +5 -0
  101. package/dist/data/auth/dto/RoleDto.js +1 -0
  102. package/dist/data/auth/dto/SignInRequestDto.d.ts +4 -0
  103. package/dist/data/auth/dto/SignInRequestDto.js +1 -0
  104. package/dist/data/auth/dto/TokensDto.d.ts +4 -0
  105. package/dist/data/auth/dto/TokensDto.js +1 -0
  106. package/dist/data/auth/dto/UserDto.d.ts +17 -0
  107. package/dist/data/auth/dto/UserDto.js +1 -0
  108. package/dist/data/auth/dto/UserInfoDto.d.ts +14 -0
  109. package/dist/data/auth/dto/UserInfoDto.js +1 -0
  110. package/dist/data/auth/dto/index.d.ts +5 -0
  111. package/dist/data/auth/dto/index.js +5 -0
  112. package/dist/data/auth/index.d.ts +2 -0
  113. package/dist/data/auth/index.js +2 -0
  114. package/dist/data/auth/policy.d.ts +52 -0
  115. package/dist/data/auth/policy.js +44 -0
  116. package/dist/data/index.d.ts +2 -0
  117. package/dist/data/index.js +2 -0
  118. package/dist/index.d.ts +4 -0
  119. package/dist/index.js +4 -0
  120. package/dist/services/api/ApiCrudControllerClient/index.d.ts +41 -0
  121. package/dist/services/api/ApiCrudControllerClient/index.integration.test.d.ts +1 -0
  122. package/dist/services/api/ApiCrudControllerClient/index.integration.test.js +34 -0
  123. package/dist/services/api/ApiCrudControllerClient/index.js +116 -0
  124. package/dist/services/api/ApiInitializationService/index.d.ts +106 -0
  125. package/dist/services/api/ApiInitializationService/index.js +208 -0
  126. package/dist/services/api/ApiReadControllerClient/index.d.ts +40 -0
  127. package/dist/services/api/ApiReadControllerClient/index.integration.test.d.ts +1 -0
  128. package/dist/services/api/ApiReadControllerClient/index.integration.test.js +59 -0
  129. package/dist/services/api/ApiReadControllerClient/index.js +111 -0
  130. package/dist/services/api/HttpService/FetchHttpService.d.ts +7 -0
  131. package/dist/services/api/HttpService/FetchHttpService.integration.test.d.ts +1 -0
  132. package/dist/services/api/HttpService/FetchHttpService.integration.test.js +52 -0
  133. package/dist/services/api/HttpService/FetchHttpService.js +29 -0
  134. package/dist/services/api/HttpService/HttpRequestConfig.d.ts +10 -0
  135. package/dist/services/api/HttpService/HttpRequestConfig.js +1 -0
  136. package/dist/services/api/HttpService/HttpResponse.d.ts +11 -0
  137. package/dist/services/api/HttpService/HttpResponse.js +3 -0
  138. package/dist/services/api/HttpService/IHttpService.d.ts +13 -0
  139. package/dist/services/api/HttpService/IHttpService.js +3 -0
  140. package/dist/services/api/HttpService/index.d.ts +9 -0
  141. package/dist/services/api/HttpService/index.js +10 -0
  142. package/dist/services/api/UserManagementControllerClient/index.d.ts +41 -0
  143. package/dist/services/api/UserManagementControllerClient/index.integration.test.d.ts +1 -0
  144. package/dist/services/api/UserManagementControllerClient/index.integration.test.js +60 -0
  145. package/dist/services/api/UserManagementControllerClient/index.js +117 -0
  146. package/dist/services/api/index.d.ts +5 -0
  147. package/dist/services/api/index.js +5 -0
  148. package/dist/services/auth/client/AuthService/index.d.ts +75 -0
  149. package/dist/services/auth/client/AuthService/index.js +200 -0
  150. package/dist/services/auth/client/AuthorizationManagementControllerClient/index.d.ts +48 -0
  151. package/dist/services/auth/client/AuthorizationManagementControllerClient/index.integration.test.d.ts +1 -0
  152. package/dist/services/auth/client/AuthorizationManagementControllerClient/index.integration.test.js +89 -0
  153. package/dist/services/auth/client/AuthorizationManagementControllerClient/index.js +148 -0
  154. package/dist/services/auth/client/index.d.ts +2 -0
  155. package/dist/services/auth/client/index.js +2 -0
  156. package/dist/services/auth/index.d.ts +1 -0
  157. package/dist/services/auth/index.js +1 -0
  158. package/dist/services/index.d.ts +2 -0
  159. package/dist/services/index.js +2 -0
  160. package/dist/utils/authorization/index.d.ts +17 -0
  161. package/dist/utils/authorization/index.js +45 -0
  162. package/dist/utils/index.d.ts +2 -0
  163. package/dist/utils/index.js +2 -0
  164. package/dist/utils/result/index.d.ts +21 -0
  165. package/dist/utils/result/index.js +16 -0
  166. package/dist/utils/search/index.d.ts +34 -0
  167. package/dist/utils/search/index.js +106 -0
  168. package/package.json +45 -0
  169. package/src/adapters/CollectionViewAdapter/index.integration.test.ts +197 -0
  170. package/src/adapters/CollectionViewAdapter/index.ts +477 -0
  171. package/src/adapters/SearchAdapter/index.ts +302 -0
  172. package/src/adapters/index.ts +2 -0
  173. package/src/data/api/dto/PropertyPathDto.ts +4 -0
  174. package/src/data/api/dto/ReadOptionsDto.ts +8 -0
  175. package/src/data/api/dto/ReadResultDto.ts +13 -0
  176. package/src/data/api/dto/ReadResultMetadataDto.ts +8 -0
  177. package/src/data/api/dto/crud/CrudMetadataDto.ts +4 -0
  178. package/src/data/api/dto/crud/index.ts +1 -0
  179. package/src/data/api/dto/index.ts +4 -0
  180. package/src/data/api/dto/read/ReadMetadataDto.ts +8 -0
  181. package/src/data/api/dto/read/ReadSelectedDefinitionDto.ts +21 -0
  182. package/src/data/api/dto/read/ReadSelectedNestedCollectionCriteriaDto.ts +25 -0
  183. package/src/data/api/dto/read/ReadSelectedNestedCriteriaDto.ts +20 -0
  184. package/src/data/api/dto/read/ReadSelectedOrderingDefinitionDto.ts +8 -0
  185. package/src/data/api/dto/read/ReadSelectedOrderingPropertyDefinitionDto.ts +16 -0
  186. package/src/data/api/dto/read/ReadSelectedPaginationDefinitionDto.ts +13 -0
  187. package/src/data/api/dto/read/ReadSelectedSearchDefinitionBuilder.ts +348 -0
  188. package/src/data/api/dto/read/ReadSelectedSearchDefinitionDto.ts +43 -0
  189. package/src/data/api/dto/read/ReadSelectedSearchPropertyDefinitionDto.ts +186 -0
  190. package/src/data/api/dto/read/index.ts +10 -0
  191. package/src/data/api/dto/response/ApiErrorDto.ts +21 -0
  192. package/src/data/api/dto/response/ApiErrorResponseDto.ts +13 -0
  193. package/src/data/api/dto/response/ApiResponseDto.ts +7 -0
  194. package/src/data/api/dto/response/ApiSuccessResponseDto.ts +13 -0
  195. package/src/data/api/dto/response/MetadataDto.ts +24 -0
  196. package/src/data/api/dto/response/index.ts +5 -0
  197. package/src/data/api/enum/index.ts +2 -0
  198. package/src/data/api/enum/read/ReadSelectedCollectionOperator.ts +17 -0
  199. package/src/data/api/enum/read/ReadSelectedComparisonOperator.ts +96 -0
  200. package/src/data/api/enum/read/ReadSelectedLogicalOperator.ts +16 -0
  201. package/src/data/api/enum/read/ReadSelectedOrderingDirection.ts +13 -0
  202. package/src/data/api/enum/read/ReadSelectedPropertyType.ts +96 -0
  203. package/src/data/api/enum/read/index.ts +5 -0
  204. package/src/data/api/enum/response/ErrorCode.ts +13 -0
  205. package/src/data/api/enum/response/index.ts +1 -0
  206. package/src/data/api/index.ts +3 -0
  207. package/src/data/api/interface/ICommonIdentifiable.ts +9 -0
  208. package/src/data/api/interface/IConcurrencySafe.ts +9 -0
  209. package/src/data/api/interface/IIdentifiable.ts +12 -0
  210. package/src/data/api/interface/IIdentifiableSecondary.ts +9 -0
  211. package/src/data/api/interface/index.ts +3 -0
  212. package/src/data/auth/dto/ClaimDto.ts +4 -0
  213. package/src/data/auth/dto/RegisterRequestDto.ts +4 -0
  214. package/src/data/auth/dto/RoleDto.ts +6 -0
  215. package/src/data/auth/dto/SignInRequestDto.ts +4 -0
  216. package/src/data/auth/dto/TokensDto.ts +4 -0
  217. package/src/data/auth/dto/UserDto.ts +18 -0
  218. package/src/data/auth/dto/UserInfoDto.ts +15 -0
  219. package/src/data/auth/dto/index.ts +5 -0
  220. package/src/data/auth/index.ts +2 -0
  221. package/src/data/auth/policy.ts +63 -0
  222. package/src/data/index.ts +2 -0
  223. package/src/index.ts +4 -0
  224. package/src/services/api/ApiCrudControllerClient/index.integration.test.ts +46 -0
  225. package/src/services/api/ApiCrudControllerClient/index.ts +135 -0
  226. package/src/services/api/ApiInitializationService/index.ts +254 -0
  227. package/src/services/api/ApiReadControllerClient/index.integration.test.ts +71 -0
  228. package/src/services/api/ApiReadControllerClient/index.ts +137 -0
  229. package/src/services/api/HttpService/FetchHttpService.integration.test.ts +65 -0
  230. package/src/services/api/HttpService/FetchHttpService.ts +34 -0
  231. package/src/services/api/HttpService/HttpRequestConfig.ts +10 -0
  232. package/src/services/api/HttpService/HttpResponse.ts +14 -0
  233. package/src/services/api/HttpService/IHttpService.ts +17 -0
  234. package/src/services/api/HttpService/README.md +106 -0
  235. package/src/services/api/HttpService/index.ts +12 -0
  236. package/src/services/api/UserManagementControllerClient/index.integration.test.ts +69 -0
  237. package/src/services/api/UserManagementControllerClient/index.ts +134 -0
  238. package/src/services/api/index.ts +5 -0
  239. package/src/services/auth/client/AuthService/index.ts +233 -0
  240. package/src/services/auth/client/AuthorizationManagementControllerClient/index.integration.test.ts +110 -0
  241. package/src/services/auth/client/AuthorizationManagementControllerClient/index.ts +165 -0
  242. package/src/services/auth/client/index.ts +2 -0
  243. package/src/services/auth/index.ts +1 -0
  244. package/src/services/index.ts +2 -0
  245. package/src/utils/authorization/index.ts +47 -0
  246. package/src/utils/index.ts +2 -0
  247. package/src/utils/result/index.ts +25 -0
  248. package/src/utils/search/index.ts +150 -0
  249. package/tsconfig.json +19 -0
  250. package/vitest-setup.ts +43 -0
  251. package/vitest.config.ts +59 -0
@@ -0,0 +1,111 @@
1
+ import { apiInitializationService } from '../ApiInitializationService';
2
+ import { fail, ok } from '../../../utils/result';
3
+ import { ErrorCode } from '../../../data';
4
+ /**
5
+ * Base client for read-only API controllers
6
+ */
7
+ export class ApiReadControllerClient {
8
+ baseControllerPath;
9
+ /**
10
+ * Constructor
11
+ * @param baseControllerPath Base path to API controller
12
+ * @param httpService HTTP service implementation to use for requests
13
+ */
14
+ constructor(baseControllerPath, httpService) {
15
+ this.baseControllerPath = baseControllerPath;
16
+ this._httpService = httpService;
17
+ }
18
+ // #region HTTP service
19
+ _httpService = undefined;
20
+ /**
21
+ * Gets globally selected HTTP service
22
+ */
23
+ get httpService() {
24
+ return this._httpService || apiInitializationService._getHttpService();
25
+ }
26
+ // #endregion
27
+ // #region API
28
+ /**
29
+ * Fetches all entities from the read controller.
30
+ * @param {AbortSignal} [signal] - Optional cancellation signal
31
+ * @returns {Promise<ApiSuccessResponseDto<TDto>[], ReadMetadataDto>>} List of all entities with metadata
32
+ */
33
+ async readAll(signal) {
34
+ try {
35
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/ReadAll`);
36
+ const res = await this.httpService.request(url, { method: 'GET', credentials: 'include', signal });
37
+ if (!res.ok) {
38
+ return fail(await res.json());
39
+ }
40
+ return ok(await res.json());
41
+ }
42
+ catch (err) {
43
+ console.error(err);
44
+ return fail({
45
+ error: {
46
+ code: ErrorCode.UnknownError,
47
+ message: 'Unknown error fetching all records',
48
+ metadata: {},
49
+ },
50
+ });
51
+ }
52
+ }
53
+ /**
54
+ * Fetches selected entities based on a filter definition.
55
+ * @param {any} definition - The filter definition object
56
+ * @param {AbortSignal} [signal] - Optional cancellation signal
57
+ * @returns {Promise<ApiSuccessResponseDto<TDto>[], ReadMetadataDto>>} The result of the read operation with metadata
58
+ */
59
+ async readSelected(definition, signal) {
60
+ try {
61
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/ReadSelected`);
62
+ const res = await this.httpService.request(url, {
63
+ method: 'POST',
64
+ headers: { 'Content-Type': 'application/json' },
65
+ body: JSON.stringify(definition),
66
+ credentials: 'include',
67
+ signal,
68
+ });
69
+ if (!res.ok) {
70
+ return fail(await res.json());
71
+ }
72
+ return ok(await res.json());
73
+ }
74
+ catch (err) {
75
+ console.error(err);
76
+ return fail({
77
+ error: {
78
+ code: ErrorCode.UnknownError,
79
+ message: 'Unknown error fetching selected records',
80
+ metadata: {},
81
+ },
82
+ });
83
+ }
84
+ }
85
+ /**
86
+ * Fetches a single entity by its ID.
87
+ * @param {TKey} id - The ID of the entity
88
+ * @param {AbortSignal} [signal] - Optional cancellation signal
89
+ * @returns {Promise<ApiSuccessResponseDto<TDto, EmptyMetadataDto>>} The requested entity
90
+ */
91
+ async readSingle(id, signal) {
92
+ try {
93
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/ReadSingle?id=${encodeURIComponent(String(id))}`);
94
+ const res = await this.httpService.request(url, { method: 'GET', credentials: 'include', signal });
95
+ if (!res.ok) {
96
+ return fail(await res.json());
97
+ }
98
+ return ok(await res.json());
99
+ }
100
+ catch (err) {
101
+ console.error(err);
102
+ return fail({
103
+ error: {
104
+ code: ErrorCode.UnknownError,
105
+ message: `Unknown error fetching record with id ${id}`,
106
+ metadata: {},
107
+ },
108
+ });
109
+ }
110
+ }
111
+ }
@@ -0,0 +1,7 @@
1
+ import { HttpRequestConfig, HttpResponse, IHttpService } from '../../../services';
2
+ /**
3
+ * Default HTTP service implementation using the Fetch API
4
+ */
5
+ export declare class FetchHttpService implements IHttpService {
6
+ request<T = any>(url: string, config?: HttpRequestConfig): Promise<HttpResponse<T>>;
7
+ }
@@ -0,0 +1,52 @@
1
+ import { beforeEach, describe, expect, it } from 'vitest';
2
+ import { FetchHttpService } from './FetchHttpService';
3
+ const baseUrl = 'http://localhost:5000/api';
4
+ const credentials = {
5
+ username: 'admin@test.com',
6
+ password: 'Password1234!',
7
+ };
8
+ describe('FetchHttpService', () => {
9
+ let fetchService;
10
+ beforeEach(() => {
11
+ fetchService = new FetchHttpService();
12
+ });
13
+ it('should make a GET request successfully', async () => {
14
+ const result = await fetchService.request(`${baseUrl}/AnythingManuallyMappedRead/ReadAll`);
15
+ expect(result.ok).toBe(true);
16
+ expect(result.status).toBe(200);
17
+ expect(result.statusText).toBe('OK');
18
+ const jsonData = await result.json();
19
+ expect(jsonData.result).toBeDefined();
20
+ expect(jsonData.error).toBeNull();
21
+ });
22
+ it('should make a POST request with body', async () => {
23
+ const result = await fetchService.request(`${baseUrl}/auth/signin`, {
24
+ method: 'POST',
25
+ headers: { 'Content-Type': 'application/json' },
26
+ body: JSON.stringify(credentials),
27
+ });
28
+ expect(result.ok).toBe(true);
29
+ expect(result.status).toBe(204);
30
+ });
31
+ it('should handle non-ok responses', async () => {
32
+ const result = await fetchService.request(`${baseUrl}/auth/signin`, {
33
+ method: 'POST',
34
+ headers: { 'Content-Type': 'application/json' },
35
+ body: JSON.stringify({ username: credentials.username, password: `${credentials.password}wrong` }),
36
+ });
37
+ expect(result.ok).toBe(false);
38
+ expect(result.status).toBe(400);
39
+ expect(result.statusText).toBe('Bad Request');
40
+ const jsonData = await result.json();
41
+ expect(jsonData.result).toBeNull();
42
+ expect(jsonData.error).toBeDefined();
43
+ expect(jsonData.error.code).toBe(400);
44
+ expect(jsonData.error.message).toBe('Invalid email or password');
45
+ });
46
+ it('should handle fetch errors from backend', async () => {
47
+ const result = await fetchService.request('http://localhost:5000/api/error');
48
+ expect(result.ok).toBe(false);
49
+ expect(result.status).toBe(404);
50
+ expect(result.statusText).toBe('Not Found');
51
+ });
52
+ });
@@ -0,0 +1,29 @@
1
+ // Ignore eslint any error in this file
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ /**
4
+ * Default HTTP service implementation using the Fetch API
5
+ */
6
+ export class FetchHttpService {
7
+ async request(url, config) {
8
+ const response = await fetch(url, {
9
+ method: config?.method || 'GET',
10
+ headers: config?.headers,
11
+ body: config?.body,
12
+ credentials: config?.credentials || 'include',
13
+ signal: config?.signal,
14
+ });
15
+ // Convert Headers to a plain object
16
+ const headers = {};
17
+ response.headers.forEach((value, key) => {
18
+ headers[key] = value;
19
+ });
20
+ return {
21
+ ok: response.ok,
22
+ status: response.status,
23
+ statusText: response.statusText,
24
+ headers,
25
+ json: () => response.json(),
26
+ text: () => response.text(),
27
+ };
28
+ }
29
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * HTTP request configuration interface
3
+ */
4
+ export interface HttpRequestConfig {
5
+ method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
6
+ headers?: Record<string, string>;
7
+ body?: string;
8
+ credentials?: RequestCredentials;
9
+ signal?: AbortSignal;
10
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ /**
2
+ * HTTP response interface
3
+ */
4
+ export interface HttpResponse<T = any> {
5
+ ok: boolean;
6
+ status: number;
7
+ statusText: string;
8
+ headers: Record<string, string>;
9
+ json(): Promise<T>;
10
+ text(): Promise<string>;
11
+ }
@@ -0,0 +1,3 @@
1
+ // Ignore eslint any error in this file
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ export {};
@@ -0,0 +1,13 @@
1
+ import { HttpRequestConfig, HttpResponse } from '../../../services';
2
+ /**
3
+ * Abstract HTTP service interface that can be implemented by different HTTP clients
4
+ */
5
+ export interface IHttpService {
6
+ /**
7
+ * Performs an HTTP request
8
+ * @param url - The URL to make the request to
9
+ * @param config - Request configuration
10
+ * @returns Promise that resolves to the HTTP response
11
+ */
12
+ request<T = any>(url: string, config?: HttpRequestConfig): Promise<HttpResponse<T>>;
13
+ }
@@ -0,0 +1,3 @@
1
+ // Ignore eslint any error in this file
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ export {};
@@ -0,0 +1,9 @@
1
+ import { FetchHttpService } from './FetchHttpService';
2
+ /**
3
+ * Default HTTP service instance
4
+ */
5
+ export declare const defaultHttpService: FetchHttpService;
6
+ export * from './FetchHttpService';
7
+ export * from './HttpRequestConfig';
8
+ export * from './HttpResponse';
9
+ export * from './IHttpService';
@@ -0,0 +1,10 @@
1
+ import { FetchHttpService } from './FetchHttpService';
2
+ /**
3
+ * Default HTTP service instance
4
+ */
5
+ export const defaultHttpService = new FetchHttpService();
6
+ // Export additional HTTP service implementations
7
+ export * from './FetchHttpService';
8
+ export * from './HttpRequestConfig';
9
+ export * from './HttpResponse';
10
+ export * from './IHttpService';
@@ -0,0 +1,41 @@
1
+ import { ApiCrudControllerClient } from '../ApiCrudControllerClient';
2
+ import { IHttpService } from '../HttpService';
3
+ import { ApiResponseDto, ClaimDto, EmptyMetadataDto, ReadMetadataDto, UserDto } from '../../../data';
4
+ /**
5
+ * Client for user management operations
6
+ *
7
+ * @export
8
+ * @class UserManagementControllerClient
9
+ * @template TKey - Type of the entity key (e.g., number, string, GUID, etc.)
10
+ * @template TUser - Data Transfer Object representing the user entity
11
+ */
12
+ export declare class UserManagementControllerClient<TKey, TResultDto extends UserDto<TKey>, TSingleResultDto extends UserDto<TKey>, TInsertRequestDto extends UserDto<TKey>, TUpdateRequestDto extends UserDto<TKey>> extends ApiCrudControllerClient<TKey, TResultDto, TSingleResultDto, TInsertRequestDto, TUpdateRequestDto> {
13
+ /**
14
+ * Constructor
15
+ * @param baseControllerPath Base path to API controller
16
+ * @param httpService HTTP service implementation to use for requests
17
+ */
18
+ constructor(baseControllerPath: string, httpService?: IHttpService);
19
+ /**
20
+ * Gets the roles assigned to a user
21
+ * @param id - The ID of the user
22
+ * @param {AbortSignal} [signal] - Optional cancellation signal
23
+ * @returns List of role names assigned to the user
24
+ */
25
+ getUserRoles(id: TKey, signal?: AbortSignal): Promise<ApiResponseDto<string[], ReadMetadataDto>>;
26
+ /**
27
+ * Gets the claims assigned to a user
28
+ * @param id - The ID of the user
29
+ * @param {AbortSignal} [signal] - Optional cancellation signal
30
+ * @returns List of claims assigned to the user
31
+ */
32
+ getUserClaims(id: TKey, signal?: AbortSignal): Promise<ApiResponseDto<ClaimDto[], ReadMetadataDto>>;
33
+ /**
34
+ * Changes the password for a user
35
+ * @param id - The ID of the user
36
+ * @param newPassword - The new password to set
37
+ * @param {AbortSignal} [signal] - Optional cancellation signal
38
+ * @returns Promise that resolves when the password is changed successfully
39
+ */
40
+ changePassword(id: TKey, newPassword: string, signal?: AbortSignal): Promise<ApiResponseDto<undefined, EmptyMetadataDto>>;
41
+ }
@@ -0,0 +1,60 @@
1
+ import { beforeAll, beforeEach, describe, expect, it } from 'vitest';
2
+ import { UserManagementControllerClient } from '.';
3
+ import fetchOrig from 'node-fetch';
4
+ import fetchCookie from 'fetch-cookie';
5
+ import { CookieJar } from 'tough-cookie';
6
+ // Create a fetch instance that handles auth cookies
7
+ const jar = new CookieJar();
8
+ const cookieFetch = fetchCookie(fetchOrig, jar);
9
+ // Custom IHttpService implementation for tests
10
+ class CookieFetchHttpService {
11
+ async request(url, config) {
12
+ const response = await cookieFetch(url, {
13
+ method: config?.method || 'GET',
14
+ headers: config?.headers,
15
+ body: config?.body,
16
+ signal: config?.signal,
17
+ });
18
+ const headers = {};
19
+ response.headers.forEach((value, key) => {
20
+ headers[key] = value;
21
+ });
22
+ return {
23
+ ok: response.ok,
24
+ status: response.status,
25
+ statusText: response.statusText,
26
+ headers,
27
+ json: () => response.json(),
28
+ text: () => response.text(),
29
+ };
30
+ }
31
+ }
32
+ const credentials = {
33
+ username: 'admin@test.com',
34
+ password: 'Password1234!',
35
+ };
36
+ const baseUrl = 'http://localhost:5000/api';
37
+ describe('UserManagementControllerClient', () => {
38
+ let client;
39
+ let fetchService = new CookieFetchHttpService();
40
+ beforeAll(async () => {
41
+ await fetchService.request(`${baseUrl}/auth/signin`, {
42
+ method: 'POST',
43
+ headers: { 'Content-Type': 'application/json' },
44
+ body: JSON.stringify(credentials),
45
+ });
46
+ });
47
+ beforeEach(() => {
48
+ client = new UserManagementControllerClient('/users', fetchService);
49
+ });
50
+ it('should use injected HTTP service for getUserRoles', async () => {
51
+ const result = (await client.getUserRoles(1));
52
+ expect(result.ok).toBe(true);
53
+ expect(result.result).toBeDefined();
54
+ });
55
+ it('should use injected HTTP service for getUserClaims', async () => {
56
+ const result = (await client.getUserClaims(1));
57
+ expect(result.ok).toBe(true);
58
+ expect(result.result).toBeDefined();
59
+ });
60
+ });
@@ -0,0 +1,117 @@
1
+ import { ApiCrudControllerClient } from '../ApiCrudControllerClient';
2
+ import { apiInitializationService } from '../ApiInitializationService';
3
+ import { ErrorCode } from '../../../data';
4
+ import { fail, ok } from '../../../utils/result';
5
+ /**
6
+ * Client for user management operations
7
+ *
8
+ * @export
9
+ * @class UserManagementControllerClient
10
+ * @template TKey - Type of the entity key (e.g., number, string, GUID, etc.)
11
+ * @template TUser - Data Transfer Object representing the user entity
12
+ */
13
+ export class UserManagementControllerClient extends ApiCrudControllerClient {
14
+ /**
15
+ * Constructor
16
+ * @param baseControllerPath Base path to API controller
17
+ * @param httpService HTTP service implementation to use for requests
18
+ */
19
+ constructor(baseControllerPath, httpService) {
20
+ super(baseControllerPath, httpService);
21
+ }
22
+ /**
23
+ * Gets the roles assigned to a user
24
+ * @param id - The ID of the user
25
+ * @param {AbortSignal} [signal] - Optional cancellation signal
26
+ * @returns List of role names assigned to the user
27
+ */
28
+ async getUserRoles(id, signal) {
29
+ try {
30
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, 'GetUserRoles', encodeURIComponent(String(id)));
31
+ const res = await this.httpService.request(url, {
32
+ method: 'GET',
33
+ credentials: 'include',
34
+ signal,
35
+ });
36
+ if (!res.ok) {
37
+ return fail(await res.json());
38
+ }
39
+ return ok(await res.json());
40
+ }
41
+ catch (err) {
42
+ console.error(err);
43
+ return fail({
44
+ error: {
45
+ code: ErrorCode.UnknownError,
46
+ message: 'Unknown error while fetching user roles',
47
+ metadata: {},
48
+ },
49
+ });
50
+ }
51
+ }
52
+ /**
53
+ * Gets the claims assigned to a user
54
+ * @param id - The ID of the user
55
+ * @param {AbortSignal} [signal] - Optional cancellation signal
56
+ * @returns List of claims assigned to the user
57
+ */
58
+ async getUserClaims(id, signal) {
59
+ try {
60
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, 'GetUserClaims', encodeURIComponent(String(id)));
61
+ const res = await this.httpService.request(url, {
62
+ method: 'GET',
63
+ credentials: 'include',
64
+ signal,
65
+ });
66
+ if (!res.ok) {
67
+ return fail(await res.json());
68
+ }
69
+ return ok(await res.json());
70
+ }
71
+ catch (err) {
72
+ console.error(err);
73
+ return fail({
74
+ error: {
75
+ code: ErrorCode.UnknownError,
76
+ message: 'Unknown error while fetching user claims',
77
+ metadata: {},
78
+ },
79
+ });
80
+ }
81
+ }
82
+ /**
83
+ * Changes the password for a user
84
+ * @param id - The ID of the user
85
+ * @param newPassword - The new password to set
86
+ * @param {AbortSignal} [signal] - Optional cancellation signal
87
+ * @returns Promise that resolves when the password is changed successfully
88
+ */
89
+ async changePassword(id, newPassword, signal) {
90
+ try {
91
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, 'ChangePassword', encodeURIComponent(String(id)));
92
+ const res = await this.httpService.request(url, {
93
+ method: 'POST',
94
+ headers: {
95
+ 'Content-Type': 'application/json',
96
+ },
97
+ body: JSON.stringify(newPassword),
98
+ credentials: 'include',
99
+ signal,
100
+ });
101
+ if (!res.ok) {
102
+ return fail(await res.json());
103
+ }
104
+ return ok(undefined);
105
+ }
106
+ catch (err) {
107
+ console.error(err);
108
+ return fail({
109
+ error: {
110
+ code: ErrorCode.UnknownError,
111
+ message: 'Unknown error while changing password',
112
+ metadata: {},
113
+ },
114
+ });
115
+ }
116
+ }
117
+ }
@@ -0,0 +1,5 @@
1
+ export * from './HttpService';
2
+ export * from './ApiInitializationService';
3
+ export * from './ApiReadControllerClient';
4
+ export * from './ApiCrudControllerClient';
5
+ export * from './UserManagementControllerClient';
@@ -0,0 +1,5 @@
1
+ export * from './HttpService';
2
+ export * from './ApiInitializationService';
3
+ export * from './ApiReadControllerClient';
4
+ export * from './ApiCrudControllerClient';
5
+ export * from './UserManagementControllerClient';
@@ -0,0 +1,75 @@
1
+ import { IHttpService } from '../../..';
2
+ import { ApiResponseDto, EmptyMetadataDto, UserDto, UserInfoDto, RegisterRequestDto } from '../../../../data';
3
+ export { UserDto, UserInfoDto };
4
+ /**
5
+ * AuthService class is responsible for managing user authentication operations.
6
+ * It supports login, logout, and checking the current user's details.
7
+ *
8
+ * @export
9
+ * @class AuthService
10
+ */
11
+ export declare class AuthService<TKey, TRegisterUser extends RegisterRequestDto = RegisterRequestDto, TUser extends UserDto<TKey> = UserDto<TKey>> {
12
+ protected readonly baseControllerPath: string;
13
+ /**
14
+ * Constructor
15
+ * @param baseControllerPath Base path to Auth API controller
16
+ * @param httpService HTTP service implementation to use for requests
17
+ */
18
+ constructor(baseControllerPath?: string, httpService?: IHttpService);
19
+ private readonly _httpService?;
20
+ /**
21
+ * Gets globally selected HTTP service
22
+ */
23
+ protected get httpService(): IHttpService;
24
+ /**
25
+ * Holds currently authenticated user's details
26
+ */
27
+ user: TUser | undefined;
28
+ /**
29
+ * Initializes the Authentication status by checking with the API if the current user is authenticated or not
30
+ *
31
+ * @async
32
+ * @return {Promise<void>} Resolves when initialization is complete.
33
+ */
34
+ initialize(): Promise<void>;
35
+ /**
36
+ * Checks if user is authenticated and retrieves the current user's details if they are
37
+ *
38
+ * @return {Promise<UserInfoDto<TKey, TUser>>} Currently logged in user's details
39
+ * @throws {Error} Error if fetch fails
40
+ */
41
+ whoAmI(): Promise<ApiResponseDto<UserInfoDto<TKey, TUser>, EmptyMetadataDto>>;
42
+ /**
43
+ * Authenticates a user using their username and password, and retrieves user's details
44
+ *
45
+ * @param {string} username Login credentials: username
46
+ * @param {string} password Login credentials: password
47
+ * @return {Promise<TUser>} Currently logged in user's details
48
+ * @throws {Error} Error if fetch fails
49
+ */
50
+ signIn(username: string, password: string): Promise<ApiResponseDto<TUser, EmptyMetadataDto>>;
51
+ /**
52
+ * Deauthenticates current user
53
+ *
54
+ * @return {Promise<void>}
55
+ * @throws {Error} Error if fetch fails
56
+ */
57
+ signOut(): Promise<ApiResponseDto<undefined, EmptyMetadataDto>>;
58
+ /**
59
+ * Registers a new user by sending user details to the API.
60
+ *
61
+ * @param {TRegisterUser} user User object containing registration data (e.g. username, password, and optionally firstName, lastName, etc.)
62
+ * @return {Promise<ApiResponseDto<TUser, EmptyMetadataDto>>} API response with registered user details or error info
63
+ * @throws {Error} Error if the request fails
64
+ */
65
+ register(user: TRegisterUser): Promise<ApiResponseDto<TUser, EmptyMetadataDto>>;
66
+ /**
67
+ * If any API response returns an "Unauthenticated" response, call this method
68
+ * to update local authentication state to unauthenticated
69
+ */
70
+ handleNoAuthApiResponse(): void;
71
+ /**
72
+ * True if a user is currently loaded (post whoAmI/signIn)
73
+ */
74
+ isAuthenticated(): boolean;
75
+ }