@intellegens/cornerstone-client 0.0.9999-alpha-9 → 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.
- 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/jest.config.js +29 -0
- package/package.json +1 -1
- package/src/adapters/CollectionViewAdapter/index.ts +390 -0
- package/src/adapters/index.ts +1 -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/ReadSelectedSearchDefinitionDto.ts +43 -0
- package/src/data/api/dto/read/ReadSelectedSearchPropertyDefinitionDto.ts +186 -0
- package/src/data/api/dto/read/index.ts +9 -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 +86 -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/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 +4 -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.ts +129 -0
- package/src/services/api/ApiInitializationService/index.ts +254 -0
- package/src/services/api/ApiReadControllerClient/index.ts +137 -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.ts +160 -0
- package/src/services/api/index.ts +5 -0
- package/src/services/auth/client/AuthService/index.ts +187 -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/tests/ApiClients.test.ts +284 -0
- package/tests/CollectionViewAdapter.test.ts +392 -0
- package/tests/HttpService.test.ts +303 -0
- package/tests/setup.ts +76 -0
- package/tsconfig.json +19 -0
- package/LICENSE.md +0 -7
- /package/{adapters → dist/adapters}/CollectionViewAdapter/index.d.ts +0 -0
- /package/{adapters → dist/adapters}/CollectionViewAdapter/index.js +0 -0
- /package/{adapters → dist/adapters}/index.d.ts +0 -0
- /package/{adapters → dist/adapters}/index.js +0 -0
- /package/{data → dist/data}/api/dto/PropertyPathDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/PropertyPathDto.js +0 -0
- /package/{data → dist/data}/api/dto/ReadOptionsDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/ReadOptionsDto.js +0 -0
- /package/{data → dist/data}/api/dto/ReadResultDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/ReadResultDto.js +0 -0
- /package/{data → dist/data}/api/dto/ReadResultMetadataDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/ReadResultMetadataDto.js +0 -0
- /package/{data → dist/data}/api/dto/crud/CrudMetadataDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/crud/CrudMetadataDto.js +0 -0
- /package/{data → dist/data}/api/dto/crud/index.d.ts +0 -0
- /package/{data → dist/data}/api/dto/crud/index.js +0 -0
- /package/{data → dist/data}/api/dto/index.d.ts +0 -0
- /package/{data → dist/data}/api/dto/index.js +0 -0
- /package/{data → dist/data}/api/dto/read/ReadMetadataDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/read/ReadMetadataDto.js +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedDefinitionDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedDefinitionDto.js +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedNestedCollectionCriteriaDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedNestedCollectionCriteriaDto.js +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedNestedCriteriaDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedNestedCriteriaDto.js +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedOrderingDefinitionDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedOrderingDefinitionDto.js +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedOrderingPropertyDefinitionDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedOrderingPropertyDefinitionDto.js +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedPaginationDefinitionDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedPaginationDefinitionDto.js +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedSearchDefinitionDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedSearchDefinitionDto.js +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedSearchPropertyDefinitionDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/read/ReadSelectedSearchPropertyDefinitionDto.js +0 -0
- /package/{data → dist/data}/api/dto/read/index.d.ts +0 -0
- /package/{data → dist/data}/api/dto/read/index.js +0 -0
- /package/{data → dist/data}/api/dto/response/ApiErrorDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/response/ApiErrorDto.js +0 -0
- /package/{data → dist/data}/api/dto/response/ApiErrorResponseDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/response/ApiErrorResponseDto.js +0 -0
- /package/{data → dist/data}/api/dto/response/ApiResponseDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/response/ApiResponseDto.js +0 -0
- /package/{data → dist/data}/api/dto/response/ApiSuccessResponseDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/response/ApiSuccessResponseDto.js +0 -0
- /package/{data → dist/data}/api/dto/response/EmptyMetadataDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/response/EmptyMetadataDto.js +0 -0
- /package/{data → dist/data}/api/dto/response/MetadataDto.d.ts +0 -0
- /package/{data → dist/data}/api/dto/response/MetadataDto.js +0 -0
- /package/{data → dist/data}/api/dto/response/index.d.ts +0 -0
- /package/{data → dist/data}/api/dto/response/index.js +0 -0
- /package/{data → dist/data}/api/enum/index.d.ts +0 -0
- /package/{data → dist/data}/api/enum/index.js +0 -0
- /package/{data → dist/data}/api/enum/read/ReadSelectedCollectionOperator.d.ts +0 -0
- /package/{data → dist/data}/api/enum/read/ReadSelectedCollectionOperator.js +0 -0
- /package/{data → dist/data}/api/enum/read/ReadSelectedComparisonOperator.d.ts +0 -0
- /package/{data → dist/data}/api/enum/read/ReadSelectedComparisonOperator.js +0 -0
- /package/{data → dist/data}/api/enum/read/ReadSelectedLogicalOperator.d.ts +0 -0
- /package/{data → dist/data}/api/enum/read/ReadSelectedLogicalOperator.js +0 -0
- /package/{data → dist/data}/api/enum/read/ReadSelectedOrderingDirection.d.ts +0 -0
- /package/{data → dist/data}/api/enum/read/ReadSelectedOrderingDirection.js +0 -0
- /package/{data → dist/data}/api/enum/read/ReadSelectedPropertyType.d.ts +0 -0
- /package/{data → dist/data}/api/enum/read/ReadSelectedPropertyType.js +0 -0
- /package/{data → dist/data}/api/enum/read/index.d.ts +0 -0
- /package/{data → dist/data}/api/enum/read/index.js +0 -0
- /package/{data → dist/data}/api/enum/response/ApiErrorCodes.d.ts +0 -0
- /package/{data → dist/data}/api/enum/response/ApiErrorCodes.js +0 -0
- /package/{data → dist/data}/api/enum/response/ErrorCode.d.ts +0 -0
- /package/{data → dist/data}/api/enum/response/ErrorCode.js +0 -0
- /package/{data → dist/data}/api/enum/response/index.d.ts +0 -0
- /package/{data → dist/data}/api/enum/response/index.js +0 -0
- /package/{data → dist/data}/api/index.d.ts +0 -0
- /package/{data → dist/data}/api/index.js +0 -0
- /package/{data → dist/data}/api/interface/IConcurrencySafe.d.ts +0 -0
- /package/{data → dist/data}/api/interface/IConcurrencySafe.js +0 -0
- /package/{data → dist/data}/api/interface/IIdentifiable.d.ts +0 -0
- /package/{data → dist/data}/api/interface/IIdentifiable.js +0 -0
- /package/{data → dist/data}/api/interface/IIdentifiableSecondary.d.ts +0 -0
- /package/{data → dist/data}/api/interface/IIdentifiableSecondary.js +0 -0
- /package/{data → dist/data}/api/interface/index.d.ts +0 -0
- /package/{data → dist/data}/api/interface/index.js +0 -0
- /package/{data → dist/data}/auth/dto/ClaimDto.d.ts +0 -0
- /package/{data → dist/data}/auth/dto/ClaimDto.js +0 -0
- /package/{data → dist/data}/auth/dto/RegisterRequestDto.d.ts +0 -0
- /package/{data → dist/data}/auth/dto/RegisterRequestDto.js +0 -0
- /package/{data → dist/data}/auth/dto/RoleDto.d.ts +0 -0
- /package/{data → dist/data}/auth/dto/RoleDto.js +0 -0
- /package/{data → dist/data}/auth/dto/SignInRequestDto.d.ts +0 -0
- /package/{data → dist/data}/auth/dto/SignInRequestDto.js +0 -0
- /package/{data → dist/data}/auth/dto/TokensDto.d.ts +0 -0
- /package/{data → dist/data}/auth/dto/TokensDto.js +0 -0
- /package/{data → dist/data}/auth/dto/UserDto.d.ts +0 -0
- /package/{data → dist/data}/auth/dto/UserDto.js +0 -0
- /package/{data → dist/data}/auth/dto/UserInfoDto.d.ts +0 -0
- /package/{data → dist/data}/auth/dto/UserInfoDto.js +0 -0
- /package/{data → dist/data}/auth/dto/index.d.ts +0 -0
- /package/{data → dist/data}/auth/dto/index.js +0 -0
- /package/{data → dist/data}/auth/index.d.ts +0 -0
- /package/{data → dist/data}/auth/index.js +0 -0
- /package/{data → dist/data}/auth/policy.d.ts +0 -0
- /package/{data → dist/data}/auth/policy.js +0 -0
- /package/{data → dist/data}/index.d.ts +0 -0
- /package/{data → dist/data}/index.js +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /package/{index.js → dist/index.js} +0 -0
- /package/{services → dist/services}/api/ApiCrudControllerClient/index.d.ts +0 -0
- /package/{services → dist/services}/api/ApiCrudControllerClient/index.js +0 -0
- /package/{services → dist/services}/api/ApiInitializationService/index.d.ts +0 -0
- /package/{services → dist/services}/api/ApiInitializationService/index.js +0 -0
- /package/{services → dist/services}/api/ApiReadControllerClient/index.d.ts +0 -0
- /package/{services → dist/services}/api/ApiReadControllerClient/index.js +0 -0
- /package/{services → dist/services}/api/HttpService/FetchHttpService.d.ts +0 -0
- /package/{services → dist/services}/api/HttpService/FetchHttpService.js +0 -0
- /package/{services → dist/services}/api/HttpService/HttpRequestConfig.d.ts +0 -0
- /package/{services → dist/services}/api/HttpService/HttpRequestConfig.js +0 -0
- /package/{services → dist/services}/api/HttpService/HttpResponse.d.ts +0 -0
- /package/{services → dist/services}/api/HttpService/HttpResponse.js +0 -0
- /package/{services → dist/services}/api/HttpService/IHttpService.d.ts +0 -0
- /package/{services → dist/services}/api/HttpService/IHttpService.js +0 -0
- /package/{services → dist/services}/api/HttpService/index.d.ts +0 -0
- /package/{services → dist/services}/api/HttpService/index.js +0 -0
- /package/{services → dist/services}/api/UserManagementControllerClient/index.d.ts +0 -0
- /package/{services → dist/services}/api/UserManagementControllerClient/index.js +0 -0
- /package/{services → dist/services}/api/index.d.ts +0 -0
- /package/{services → dist/services}/api/index.js +0 -0
- /package/{services → dist/services}/auth/client/AuthService/index.d.ts +0 -0
- /package/{services → dist/services}/auth/client/AuthService/index.js +0 -0
- /package/{services → dist/services}/auth/client/AuthorizationManagementControllerClient/index.d.ts +0 -0
- /package/{services → dist/services}/auth/client/AuthorizationManagementControllerClient/index.js +0 -0
- /package/{services → dist/services}/auth/client/index.d.ts +0 -0
- /package/{services → dist/services}/auth/client/index.js +0 -0
- /package/{services → dist/services}/auth/index.d.ts +0 -0
- /package/{services → dist/services}/auth/index.js +0 -0
- /package/{services → dist/services}/index.d.ts +0 -0
- /package/{services → dist/services}/index.js +0 -0
- /package/{utils → dist/utils}/authorization/index.d.ts +0 -0
- /package/{utils → dist/utils}/authorization/index.js +0 -0
- /package/{utils → dist/utils}/index.d.ts +0 -0
- /package/{utils → dist/utils}/index.js +0 -0
- /package/{utils → dist/utils}/result/index.d.ts +0 -0
- /package/{utils → dist/utils}/result/index.js +0 -0
- /package/{utils → dist/utils}/search/index.d.ts +0 -0
- /package/{utils → dist/utils}/search/index.js +0 -0
package/demo/index.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { createProxyMiddleware } from 'http-proxy-middleware';
|
|
3
|
+
|
|
4
|
+
const HTTP_PORT = 3000;
|
|
5
|
+
const API_PORT = 5235;
|
|
6
|
+
|
|
7
|
+
const app = express();
|
|
8
|
+
|
|
9
|
+
// config proxy for api calls
|
|
10
|
+
app.use(
|
|
11
|
+
createProxyMiddleware({
|
|
12
|
+
pathFilter: '/api',
|
|
13
|
+
target: `http://localhost:${API_PORT}`,
|
|
14
|
+
changeOrigin: true,
|
|
15
|
+
logger: console,
|
|
16
|
+
}),
|
|
17
|
+
);
|
|
18
|
+
app.use(
|
|
19
|
+
express.static('./demo/public_html', {
|
|
20
|
+
setHeaders: function (res) {
|
|
21
|
+
if (Math.random() > 0.5) res.set('CORNERSTONE-API-BASEURL', `/api`);
|
|
22
|
+
},
|
|
23
|
+
}),
|
|
24
|
+
);
|
|
25
|
+
app.listen(HTTP_PORT, () => {
|
|
26
|
+
console.log();
|
|
27
|
+
console.log(`Demo App listening on: http://localhost:${HTTP_PORT}`);
|
|
28
|
+
console.log(`... API requests proxied to: http://localhost:${API_PORT}/api`);
|
|
29
|
+
});
|
|
Binary file
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<!-- HEAD -->
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Cornerstone Test Client</title>
|
|
8
|
+
|
|
9
|
+
<!-- General styling -->
|
|
10
|
+
<style>
|
|
11
|
+
html {
|
|
12
|
+
font-family: monospace;
|
|
13
|
+
}
|
|
14
|
+
.comment {
|
|
15
|
+
color: gray;
|
|
16
|
+
}
|
|
17
|
+
</style>
|
|
18
|
+
</head>
|
|
19
|
+
|
|
20
|
+
<!-- BODY -->
|
|
21
|
+
<body>
|
|
22
|
+
<!-- API base URL detection demo template-->
|
|
23
|
+
<div>
|
|
24
|
+
<h2>API Detection Demo</h2>
|
|
25
|
+
<pre class="comment">
|
|
26
|
+
This demo will randomly initialize client configuration from one of:
|
|
27
|
+
- Response CORNERSTONE-API-BASEURL header
|
|
28
|
+
- A settings file: websettings.json
|
|
29
|
+
</pre>
|
|
30
|
+
|
|
31
|
+
<span>Detected API base URL as: <strong id="api-base-url"></strong> via method <strong id="api-base-url-method"></strong></span>
|
|
32
|
+
</pre>
|
|
33
|
+
</div>
|
|
34
|
+
<!-- API base URL detection demo JS -->
|
|
35
|
+
<script type="module">
|
|
36
|
+
import { apiService } from './index.js';
|
|
37
|
+
document.getElementById('api-base-url').innerText = await apiService._getApiBaseUrl();
|
|
38
|
+
document.getElementById('api-base-url-method').innerText = apiService._apiBaseUrlDetectionMethod;
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<!-- Auth demo template -->
|
|
42
|
+
<hr />
|
|
43
|
+
<div>
|
|
44
|
+
<h2>Auth Demo</h2>
|
|
45
|
+
<pre class="comment">
|
|
46
|
+
This demo will allow you to interact with the authentication API by:
|
|
47
|
+
- Checking the authentication status
|
|
48
|
+
- Authenticating with a username and password
|
|
49
|
+
- Deauthenticating
|
|
50
|
+
</pre>
|
|
51
|
+
<div>
|
|
52
|
+
<div>
|
|
53
|
+
Check your current authentication status:
|
|
54
|
+
<button id="whoAmI">Who am I?</button>
|
|
55
|
+
</div>
|
|
56
|
+
<div>
|
|
57
|
+
Authenticate using your credentials:
|
|
58
|
+
<input type="text" name="username" id="username" placeholder="Username" value="admin@test.com" />
|
|
59
|
+
<input type="password" name="password" id="password" placeholder="Password" value="Test1234!" />
|
|
60
|
+
<button id="signin">Sign in</button>
|
|
61
|
+
</div>
|
|
62
|
+
<div>
|
|
63
|
+
Deauthenticate:
|
|
64
|
+
<button id="signout">Sign out</button>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
<div id="authentication-info" style="margin-top: 10px"></div>
|
|
68
|
+
</div>
|
|
69
|
+
<!-- API base URL detection demo JS -->
|
|
70
|
+
<script type="module">
|
|
71
|
+
import { authService } from './index.js';
|
|
72
|
+
// whoAmI demo functionality
|
|
73
|
+
document.getElementById('whoAmI').addEventListener('click', async () => {
|
|
74
|
+
const authInfoEl = document.getElementById('authentication-info');
|
|
75
|
+
try {
|
|
76
|
+
const user = await authService.whoAmI();
|
|
77
|
+
authInfoEl.innerText = `You are authenticated as: ${JSON.stringify(user)}`;
|
|
78
|
+
} catch (err) {
|
|
79
|
+
authInfoEl.innerText = 'You are not authenticated!';
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
// login demo functionality
|
|
83
|
+
document.getElementById('signin').addEventListener('click', async () => {
|
|
84
|
+
const authInfoEl = document.getElementById('authentication-info');
|
|
85
|
+
const username = document.getElementById('username').value;
|
|
86
|
+
const password = document.getElementById('password').value;
|
|
87
|
+
try {
|
|
88
|
+
const user = await authService.signin(username, password);
|
|
89
|
+
authInfoEl.innerText = `Signed in in successfully as: ${JSON.stringify(user)}`;
|
|
90
|
+
} catch (err) {
|
|
91
|
+
authInfoEl.innerText = `Failed signing in: ${err.message}`;
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
// logout demo functionality
|
|
95
|
+
document.getElementById('signout').addEventListener('click', async () => {
|
|
96
|
+
const authInfoEl = document.getElementById('authentication-info');
|
|
97
|
+
try {
|
|
98
|
+
await authService.signout();
|
|
99
|
+
authInfoEl.innerText = `Successfully signed out`;
|
|
100
|
+
} catch (err) {
|
|
101
|
+
authInfoEl.innerText = `Failed signing out: ${err.message}`;
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
</script>
|
|
105
|
+
</body>
|
|
106
|
+
</html>
|
package/jest.config.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
preset: 'ts-jest/presets/default-esm',
|
|
3
|
+
extensionsToTreatAsEsm: ['.ts'],
|
|
4
|
+
testEnvironment: 'jsdom',
|
|
5
|
+
roots: ['<rootDir>/src', '<rootDir>/tests'],
|
|
6
|
+
testMatch: ['**/__tests__/**/*.+(ts|tsx|js)', '**/*.(test|spec).+(ts|tsx|js)'],
|
|
7
|
+
transform: {
|
|
8
|
+
'^.+\\.(ts|tsx)$': [
|
|
9
|
+
'ts-jest',
|
|
10
|
+
{
|
|
11
|
+
useESM: true,
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
collectCoverageFrom: ['src/**/*.{ts,tsx}', '!src/**/*.d.ts', '!src/**/index.ts'],
|
|
16
|
+
moduleNameMapper: {
|
|
17
|
+
'^@/(.*)$': '<rootDir>/src/$1',
|
|
18
|
+
'^@adapters/(.*)$': '<rootDir>/src/adapters/$1',
|
|
19
|
+
'^@adapters$': '<rootDir>/src/adapters',
|
|
20
|
+
'^@data/(.*)$': '<rootDir>/src/data/$1',
|
|
21
|
+
'^@data$': '<rootDir>/src/data',
|
|
22
|
+
'^@services/(.*)$': '<rootDir>/src/services/$1',
|
|
23
|
+
'^@services$': '<rootDir>/src/services',
|
|
24
|
+
'^@utils/(.*)$': '<rootDir>/src/utils/$1',
|
|
25
|
+
'^@utils$': '<rootDir>/src/utils',
|
|
26
|
+
},
|
|
27
|
+
setupFilesAfterEnv: ['<rootDir>/tests/setup.ts'],
|
|
28
|
+
testTimeout: 10000,
|
|
29
|
+
};
|
package/package.json
CHANGED
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
import { IIdentifiable, PropertyPathDto, ReadSelectedDefinitionDto, ReadSelectedOrderingDirection, ReadSelectedSearchDefinitionDto } from '@data';
|
|
2
|
+
import { toPascalCase } from '@utils';
|
|
3
|
+
import { ApiReadControllerClient } from '@services';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Used with CollectionViewAdapter, a simplified configuration object for handling reading/writing from/to ReadSelectedDefinitionDto.
|
|
7
|
+
*
|
|
8
|
+
* @template TDto The type of the collection being sorted/filtered/paginated.
|
|
9
|
+
*
|
|
10
|
+
* @property {object} pagination - Pagination configuration
|
|
11
|
+
* @property {boolean} pagination.useTotalItemCount - Used for last page related logic of the paginator.
|
|
12
|
+
* Set to true if the total count for the collection is available; false assumes the last page is not known
|
|
13
|
+
* and adapts the pagination display accordingly.
|
|
14
|
+
* @property {number} [pagination.pageSize] - Number of items/rows to be fetched for the current page.
|
|
15
|
+
* @property {number} [pagination.pageNumber] - Current page index (skips fetching `(n-1) * pageSize` items/rows).
|
|
16
|
+
*
|
|
17
|
+
* @property {object} ordering - Ordering configuration
|
|
18
|
+
* @property {string[]} [ordering.orderByPath] - Array of column/property names that are sortable.
|
|
19
|
+
* @property {ReadSelectedOrderingDirection} [ordering.orderDirection] - Enum for ascending/descending sort order.
|
|
20
|
+
*
|
|
21
|
+
* @property {object} search - Search configuration
|
|
22
|
+
* @property {(keyof TDto)[]} [search.textSearchableProperties] - Array of column/property names that are searchable where the value type is string.
|
|
23
|
+
* @property {(keyof TDto)[]} [search.numericSearchableProperties] - Array of column/property names that are searchable where the value type is number.
|
|
24
|
+
* @property {ReadSelectedSearchDefinitionDto<TDto>} [search.searchDefinition] - The search definition by which the collection will be filtered.
|
|
25
|
+
*/
|
|
26
|
+
export type CollectionViewAdapterOptions<TDto> = {
|
|
27
|
+
pagination: {
|
|
28
|
+
useTotalItemCount: boolean;
|
|
29
|
+
pageSize?: number;
|
|
30
|
+
pageNumber?: number;
|
|
31
|
+
};
|
|
32
|
+
ordering: {
|
|
33
|
+
maxActiveOrderingColumns: number;
|
|
34
|
+
orderByPaths: {
|
|
35
|
+
orderByPath: PropertyPathDto;
|
|
36
|
+
orderDirection: ReadSelectedOrderingDirection;
|
|
37
|
+
}[];
|
|
38
|
+
};
|
|
39
|
+
search: {
|
|
40
|
+
textSearchableProperties?: (keyof TDto)[];
|
|
41
|
+
numericSearchableProperties?: (keyof TDto)[];
|
|
42
|
+
searchDefinition?: ReadSelectedSearchDefinitionDto<TDto>;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* TS class for handling ordering, filtering and paginating collections
|
|
48
|
+
*
|
|
49
|
+
* @param controllerName - specify the target endpoint controller name.
|
|
50
|
+
* @param dataChangedCallback - Function invoked whenever the data changes.
|
|
51
|
+
* Receives a loading state flag and the updated data collection.
|
|
52
|
+
* @param options - Optional settings of type CollectionViewAdapter to customize the behavior of the adapter.
|
|
53
|
+
*/
|
|
54
|
+
export class CollectionViewAdapter<TKey, TDto extends IIdentifiable<TKey>> {
|
|
55
|
+
private _readClient: ApiReadControllerClient<TKey, TDto>;
|
|
56
|
+
|
|
57
|
+
private _isLoading = false;
|
|
58
|
+
private _pageData: TDto[] = [];
|
|
59
|
+
|
|
60
|
+
private _defaultOptions: CollectionViewAdapterOptions<TDto> = {
|
|
61
|
+
pagination: {
|
|
62
|
+
useTotalItemCount: false,
|
|
63
|
+
pageSize: 10,
|
|
64
|
+
pageNumber: 1,
|
|
65
|
+
},
|
|
66
|
+
ordering: {
|
|
67
|
+
maxActiveOrderingColumns: 1,
|
|
68
|
+
orderByPaths: [],
|
|
69
|
+
},
|
|
70
|
+
search: {
|
|
71
|
+
textSearchableProperties: [],
|
|
72
|
+
numericSearchableProperties: [],
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
private _initialOptions: CollectionViewAdapterOptions<TDto>;
|
|
77
|
+
private _currentOptions: CollectionViewAdapterOptions<TDto>;
|
|
78
|
+
|
|
79
|
+
constructor(
|
|
80
|
+
controllerName: string,
|
|
81
|
+
dataChangedCallback: (isLoading: boolean, data: TDto[] | undefined, error: string | undefined) => void,
|
|
82
|
+
options?: CollectionViewAdapterOptions<TDto>,
|
|
83
|
+
) {
|
|
84
|
+
this._readClient = new ApiReadControllerClient<TKey, TDto>(controllerName);
|
|
85
|
+
|
|
86
|
+
this._initialOptions = {
|
|
87
|
+
pagination: {
|
|
88
|
+
...this._defaultOptions.pagination,
|
|
89
|
+
...options?.pagination,
|
|
90
|
+
},
|
|
91
|
+
ordering: {
|
|
92
|
+
...this._defaultOptions.ordering,
|
|
93
|
+
...options?.ordering,
|
|
94
|
+
},
|
|
95
|
+
search: {
|
|
96
|
+
...this._defaultOptions.search,
|
|
97
|
+
...options?.search,
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
this._currentOptions = {
|
|
102
|
+
pagination: { ...this._initialOptions.pagination },
|
|
103
|
+
ordering: { ...this._initialOptions.ordering },
|
|
104
|
+
search: { ...this._initialOptions.search },
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
this._dataChangedCallback = dataChangedCallback;
|
|
108
|
+
this._fetchCurrentPageData();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
//#region SEARCH
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Allows for adding any filtering criteria. Label is required to distinguish custom search categories (e.g. searchTerm, dateRange, anyCustom ...)
|
|
115
|
+
*/
|
|
116
|
+
public setSearchDefinition(searchDefinition: ReadSelectedSearchDefinitionDto<TDto>) {
|
|
117
|
+
this._currentOptions.search.searchDefinition = searchDefinition;
|
|
118
|
+
this._currentOptions.pagination.pageNumber = 1; // Reset to first page
|
|
119
|
+
return this._fetchCurrentPageData();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
//#endregion
|
|
123
|
+
|
|
124
|
+
//#region ORDERING
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Compares two PropertyPathDto arrays for equality
|
|
128
|
+
*/
|
|
129
|
+
private _arePropertyPathsEqual(path1: PropertyPathDto, path2: PropertyPathDto): boolean {
|
|
130
|
+
if (path1.length !== path2.length) return false;
|
|
131
|
+
return path1.every((segment, index) => segment === path2[index]);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Public method for ordering the collection by property path / column name.
|
|
136
|
+
*
|
|
137
|
+
* @param propertyPath - must match camel-cased property/column name being sorted
|
|
138
|
+
* @param orderDirection - use `ReadSelectedOrderingDirection` enum choices
|
|
139
|
+
*/
|
|
140
|
+
public setOrdering(propertyPath: PropertyPathDto, orderDirection: ReadSelectedOrderingDirection) {
|
|
141
|
+
// Remove any existing ordering for this property path
|
|
142
|
+
this._currentOptions.ordering.orderByPaths = this._currentOptions.ordering.orderByPaths.filter(
|
|
143
|
+
p => !this._arePropertyPathsEqual(p.orderByPath, propertyPath),
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
// Add the new ordering at the beginning
|
|
147
|
+
this._currentOptions.ordering.orderByPaths.unshift({
|
|
148
|
+
orderByPath: propertyPath,
|
|
149
|
+
orderDirection: orderDirection,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Limit to maxActiveOrderingColumns
|
|
153
|
+
if (this._currentOptions.ordering.orderByPaths.length > this._currentOptions.ordering.maxActiveOrderingColumns) {
|
|
154
|
+
this._currentOptions.ordering.orderByPaths = this._currentOptions.ordering.orderByPaths.slice(0, this._currentOptions.ordering.maxActiveOrderingColumns);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
this._currentOptions.pagination.pageNumber = 1; // Reset to first page
|
|
158
|
+
return this._fetchCurrentPageData();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Returns the property name of the current columns/properties on which ordering is applied, along with the `ReadSelectedOrderingDirection` direction
|
|
163
|
+
*/
|
|
164
|
+
public getCurrentOrdering() {
|
|
165
|
+
return this._currentOptions.ordering.orderByPaths;
|
|
166
|
+
}
|
|
167
|
+
//#endregion
|
|
168
|
+
|
|
169
|
+
//#region PAGINATION
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Returns the current page's page number
|
|
173
|
+
*/
|
|
174
|
+
public get currentPage() {
|
|
175
|
+
return this._currentOptions.pagination.pageNumber;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Sets the current page to `pageNumber` and triggers data re-fetch
|
|
180
|
+
*
|
|
181
|
+
* @param pageNumber
|
|
182
|
+
*/
|
|
183
|
+
public jumpToPage(pageNumber: number) {
|
|
184
|
+
this._currentOptions.pagination.pageNumber = pageNumber;
|
|
185
|
+
return this._fetchCurrentPageData();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Returns the currently set page size value
|
|
190
|
+
*/
|
|
191
|
+
public get pageSize() {
|
|
192
|
+
return this._currentOptions.pagination.pageSize;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Page size dictates the number of items or rows being fetched in a single API call
|
|
197
|
+
*
|
|
198
|
+
* @param pageSize
|
|
199
|
+
*/
|
|
200
|
+
public setPageSize(pageSize: number) {
|
|
201
|
+
this._currentOptions.pagination.pageSize = pageSize;
|
|
202
|
+
this._currentOptions.pagination.pageNumber = 1; // Reset to first page
|
|
203
|
+
return this._fetchCurrentPageData();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
private _totalItemCount = -1;
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Returns the total count value of the collection.
|
|
210
|
+
*
|
|
211
|
+
* If `CollectionViewAdapterOptions` has set `pagination.useTotalItemCount` to `true`, the API will return this value along with the collection and it will be set automatically.
|
|
212
|
+
* Else this adapter will attempt to dynamically calculate this value via `_calculateTotal()`.
|
|
213
|
+
*/
|
|
214
|
+
public get totalItemCount() {
|
|
215
|
+
return this._totalItemCount;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
//#endregion
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Callback function invoked whenever data changes.
|
|
222
|
+
* Receives a loading state flag and the updated data collection.
|
|
223
|
+
*/
|
|
224
|
+
private readonly _dataChangedCallback!: (isLoading: boolean, data: TDto[] | undefined, errorMessage: string | undefined) => void;
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Timeout reference used to debounce calls to `_fetchCurrentPageData`.
|
|
228
|
+
*/
|
|
229
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
230
|
+
private _fetchCurrentPageDataTimeout?: any;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Queue of pending promises waiting for `_fetchCurrentPageData` to resolve or reject.
|
|
234
|
+
*/
|
|
235
|
+
private _fetchCurrentPageDataPromises: { resolve: (value: TDto[] | PromiseLike<TDto[]>) => void; reject: (reason?: unknown) => void }[] = [];
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Tracks the current in-flight request controller to allow cancellation when a new fetch starts.
|
|
239
|
+
*/
|
|
240
|
+
private _currentAbortController?: AbortController;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Fetches the current page of data with debouncing support.
|
|
244
|
+
* Consolidates multiple concurrent calls into a single execution,
|
|
245
|
+
* resolving all queued promises with the same result.
|
|
246
|
+
*
|
|
247
|
+
* @returns A promise resolving to the fetched page of data.
|
|
248
|
+
*/
|
|
249
|
+
private async _fetchCurrentPageData(): Promise<TDto[]> {
|
|
250
|
+
return new Promise((resolve, reject) => {
|
|
251
|
+
this._fetchCurrentPageDataPromises.push({ resolve, reject });
|
|
252
|
+
if (this._fetchCurrentPageDataTimeout !== undefined) {
|
|
253
|
+
clearTimeout(this._fetchCurrentPageDataTimeout);
|
|
254
|
+
}
|
|
255
|
+
this._fetchCurrentPageDataTimeout = setTimeout(async () => {
|
|
256
|
+
try {
|
|
257
|
+
const result = await this._fetchCurrentPageDataDebounced();
|
|
258
|
+
const promises = this._fetchCurrentPageDataPromises.splice(0, this._fetchCurrentPageDataPromises.length);
|
|
259
|
+
for (const p of promises) p.resolve(result);
|
|
260
|
+
} catch (err) {
|
|
261
|
+
const promises = this._fetchCurrentPageDataPromises.splice(0, this._fetchCurrentPageDataPromises.length);
|
|
262
|
+
for (const p of promises) p.reject(err);
|
|
263
|
+
}
|
|
264
|
+
}, 50);
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Executes the actual data fetch operation after debounce delay.
|
|
270
|
+
* Updates the loading state, triggers data change callbacks,
|
|
271
|
+
* and handles total item count calculation if pagination is enabled.
|
|
272
|
+
*
|
|
273
|
+
* @returns A promise resolving to the fetched page of data.
|
|
274
|
+
*/
|
|
275
|
+
private async _fetchCurrentPageDataDebounced(): Promise<TDto[]> {
|
|
276
|
+
this._isLoading = true;
|
|
277
|
+
this._dataChangedCallback(this._isLoading, undefined, undefined);
|
|
278
|
+
let abortController: AbortController | undefined;
|
|
279
|
+
let caughtError: unknown;
|
|
280
|
+
|
|
281
|
+
try {
|
|
282
|
+
// Cancel any in-flight request before starting a new one
|
|
283
|
+
if (this._currentAbortController) {
|
|
284
|
+
try {
|
|
285
|
+
this._currentAbortController.abort();
|
|
286
|
+
} catch {
|
|
287
|
+
// Ignore abort errors as they are expected when debouncing
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
abortController = new AbortController();
|
|
291
|
+
this._currentAbortController = abortController;
|
|
292
|
+
|
|
293
|
+
const definition = this._parseOptionsToDefinition();
|
|
294
|
+
const response = await this._readClient.readSelected(definition, abortController?.signal);
|
|
295
|
+
|
|
296
|
+
if (!response.ok) {
|
|
297
|
+
throw response.error;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
this._pageData = response.result;
|
|
301
|
+
|
|
302
|
+
if (this._currentOptions.pagination.useTotalItemCount && response.metadata.totalCount !== undefined) {
|
|
303
|
+
this._totalItemCount = response.metadata.totalCount;
|
|
304
|
+
} else {
|
|
305
|
+
const pageSize = this._currentOptions.pagination.pageSize!;
|
|
306
|
+
const currentPageNumber = this._currentOptions.pagination.pageNumber!;
|
|
307
|
+
const itemsOnCurrentPageCount = this._pageData.length;
|
|
308
|
+
this._totalItemCount = this._calculateTotal(pageSize, currentPageNumber, itemsOnCurrentPageCount, this._totalItemCount);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return this._pageData;
|
|
312
|
+
} catch (error: unknown) {
|
|
313
|
+
caughtError = error;
|
|
314
|
+
|
|
315
|
+
// Do not log abort-related errors as they are expected when debouncing
|
|
316
|
+
if (error instanceof DOMException && error.name === 'AbortError') {
|
|
317
|
+
return Promise.reject(error);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
console.error('Error fetching data:', error);
|
|
321
|
+
return Promise.reject(error);
|
|
322
|
+
} finally {
|
|
323
|
+
this._isLoading = false;
|
|
324
|
+
|
|
325
|
+
let errorName: string | undefined;
|
|
326
|
+
if (caughtError && !(caughtError instanceof DOMException && caughtError.name === 'AbortError')) {
|
|
327
|
+
errorName = caughtError instanceof Error ? caughtError.name : undefined;
|
|
328
|
+
}
|
|
329
|
+
this._dataChangedCallback(this._isLoading, this._pageData, errorName);
|
|
330
|
+
|
|
331
|
+
// Clear the abort controller only if it belongs to this request (avoid racing with a newer one)
|
|
332
|
+
|
|
333
|
+
if (abortController && this._currentAbortController === abortController) {
|
|
334
|
+
this._currentAbortController = undefined;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Takes current `CollectionViewAdapterOptions` and parses to `ReadSelectedDefinitionDto` which the cornerstone API expects.
|
|
341
|
+
*
|
|
342
|
+
* @returns - `ReadSelectedDefinitionDto` object
|
|
343
|
+
*/
|
|
344
|
+
private _parseOptionsToDefinition(): ReadSelectedDefinitionDto<TDto> {
|
|
345
|
+
const definition: ReadSelectedDefinitionDto<TDto> = {
|
|
346
|
+
paginationDefinition: {
|
|
347
|
+
skip: (this._currentOptions.pagination.pageNumber! - 1) * this._currentOptions.pagination.pageSize!,
|
|
348
|
+
limit: this._currentOptions.pagination.pageSize!,
|
|
349
|
+
},
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
// Apply ordering
|
|
353
|
+
const orderByPaths = this._currentOptions.ordering.orderByPaths;
|
|
354
|
+
|
|
355
|
+
if (orderByPaths && orderByPaths.length > 0) {
|
|
356
|
+
definition.orderingDefinition = {
|
|
357
|
+
order: orderByPaths.map(orderPath => ({
|
|
358
|
+
propertyPath: orderPath.orderByPath.map(x => toPascalCase(x)) as PropertyPathDto,
|
|
359
|
+
direction: orderPath.orderDirection,
|
|
360
|
+
})),
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Apply search
|
|
365
|
+
definition.searchDefinition = this._currentOptions.search.searchDefinition;
|
|
366
|
+
|
|
367
|
+
return definition;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Calculates the total item count given pagination inputs.
|
|
372
|
+
*
|
|
373
|
+
* For example, with 10 items per page, on page 2 with 3 items, total = 13.
|
|
374
|
+
* If the total cannot be inferred (e.g., a full page is returned), the previous total is returned unchanged.
|
|
375
|
+
*
|
|
376
|
+
* @param pageSize - Number of items per page
|
|
377
|
+
* @param currentPageNumber - Current page number (1-based)
|
|
378
|
+
* @param itemsOnCurrentPageCount - Number of items in the fetched page
|
|
379
|
+
* @param previousTotal - Previous known total to preserve when indeterminate
|
|
380
|
+
* @returns The computed total item count
|
|
381
|
+
*/
|
|
382
|
+
private _calculateTotal(pageSize: number, currentPageNumber: number, itemsOnCurrentPageCount: number, previousTotal: number): number {
|
|
383
|
+
if (itemsOnCurrentPageCount < pageSize && itemsOnCurrentPageCount !== 0) {
|
|
384
|
+
return pageSize * (currentPageNumber - 1) + itemsOnCurrentPageCount;
|
|
385
|
+
} else if (itemsOnCurrentPageCount === 0 && pageSize === 0) {
|
|
386
|
+
return 0;
|
|
387
|
+
}
|
|
388
|
+
return previousTotal;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CollectionViewAdapter';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ReadResultMetadataDto } from './ReadResultMetadataDto';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents a read result containing a collection of results and metadata.
|
|
5
|
+
*
|
|
6
|
+
* @template T The type of result in the collection.
|
|
7
|
+
* @property {T[]} items - The collection of results returned.
|
|
8
|
+
* @property {ReadResultMetadata} metadata - Metadata about the paginated result.
|
|
9
|
+
*/
|
|
10
|
+
export type ReadResultDto<T> = {
|
|
11
|
+
results: T[];
|
|
12
|
+
metadata: ReadResultMetadataDto;
|
|
13
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CrudMetadataDto';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ReadSelectedPaginationDefinitionDto, ReadSelectedOrderingDefinitionDto, ReadSelectedSearchDefinitionDto } from '@data';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Defines the selection criteria for a controller to fetch multiple records
|
|
5
|
+
*/
|
|
6
|
+
export type ReadSelectedDefinitionDto<T> = {
|
|
7
|
+
/**
|
|
8
|
+
* Pagination definition
|
|
9
|
+
*/
|
|
10
|
+
paginationDefinition?: ReadSelectedPaginationDefinitionDto;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Ordering definition
|
|
14
|
+
*/
|
|
15
|
+
orderingDefinition?: ReadSelectedOrderingDefinitionDto;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Search definition (supports both simple search and nested logical groups)
|
|
19
|
+
*/
|
|
20
|
+
searchDefinition?: ReadSelectedSearchDefinitionDto<T>;
|
|
21
|
+
};
|