@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.
- package/README.md +256 -0
- package/demo/index.ts +29 -0
- package/demo/public_html/favicon.ico +0 -0
- package/demo/public_html/index.html +106 -0
- package/demo/public_html/websettings.json +3 -0
- package/dist/adapters/CollectionViewAdapter/index.d.ts +198 -0
- package/dist/adapters/CollectionViewAdapter/index.integration.test.d.ts +1 -0
- package/dist/adapters/CollectionViewAdapter/index.integration.test.js +163 -0
- package/dist/adapters/CollectionViewAdapter/index.js +381 -0
- package/dist/adapters/SearchAdapter/index.d.ts +55 -0
- package/dist/adapters/SearchAdapter/index.js +233 -0
- package/dist/adapters/index.d.ts +2 -0
- package/dist/adapters/index.js +2 -0
- package/dist/data/api/dto/PropertyPathDto.d.ts +4 -0
- package/dist/data/api/dto/PropertyPathDto.js +1 -0
- package/dist/data/api/dto/ReadOptionsDto.d.ts +8 -0
- package/dist/data/api/dto/ReadOptionsDto.js +1 -0
- package/dist/data/api/dto/ReadResultDto.d.ts +12 -0
- package/dist/data/api/dto/ReadResultDto.js +1 -0
- package/dist/data/api/dto/ReadResultMetadataDto.d.ts +8 -0
- package/dist/data/api/dto/ReadResultMetadataDto.js +1 -0
- package/dist/data/api/dto/crud/CrudMetadataDto.d.ts +4 -0
- package/dist/data/api/dto/crud/CrudMetadataDto.js +1 -0
- package/dist/data/api/dto/crud/index.d.ts +1 -0
- package/dist/data/api/dto/crud/index.js +1 -0
- package/dist/data/api/dto/index.d.ts +4 -0
- package/dist/data/api/dto/index.js +4 -0
- package/dist/data/api/dto/read/ReadMetadataDto.d.ts +8 -0
- package/dist/data/api/dto/read/ReadMetadataDto.js +1 -0
- package/dist/data/api/dto/read/ReadSelectedDefinitionDto.d.ts +18 -0
- package/dist/data/api/dto/read/ReadSelectedDefinitionDto.js +1 -0
- package/dist/data/api/dto/read/ReadSelectedNestedCollectionCriteriaDto.d.ts +22 -0
- package/dist/data/api/dto/read/ReadSelectedNestedCollectionCriteriaDto.js +1 -0
- package/dist/data/api/dto/read/ReadSelectedNestedCriteriaDto.d.ts +18 -0
- package/dist/data/api/dto/read/ReadSelectedNestedCriteriaDto.js +1 -0
- package/dist/data/api/dto/read/ReadSelectedOrderingDefinitionDto.d.ts +7 -0
- package/dist/data/api/dto/read/ReadSelectedOrderingDefinitionDto.js +1 -0
- package/dist/data/api/dto/read/ReadSelectedOrderingPropertyDefinitionDto.d.ts +14 -0
- package/dist/data/api/dto/read/ReadSelectedOrderingPropertyDefinitionDto.js +1 -0
- package/dist/data/api/dto/read/ReadSelectedPaginationDefinitionDto.d.ts +13 -0
- package/dist/data/api/dto/read/ReadSelectedPaginationDefinitionDto.js +1 -0
- package/dist/data/api/dto/read/ReadSelectedSearchDefinitionBuilder.d.ts +167 -0
- package/dist/data/api/dto/read/ReadSelectedSearchDefinitionBuilder.js +267 -0
- package/dist/data/api/dto/read/ReadSelectedSearchDefinitionDto.d.ts +33 -0
- package/dist/data/api/dto/read/ReadSelectedSearchDefinitionDto.js +1 -0
- package/dist/data/api/dto/read/ReadSelectedSearchPropertyDefinitionDto.d.ts +114 -0
- package/dist/data/api/dto/read/ReadSelectedSearchPropertyDefinitionDto.js +1 -0
- package/dist/data/api/dto/read/index.d.ts +10 -0
- package/dist/data/api/dto/read/index.js +10 -0
- package/dist/data/api/dto/response/ApiErrorDto.d.ts +17 -0
- package/dist/data/api/dto/response/ApiErrorDto.js +1 -0
- package/dist/data/api/dto/response/ApiErrorResponseDto.d.ts +11 -0
- package/dist/data/api/dto/response/ApiErrorResponseDto.js +1 -0
- package/dist/data/api/dto/response/ApiResponseDto.d.ts +3 -0
- package/dist/data/api/dto/response/ApiResponseDto.js +1 -0
- package/dist/data/api/dto/response/ApiSuccessResponseDto.d.ts +13 -0
- package/dist/data/api/dto/response/ApiSuccessResponseDto.js +1 -0
- package/dist/data/api/dto/response/EmptyMetadataDto.d.ts +4 -0
- package/dist/data/api/dto/response/EmptyMetadataDto.js +1 -0
- package/dist/data/api/dto/response/MetadataDto.d.ts +25 -0
- package/dist/data/api/dto/response/MetadataDto.js +1 -0
- package/dist/data/api/dto/response/index.d.ts +5 -0
- package/dist/data/api/dto/response/index.js +5 -0
- package/dist/data/api/enum/index.d.ts +2 -0
- package/dist/data/api/enum/index.js +2 -0
- package/dist/data/api/enum/read/ReadSelectedCollectionOperator.d.ts +16 -0
- package/dist/data/api/enum/read/ReadSelectedCollectionOperator.js +17 -0
- package/dist/data/api/enum/read/ReadSelectedComparisonOperator.d.ts +69 -0
- package/dist/data/api/enum/read/ReadSelectedComparisonOperator.js +76 -0
- package/dist/data/api/enum/read/ReadSelectedLogicalOperator.d.ts +15 -0
- package/dist/data/api/enum/read/ReadSelectedLogicalOperator.js +16 -0
- package/dist/data/api/enum/read/ReadSelectedOrderingDirection.d.ts +13 -0
- package/dist/data/api/enum/read/ReadSelectedOrderingDirection.js +14 -0
- package/dist/data/api/enum/read/ReadSelectedPropertyType.d.ts +66 -0
- package/dist/data/api/enum/read/ReadSelectedPropertyType.js +75 -0
- package/dist/data/api/enum/read/index.d.ts +5 -0
- package/dist/data/api/enum/read/index.js +5 -0
- package/dist/data/api/enum/response/ApiErrorCodes.d.ts +7 -0
- package/dist/data/api/enum/response/ApiErrorCodes.js +8 -0
- package/dist/data/api/enum/response/ErrorCode.d.ts +13 -0
- package/dist/data/api/enum/response/ErrorCode.js +14 -0
- package/dist/data/api/enum/response/index.d.ts +1 -0
- package/dist/data/api/enum/response/index.js +1 -0
- package/dist/data/api/index.d.ts +3 -0
- package/dist/data/api/index.js +3 -0
- package/dist/data/api/interface/ICommonIdentifiable.d.ts +7 -0
- package/dist/data/api/interface/ICommonIdentifiable.js +1 -0
- package/dist/data/api/interface/IConcurrencySafe.d.ts +9 -0
- package/dist/data/api/interface/IConcurrencySafe.js +2 -0
- package/dist/data/api/interface/IIdentifiable.d.ts +11 -0
- package/dist/data/api/interface/IIdentifiable.js +1 -0
- package/dist/data/api/interface/IIdentifiableSecondary.d.ts +9 -0
- package/dist/data/api/interface/IIdentifiableSecondary.js +1 -0
- package/dist/data/api/interface/index.d.ts +3 -0
- package/dist/data/api/interface/index.js +3 -0
- package/dist/data/auth/dto/ClaimDto.d.ts +4 -0
- package/dist/data/auth/dto/ClaimDto.js +1 -0
- package/dist/data/auth/dto/RegisterRequestDto.d.ts +4 -0
- package/dist/data/auth/dto/RegisterRequestDto.js +1 -0
- package/dist/data/auth/dto/RoleDto.d.ts +5 -0
- package/dist/data/auth/dto/RoleDto.js +1 -0
- package/dist/data/auth/dto/SignInRequestDto.d.ts +4 -0
- package/dist/data/auth/dto/SignInRequestDto.js +1 -0
- package/dist/data/auth/dto/TokensDto.d.ts +4 -0
- package/dist/data/auth/dto/TokensDto.js +1 -0
- package/dist/data/auth/dto/UserDto.d.ts +17 -0
- package/dist/data/auth/dto/UserDto.js +1 -0
- package/dist/data/auth/dto/UserInfoDto.d.ts +14 -0
- package/dist/data/auth/dto/UserInfoDto.js +1 -0
- package/dist/data/auth/dto/index.d.ts +5 -0
- package/dist/data/auth/dto/index.js +5 -0
- package/dist/data/auth/index.d.ts +2 -0
- package/dist/data/auth/index.js +2 -0
- package/dist/data/auth/policy.d.ts +52 -0
- package/dist/data/auth/policy.js +44 -0
- package/dist/data/index.d.ts +2 -0
- package/dist/data/index.js +2 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/services/api/ApiCrudControllerClient/index.d.ts +41 -0
- package/dist/services/api/ApiCrudControllerClient/index.integration.test.d.ts +1 -0
- package/dist/services/api/ApiCrudControllerClient/index.integration.test.js +34 -0
- package/dist/services/api/ApiCrudControllerClient/index.js +116 -0
- package/dist/services/api/ApiInitializationService/index.d.ts +106 -0
- package/dist/services/api/ApiInitializationService/index.js +208 -0
- package/dist/services/api/ApiReadControllerClient/index.d.ts +40 -0
- package/dist/services/api/ApiReadControllerClient/index.integration.test.d.ts +1 -0
- package/dist/services/api/ApiReadControllerClient/index.integration.test.js +59 -0
- package/dist/services/api/ApiReadControllerClient/index.js +111 -0
- package/dist/services/api/HttpService/FetchHttpService.d.ts +7 -0
- package/dist/services/api/HttpService/FetchHttpService.integration.test.d.ts +1 -0
- package/dist/services/api/HttpService/FetchHttpService.integration.test.js +52 -0
- package/dist/services/api/HttpService/FetchHttpService.js +29 -0
- package/dist/services/api/HttpService/HttpRequestConfig.d.ts +10 -0
- package/dist/services/api/HttpService/HttpRequestConfig.js +1 -0
- package/dist/services/api/HttpService/HttpResponse.d.ts +11 -0
- package/dist/services/api/HttpService/HttpResponse.js +3 -0
- package/dist/services/api/HttpService/IHttpService.d.ts +13 -0
- package/dist/services/api/HttpService/IHttpService.js +3 -0
- package/dist/services/api/HttpService/index.d.ts +9 -0
- package/dist/services/api/HttpService/index.js +10 -0
- package/dist/services/api/UserManagementControllerClient/index.d.ts +41 -0
- package/dist/services/api/UserManagementControllerClient/index.integration.test.d.ts +1 -0
- package/dist/services/api/UserManagementControllerClient/index.integration.test.js +60 -0
- package/dist/services/api/UserManagementControllerClient/index.js +117 -0
- package/dist/services/api/index.d.ts +5 -0
- package/dist/services/api/index.js +5 -0
- package/dist/services/auth/client/AuthService/index.d.ts +75 -0
- package/dist/services/auth/client/AuthService/index.js +200 -0
- package/dist/services/auth/client/AuthorizationManagementControllerClient/index.d.ts +48 -0
- package/dist/services/auth/client/AuthorizationManagementControllerClient/index.integration.test.d.ts +1 -0
- package/dist/services/auth/client/AuthorizationManagementControllerClient/index.integration.test.js +89 -0
- package/dist/services/auth/client/AuthorizationManagementControllerClient/index.js +148 -0
- package/dist/services/auth/client/index.d.ts +2 -0
- package/dist/services/auth/client/index.js +2 -0
- package/dist/services/auth/index.d.ts +1 -0
- package/dist/services/auth/index.js +1 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.js +2 -0
- package/dist/utils/authorization/index.d.ts +17 -0
- package/dist/utils/authorization/index.js +45 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/result/index.d.ts +21 -0
- package/dist/utils/result/index.js +16 -0
- package/dist/utils/search/index.d.ts +34 -0
- package/dist/utils/search/index.js +106 -0
- package/package.json +45 -0
- package/src/adapters/CollectionViewAdapter/index.integration.test.ts +197 -0
- package/src/adapters/CollectionViewAdapter/index.ts +477 -0
- package/src/adapters/SearchAdapter/index.ts +302 -0
- package/src/adapters/index.ts +2 -0
- package/src/data/api/dto/PropertyPathDto.ts +4 -0
- package/src/data/api/dto/ReadOptionsDto.ts +8 -0
- package/src/data/api/dto/ReadResultDto.ts +13 -0
- package/src/data/api/dto/ReadResultMetadataDto.ts +8 -0
- package/src/data/api/dto/crud/CrudMetadataDto.ts +4 -0
- package/src/data/api/dto/crud/index.ts +1 -0
- package/src/data/api/dto/index.ts +4 -0
- package/src/data/api/dto/read/ReadMetadataDto.ts +8 -0
- package/src/data/api/dto/read/ReadSelectedDefinitionDto.ts +21 -0
- package/src/data/api/dto/read/ReadSelectedNestedCollectionCriteriaDto.ts +25 -0
- package/src/data/api/dto/read/ReadSelectedNestedCriteriaDto.ts +20 -0
- package/src/data/api/dto/read/ReadSelectedOrderingDefinitionDto.ts +8 -0
- package/src/data/api/dto/read/ReadSelectedOrderingPropertyDefinitionDto.ts +16 -0
- package/src/data/api/dto/read/ReadSelectedPaginationDefinitionDto.ts +13 -0
- package/src/data/api/dto/read/ReadSelectedSearchDefinitionBuilder.ts +348 -0
- package/src/data/api/dto/read/ReadSelectedSearchDefinitionDto.ts +43 -0
- package/src/data/api/dto/read/ReadSelectedSearchPropertyDefinitionDto.ts +186 -0
- package/src/data/api/dto/read/index.ts +10 -0
- package/src/data/api/dto/response/ApiErrorDto.ts +21 -0
- package/src/data/api/dto/response/ApiErrorResponseDto.ts +13 -0
- package/src/data/api/dto/response/ApiResponseDto.ts +7 -0
- package/src/data/api/dto/response/ApiSuccessResponseDto.ts +13 -0
- package/src/data/api/dto/response/MetadataDto.ts +24 -0
- package/src/data/api/dto/response/index.ts +5 -0
- package/src/data/api/enum/index.ts +2 -0
- package/src/data/api/enum/read/ReadSelectedCollectionOperator.ts +17 -0
- package/src/data/api/enum/read/ReadSelectedComparisonOperator.ts +96 -0
- package/src/data/api/enum/read/ReadSelectedLogicalOperator.ts +16 -0
- package/src/data/api/enum/read/ReadSelectedOrderingDirection.ts +13 -0
- package/src/data/api/enum/read/ReadSelectedPropertyType.ts +96 -0
- package/src/data/api/enum/read/index.ts +5 -0
- package/src/data/api/enum/response/ErrorCode.ts +13 -0
- package/src/data/api/enum/response/index.ts +1 -0
- package/src/data/api/index.ts +3 -0
- package/src/data/api/interface/ICommonIdentifiable.ts +9 -0
- package/src/data/api/interface/IConcurrencySafe.ts +9 -0
- package/src/data/api/interface/IIdentifiable.ts +12 -0
- package/src/data/api/interface/IIdentifiableSecondary.ts +9 -0
- package/src/data/api/interface/index.ts +3 -0
- package/src/data/auth/dto/ClaimDto.ts +4 -0
- package/src/data/auth/dto/RegisterRequestDto.ts +4 -0
- package/src/data/auth/dto/RoleDto.ts +6 -0
- package/src/data/auth/dto/SignInRequestDto.ts +4 -0
- package/src/data/auth/dto/TokensDto.ts +4 -0
- package/src/data/auth/dto/UserDto.ts +18 -0
- package/src/data/auth/dto/UserInfoDto.ts +15 -0
- package/src/data/auth/dto/index.ts +5 -0
- package/src/data/auth/index.ts +2 -0
- package/src/data/auth/policy.ts +63 -0
- package/src/data/index.ts +2 -0
- package/src/index.ts +4 -0
- package/src/services/api/ApiCrudControllerClient/index.integration.test.ts +46 -0
- package/src/services/api/ApiCrudControllerClient/index.ts +135 -0
- package/src/services/api/ApiInitializationService/index.ts +254 -0
- package/src/services/api/ApiReadControllerClient/index.integration.test.ts +71 -0
- package/src/services/api/ApiReadControllerClient/index.ts +137 -0
- package/src/services/api/HttpService/FetchHttpService.integration.test.ts +65 -0
- package/src/services/api/HttpService/FetchHttpService.ts +34 -0
- package/src/services/api/HttpService/HttpRequestConfig.ts +10 -0
- package/src/services/api/HttpService/HttpResponse.ts +14 -0
- package/src/services/api/HttpService/IHttpService.ts +17 -0
- package/src/services/api/HttpService/README.md +106 -0
- package/src/services/api/HttpService/index.ts +12 -0
- package/src/services/api/UserManagementControllerClient/index.integration.test.ts +69 -0
- package/src/services/api/UserManagementControllerClient/index.ts +134 -0
- package/src/services/api/index.ts +5 -0
- package/src/services/auth/client/AuthService/index.ts +233 -0
- package/src/services/auth/client/AuthorizationManagementControllerClient/index.integration.test.ts +110 -0
- package/src/services/auth/client/AuthorizationManagementControllerClient/index.ts +165 -0
- package/src/services/auth/client/index.ts +2 -0
- package/src/services/auth/index.ts +1 -0
- package/src/services/index.ts +2 -0
- package/src/utils/authorization/index.ts +47 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/result/index.ts +25 -0
- package/src/utils/search/index.ts +150 -0
- package/tsconfig.json +19 -0
- package/vitest-setup.ts +43 -0
- 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 @@
|
|
|
1
|
+
export {};
|
|
@@ -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,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,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 @@
|
|
|
1
|
+
export {};
|
|
@@ -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,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
|
+
}
|