@intellegens/cornerstone-client 0.0.45 → 0.0.9999-alpha-2

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 (70) hide show
  1. package/LICENSE.md +0 -0
  2. package/README.md +133 -12
  3. package/adapters/CollectionViewAdapter/index.d.ts +154 -0
  4. package/adapters/CollectionViewAdapter/index.js +281 -0
  5. package/adapters/index.d.ts +1 -0
  6. package/adapters/index.js +1 -0
  7. package/data/api/dto/PropertyPathDto.d.ts +4 -0
  8. package/data/api/dto/ReadOptionsDto.d.ts +8 -0
  9. package/data/api/dto/ReadResultDto.d.ts +12 -0
  10. package/data/api/dto/ReadResultMetadataDto.d.ts +8 -0
  11. package/data/api/dto/crud/{CrudMetadata.d.ts → CrudMetadataDto.d.ts} +1 -1
  12. package/data/api/dto/crud/index.d.ts +1 -1
  13. package/data/api/dto/crud/index.js +1 -1
  14. package/data/api/dto/index.d.ts +1 -0
  15. package/data/api/dto/index.js +1 -0
  16. package/data/api/dto/read/{ReadMetadata.d.ts → ReadMetadataDto.d.ts} +1 -1
  17. package/data/api/dto/read/ReadSelectedOrderingPropertyDefinitionDto.d.ts +2 -2
  18. package/data/api/dto/read/ReadSelectedSearchPropertyDefinitionDto.d.ts +2 -2
  19. package/data/api/dto/read/index.d.ts +1 -1
  20. package/data/api/dto/read/index.js +1 -1
  21. package/data/api/dto/response/{ApiError.d.ts → ApiErrorDto.d.ts} +1 -1
  22. package/data/api/dto/response/ApiErrorDto.js +1 -0
  23. package/data/api/dto/response/{ApiResponse.d.ts → ApiResponseDto.d.ts} +3 -3
  24. package/data/api/dto/response/ApiResponseDto.js +1 -0
  25. package/data/api/dto/response/{ApiSuccessResponse.d.ts → ApiSuccessResponseDto.d.ts} +1 -1
  26. package/data/api/dto/response/ApiSuccessResponseDto.js +1 -0
  27. package/data/api/dto/response/EmptyMetadataDto.d.ts +4 -0
  28. package/data/api/dto/response/EmptyMetadataDto.js +1 -0
  29. package/data/api/dto/response/index.d.ts +4 -4
  30. package/data/api/dto/response/index.js +4 -4
  31. package/data/api/interface/IConcurrencySafe.d.ts +9 -0
  32. package/data/api/interface/IConcurrencySafe.js +2 -0
  33. package/data/api/interface/IIdentifiable.d.ts +4 -3
  34. package/data/api/interface/IIdentifiableSecondary.d.ts +3 -3
  35. package/data/api/interface/index.d.ts +1 -0
  36. package/data/api/interface/index.js +1 -0
  37. package/index.d.ts +3 -0
  38. package/index.js +3 -0
  39. package/package.json +15 -10
  40. package/services/api/ApiCrudControllerClient/index.d.ts +9 -5
  41. package/services/api/ApiCrudControllerClient/index.js +15 -9
  42. package/services/api/ApiInitializationService/index.d.ts +21 -3
  43. package/services/api/ApiInitializationService/index.js +36 -7
  44. package/services/api/ApiReadControllerClient/index.d.ts +12 -13
  45. package/services/api/ApiReadControllerClient/index.js +17 -18
  46. package/services/api/HttpService/FetchHttpService.d.ts +1 -1
  47. package/services/api/HttpService/FetchHttpService.js +2 -1
  48. package/services/api/HttpService/HttpRequestConfig.d.ts +1 -0
  49. package/services/api/HttpService/IHttpService.d.ts +1 -1
  50. package/services/api/HttpService/index.d.ts +0 -2
  51. package/services/api/HttpService/index.js +0 -2
  52. package/services/api/UserManagementControllerClient/index.d.ts +9 -5
  53. package/services/api/UserManagementControllerClient/index.js +20 -12
  54. package/services/auth/client/AuthService/index.d.ts +5 -5
  55. package/services/auth/client/AuthService/index.js +9 -9
  56. package/services/auth/client/AuthorizationManagementControllerClient/index.d.ts +5 -5
  57. package/services/auth/client/AuthorizationManagementControllerClient/index.js +8 -8
  58. package/utils/index.d.ts +37 -0
  59. package/utils/index.js +106 -0
  60. package/data/api/dto/response/EmptyMetadata.d.ts +0 -4
  61. package/services/api/HttpService/AngularHttpService.d.ts +0 -9
  62. package/services/api/HttpService/AngularHttpService.js +0 -86
  63. package/services/api/HttpService/AxiosHttpService.d.ts +0 -10
  64. package/services/api/HttpService/AxiosHttpService.js +0 -53
  65. /package/data/api/dto/{crud/CrudMetadata.js → PropertyPathDto.js} +0 -0
  66. /package/data/api/dto/{read/ReadMetadata.js → ReadOptionsDto.js} +0 -0
  67. /package/data/api/dto/{response/ApiError.js → ReadResultDto.js} +0 -0
  68. /package/data/api/dto/{response/ApiResponse.js → ReadResultMetadataDto.js} +0 -0
  69. /package/data/api/dto/{response/ApiSuccessResponse.js → crud/CrudMetadataDto.js} +0 -0
  70. /package/data/api/dto/{response/EmptyMetadata.js → read/ReadMetadataDto.js} +0 -0
@@ -1,4 +1,4 @@
1
1
  /**
2
2
  * Metadata associated with a crud result.
3
3
  */
4
- export type CrudMetadata = object;
4
+ export type CrudMetadataDto = object;
@@ -1 +1 @@
1
- export * from './CrudMetadata';
1
+ export * from './CrudMetadataDto';
@@ -1 +1 @@
1
- export * from './CrudMetadata';
1
+ export * from './CrudMetadataDto';
@@ -1,3 +1,4 @@
1
1
  export * from './response';
2
2
  export * from './read';
3
3
  export * from './crud';
4
+ export * from './PropertyPathDto';
@@ -1,3 +1,4 @@
1
1
  export * from './response';
2
2
  export * from './read';
3
3
  export * from './crud';
4
+ export * from './PropertyPathDto';
@@ -3,6 +3,6 @@
3
3
  *
4
4
  * @property {number} [totalCount] - The total number of items available.
5
5
  */
6
- export type ReadMetadata = {
6
+ export type ReadMetadataDto = {
7
7
  totalCount?: number;
8
8
  };
@@ -1,4 +1,4 @@
1
- import { ReadSelectedOrderingDirection } from '../../..';
1
+ import { PropertyPathDto, ReadSelectedOrderingDirection } from '../../..';
2
2
  /**
3
3
  * Defines the ordering property for a controller.
4
4
  */
@@ -6,7 +6,7 @@ export type ReadSelectedOrderingPropertyDefinitionDto = {
6
6
  /**
7
7
  * Gets or sets the property path.
8
8
  */
9
- propertyPath: string;
9
+ propertyPath: PropertyPathDto[];
10
10
  /**
11
11
  * Gets or sets the sort direction.
12
12
  */
@@ -1,4 +1,4 @@
1
- import { ReadSelectedComparisonOperator, ReadSelectedPropertyType } from '../../..';
1
+ import { PropertyPathDto, ReadSelectedComparisonOperator, ReadSelectedPropertyType } from '../../..';
2
2
  /**
3
3
  * Defines a property used for searching in a controller.
4
4
  */
@@ -10,7 +10,7 @@ type Partial_ReadSelectedSearchPropertyDefinition_IndependentProperties = {
10
10
  /**
11
11
  * The path to the property being searched.
12
12
  */
13
- propertyPath: string;
13
+ propertyPath: PropertyPathDto;
14
14
  /**
15
15
  * The comparison operator to use for the search.
16
16
  */
@@ -1,4 +1,4 @@
1
- export * from './ReadMetadata';
1
+ export * from './ReadMetadataDto';
2
2
  export * from './ReadSelectedSearchPropertyDefinitionDto';
3
3
  export * from './ReadSelectedOrderingDefinitionDto';
4
4
  export * from './ReadSelectedOrderingPropertyDefinitionDto';
@@ -1,4 +1,4 @@
1
- export * from './ReadMetadata';
1
+ export * from './ReadMetadataDto';
2
2
  export * from './ReadSelectedSearchPropertyDefinitionDto';
3
3
  export * from './ReadSelectedOrderingDefinitionDto';
4
4
  export * from './ReadSelectedOrderingPropertyDefinitionDto';
@@ -2,7 +2,7 @@ import { ApiErrorCodes } from '../../..';
2
2
  /**
3
3
  * Default, empty metadata.
4
4
  */
5
- export type ApiError = {
5
+ export type ApiErrorDto = {
6
6
  code: ApiErrorCodes;
7
7
  message: string;
8
8
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
- import { ApiError } from '../../..';
1
+ import { ApiErrorDto } from '../../..';
2
2
  /**
3
3
  * Represents an API response containing a result and metadata, or an error.
4
4
  *
@@ -7,9 +7,9 @@ import { ApiError } from '../../..';
7
7
  * @property {T} result - The result returned
8
8
  * @property {TMetadata} metadata - Metadata about the result
9
9
  */
10
- export type ApiResponse<T, TMetadata> = {
10
+ export type ApiResponseDto<T, TMetadata> = {
11
11
  success: boolean;
12
12
  result: T;
13
13
  metadata: TMetadata;
14
- error: ApiError;
14
+ error: ApiErrorDto;
15
15
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -6,7 +6,7 @@
6
6
  * @property {T} result - The result returned
7
7
  * @property {TMetadata} metadata - Metadata about the result
8
8
  */
9
- export type ApiSuccessResponse<T, TMetadata> = {
9
+ export type ApiSuccessResponseDto<T, TMetadata> = {
10
10
  result: T;
11
11
  metadata: TMetadata;
12
12
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Default, empty metadata.
3
+ */
4
+ export type EmptyMetadataDto = object;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
- export * from './ApiResponse';
2
- export * from './ApiSuccessResponse';
3
- export * from './ApiError';
4
- export * from './EmptyMetadata';
1
+ export * from './ApiResponseDto';
2
+ export * from './ApiSuccessResponseDto';
3
+ export * from './ApiErrorDto';
4
+ export * from './EmptyMetadataDto';
@@ -1,4 +1,4 @@
1
- export * from './ApiResponse';
2
- export * from './ApiSuccessResponse';
3
- export * from './ApiError';
4
- export * from './EmptyMetadata';
1
+ export * from './ApiResponseDto';
2
+ export * from './ApiSuccessResponseDto';
3
+ export * from './ApiErrorDto';
4
+ export * from './EmptyMetadataDto';
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Interface for entities that have row versioning
3
+ */
4
+ export interface IConcurrencySafe {
5
+ /**
6
+ * Row version
7
+ */
8
+ rowVersion: string;
9
+ }
@@ -0,0 +1,2 @@
1
+ ;
2
+ export {};
@@ -1,10 +1,11 @@
1
+ import { IConcurrencySafe } from './IConcurrencySafe';
1
2
  /**
2
- * Type for entities that have a Id property.
3
+ * Interface for entities that have a Id property.
3
4
  * Will be used as a primary key in the database.
4
5
  */
5
- export type IIdentifiable<TKey> = {
6
+ export interface IIdentifiable<TKey> extends IConcurrencySafe {
6
7
  /**
7
8
  * Gets or sets the Id of the entity.
8
9
  */
9
10
  id: TKey;
10
- };
11
+ }
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Type for entities that have a secondary Id property.
2
+ * Interface for entities that have a secondary Id property.
3
3
  */
4
- export type IIdentifiableSecondary<TKey> = {
4
+ export interface IIdentifiableSecondary<TKey> {
5
5
  /**
6
6
  * Gets or sets the secondary Id of the entity.
7
7
  */
8
8
  idSecondary: TKey;
9
- };
9
+ }
@@ -1,2 +1,3 @@
1
1
  export * from './IIdentifiable';
2
2
  export * from './IIdentifiableSecondary';
3
+ export * from './IConcurrencySafe';
@@ -1,2 +1,3 @@
1
1
  export * from './IIdentifiable';
2
2
  export * from './IIdentifiableSecondary';
3
+ export * from './IConcurrencySafe';
package/index.d.ts CHANGED
@@ -1 +1,4 @@
1
1
  export * from './services';
2
+ export * from './data';
3
+ export * from './adapters';
4
+ export * from './utils';
package/index.js CHANGED
@@ -1 +1,4 @@
1
1
  export * from './services';
2
+ export * from './data';
3
+ export * from './adapters';
4
+ export * from './utils';
package/package.json CHANGED
@@ -1,19 +1,25 @@
1
1
  {
2
2
  "name": "@intellegens/cornerstone-client",
3
- "version": "0.0.45",
4
- "main": "index.js",
3
+ "version": "0.0.9999-alpha-2",
4
+ "private": false,
5
+ "publishable": true,
6
+ "main": "./index.js",
7
+ "types": "./index.d.ts",
5
8
  "type": "module",
9
+ "author": "Intellegens",
10
+ "license": "MIT",
11
+ "description": "",
12
+ "keywords": [
13
+ "intellegens",
14
+ "cornerstone"
15
+ ],
6
16
  "scripts": {
7
- "clean": "node -e \"require('fs-extra').emptyDir('./dist');\"",
17
+ "clean": "npx --yes rimraf '{dist}'",
8
18
  "test": "jest",
9
- "test:watch": "jest --watch",
10
- "test:coverage": "jest --coverage",
19
+ "coverage": "jest --coverage",
11
20
  "build": "npm run clean && tsc && tsc-alias",
12
- "demo": "npm run build && npx vite build && npx tsx ./demo"
21
+ "start": "npm run build && npx vite build && npx tsx ./demo"
13
22
  },
14
- "author": "",
15
- "license": "MIT",
16
- "description": "",
17
23
  "devDependencies": {
18
24
  "@eslint/js": "^9.21.0",
19
25
  "@types/express": "^5.0.0",
@@ -22,7 +28,6 @@
22
28
  "eslint": "^9.21.0",
23
29
  "eslint-config-prettier": "^10.0.1",
24
30
  "express": "^4.21.2",
25
- "fs-extra": "^11.3.0",
26
31
  "globals": "^16.0.0",
27
32
  "jest": "^29.7.0",
28
33
  "jest-environment-jsdom": "^29.7.0",
@@ -1,6 +1,7 @@
1
- import { ApiReadControllerClient } from '../ApiReadControllerClient';
2
- import { IIdentifiable, ApiSuccessResponse, EmptyMetadata } from '../../../data';
1
+ import { ApiSuccessResponseDto, EmptyMetadataDto } from '../../../data/api/dto';
2
+ import { IIdentifiable } from '../../../data/api/interface';
3
3
  import { IHttpService } from '../HttpService';
4
+ import { ApiReadControllerClient } from '../ApiReadControllerClient';
4
5
  /**
5
6
  * Generic API client for consuming any Cornerstone CrudController
6
7
  *
@@ -19,19 +20,22 @@ export declare class ApiCrudControllerClient<TKey, TDto extends IIdentifiable<TK
19
20
  /**
20
21
  * Creates a new entity.
21
22
  * @param dto - Insert request DTO
23
+ * @param {AbortSignal} [signal] - Optional cancellation signal
22
24
  * @returns The created entity DTO
23
25
  */
24
- create(dto: TDto): Promise<ApiSuccessResponse<TDto, EmptyMetadata>>;
26
+ createAsync(dto: TDto, signal?: AbortSignal): Promise<ApiSuccessResponseDto<TDto, EmptyMetadataDto>>;
25
27
  /**
26
28
  * Updates an existing entity.
27
29
  * @param id - The ID of the entity to update
28
30
  * @param dto - Update request DTO
31
+ * @param {AbortSignal} [signal] - Optional cancellation signal
29
32
  * @returns The updated entity DTO
30
33
  */
31
- update(id: TKey, dto: TDto): Promise<ApiSuccessResponse<TDto, EmptyMetadata>>;
34
+ updateAsync(id: TKey, dto: TDto, signal?: AbortSignal): Promise<ApiSuccessResponseDto<TDto, EmptyMetadataDto>>;
32
35
  /**
33
36
  * Deletes an entity by ID.
34
37
  * @param id - The ID of the entity to delete
38
+ * @param {AbortSignal} [signal] - Optional cancellation signal
35
39
  */
36
- delete(id: TKey): Promise<void>;
40
+ deleteAsync(id: TKey, signal?: AbortSignal): Promise<void>;
37
41
  }
@@ -20,16 +20,18 @@ export class ApiCrudControllerClient extends ApiReadControllerClient {
20
20
  /**
21
21
  * Creates a new entity.
22
22
  * @param dto - Insert request DTO
23
+ * @param {AbortSignal} [signal] - Optional cancellation signal
23
24
  * @returns The created entity DTO
24
25
  */
25
- async create(dto) {
26
+ async createAsync(dto, signal) {
26
27
  try {
27
- const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/Create`);
28
- const res = await this.httpService.request(url, {
28
+ const url = await apiInitializationService.getApiUrlAsync(this.baseControllerPath, `/Create`);
29
+ const res = await this.httpService.requestAsync(url, {
29
30
  method: 'POST',
30
31
  headers: { 'Content-Type': 'application/json' },
31
32
  body: JSON.stringify(dto),
32
33
  credentials: 'include',
34
+ signal,
33
35
  });
34
36
  if (!res.ok)
35
37
  throw undefined;
@@ -47,16 +49,18 @@ export class ApiCrudControllerClient extends ApiReadControllerClient {
47
49
  * Updates an existing entity.
48
50
  * @param id - The ID of the entity to update
49
51
  * @param dto - Update request DTO
52
+ * @param {AbortSignal} [signal] - Optional cancellation signal
50
53
  * @returns The updated entity DTO
51
54
  */
52
- async update(id, dto) {
55
+ async updateAsync(id, dto, signal) {
53
56
  try {
54
- const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/Update?id=${encodeURIComponent(String(id))}`);
55
- const res = await this.httpService.request(url, {
57
+ const url = await apiInitializationService.getApiUrlAsync(this.baseControllerPath, `/Update?id=${encodeURIComponent(String(id))}`);
58
+ const res = await this.httpService.requestAsync(url, {
56
59
  method: 'PUT',
57
60
  headers: { 'Content-Type': 'application/json' },
58
61
  body: JSON.stringify(dto),
59
62
  credentials: 'include',
63
+ signal,
60
64
  });
61
65
  if (!res.ok)
62
66
  throw undefined;
@@ -73,13 +77,15 @@ export class ApiCrudControllerClient extends ApiReadControllerClient {
73
77
  /**
74
78
  * Deletes an entity by ID.
75
79
  * @param id - The ID of the entity to delete
80
+ * @param {AbortSignal} [signal] - Optional cancellation signal
76
81
  */
77
- async delete(id) {
82
+ async deleteAsync(id, signal) {
78
83
  try {
79
- const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/Delete?id=${encodeURIComponent(String(id))}`);
80
- const response = await this.httpService.request(url, {
84
+ const url = await apiInitializationService.getApiUrlAsync(this.baseControllerPath, `/Delete?id=${encodeURIComponent(String(id))}`);
85
+ const response = await this.httpService.requestAsync(url, {
81
86
  method: 'DELETE',
82
87
  credentials: 'include',
88
+ signal,
83
89
  });
84
90
  if (!response.ok)
85
91
  throw undefined;
@@ -1,3 +1,10 @@
1
+ /**
2
+ * Generic shared settings interface - can represent any user-configured settings structure
3
+ * The actual properties depend on what users configure in their appsettings.json or environment variables
4
+ */
5
+ type ISharedSettings = {
6
+ [key: string]: any;
7
+ };
1
8
  import { IHttpService } from '../HttpService';
2
9
  /**
3
10
  * Central API configuration service, fetches and exposes Cornerstone API configuration
@@ -11,13 +18,16 @@ export declare class ApiInitializationService {
11
18
  *
12
19
  * This method calls all methods that need to be called during the API configuration phase:
13
20
  * - Starts detection of API base URL.
21
+ * - Fetches shared settings from the server.
14
22
  *
15
23
  * @async
16
24
  * @param httpService - HTTP service implementation to use for requests
25
+ * @param {AbortSignal} [signal] - Optional cancellation signal
17
26
  * @return {Promise<void>} Resolves when initialization is complete.
18
27
  */
19
- initialize({ httpService }?: {
28
+ initializeAsync({ httpService, signal }?: {
20
29
  httpService?: IHttpService;
30
+ signal?: AbortSignal;
21
31
  }): Promise<void>;
22
32
  private _httpService;
23
33
  /**
@@ -56,10 +66,11 @@ export declare class ApiInitializationService {
56
66
  * IMPORTANT: This method is not meant to be used in normal cases - when ever possible use the .getApiUrl(relativeEndpointPath: string) method instead.
57
67
  *
58
68
  * @async
69
+ * @param {AbortSignal} [signal] - Optional cancellation signal
59
70
  * @return {Promise<string | undefined>} Returns detected API base URL
60
71
  * @throws {Error} Throws error if either of the detection methods fails
61
72
  */
62
- _getApiBaseUrl(): Promise<string | undefined>;
73
+ _getApiBaseUrlAsync(signal?: AbortSignal): Promise<string | undefined>;
63
74
  /**
64
75
  * Composes a full API URL for a provided endpoint path.
65
76
  *
@@ -68,7 +79,7 @@ export declare class ApiInitializationService {
68
79
  * @return {Promise<string | undefined>} Returns the API endpoint's URL
69
80
  * @throws {Error} Throws error if API base URL detection fails
70
81
  */
71
- getApiUrl(...relativeEndpointPathSections: string[]): Promise<string>;
82
+ getApiUrlAsync(...relativeEndpointPathSections: string[]): Promise<string>;
72
83
  /**
73
84
  * Removes starting '/' character
74
85
  * @param str String to remove the starting '/' character from
@@ -81,8 +92,15 @@ export declare class ApiInitializationService {
81
92
  * @returns String with ending '/' character removed
82
93
  */
83
94
  private removeEndsWithSlashChar;
95
+ appConfig?: ISharedSettings | undefined;
96
+ /**
97
+ * Fetches initialization info (shared settings) from the server
98
+ * @returns Promise that resolves to shared settings or undefined if the request fails
99
+ */
100
+ private _getAppConfigAsync;
84
101
  }
85
102
  /**
86
103
  * Singleton instance of ApiInitializationService
87
104
  */
88
105
  export declare const apiInitializationService: ApiInitializationService;
106
+ export {};
@@ -11,17 +11,21 @@ export class ApiInitializationService {
11
11
  *
12
12
  * This method calls all methods that need to be called during the API configuration phase:
13
13
  * - Starts detection of API base URL.
14
+ * - Fetches shared settings from the server.
14
15
  *
15
16
  * @async
16
17
  * @param httpService - HTTP service implementation to use for requests
18
+ * @param {AbortSignal} [signal] - Optional cancellation signal
17
19
  * @return {Promise<void>} Resolves when initialization is complete.
18
20
  */
19
- async initialize({ httpService } = {}) {
21
+ async initializeAsync({ httpService, signal } = {}) {
20
22
  // Store configuration
21
23
  if (httpService !== undefined)
22
24
  this._httpService = httpService;
23
25
  // (Pre)detect API base URL
24
- await this._getApiBaseUrl();
26
+ await this._getApiBaseUrlAsync(signal);
27
+ // Initialize app config
28
+ await this._getAppConfigAsync();
25
29
  }
26
30
  // #region HTTP service
27
31
  _httpService = defaultHttpService;
@@ -65,10 +69,11 @@ export class ApiInitializationService {
65
69
  * IMPORTANT: This method is not meant to be used in normal cases - when ever possible use the .getApiUrl(relativeEndpointPath: string) method instead.
66
70
  *
67
71
  * @async
72
+ * @param {AbortSignal} [signal] - Optional cancellation signal
68
73
  * @return {Promise<string | undefined>} Returns detected API base URL
69
74
  * @throws {Error} Throws error if either of the detection methods fails
70
75
  */
71
- async _getApiBaseUrl() {
76
+ async _getApiBaseUrlAsync(signal) {
72
77
  // Check if API already detected; don't reattempt detection
73
78
  if (this._apiBaseUrlDetected)
74
79
  return this._apiBaseUrl;
@@ -84,7 +89,7 @@ export class ApiInitializationService {
84
89
  this._apiBaseError = undefined;
85
90
  // Check CORNERSTONE-API-BASEURL header for API base URL
86
91
  try {
87
- const currentUrlResponse = await this._httpService.request(window.location.href, { method: 'GET' });
92
+ const currentUrlResponse = await this._httpService.requestAsync(window.location.href, { method: 'GET', signal });
88
93
  const apiHeader = currentUrlResponse.headers['CORNERSTONE-API-BASEURL'] || currentUrlResponse.headers['cornerstone-api-baseurl'] || null;
89
94
  if (apiHeader) {
90
95
  this._apiBaseUrlDetected = true;
@@ -100,7 +105,7 @@ export class ApiInitializationService {
100
105
  }
101
106
  // Check ./websettings.json header for API base URL
102
107
  try {
103
- const webSettingsResponse = await this._httpService.request('./websettings.json', { method: 'GET' });
108
+ const webSettingsResponse = await this._httpService.requestAsync('./websettings.json', { method: 'GET', signal });
104
109
  if (webSettingsResponse.status === 404)
105
110
  return (this._apiBaseUrl = undefined);
106
111
  const webSettings = await webSettingsResponse.json();
@@ -141,8 +146,8 @@ export class ApiInitializationService {
141
146
  * @return {Promise<string | undefined>} Returns the API endpoint's URL
142
147
  * @throws {Error} Throws error if API base URL detection fails
143
148
  */
144
- async getApiUrl(...relativeEndpointPathSections) {
145
- const apiBaseUrl = await this._getApiBaseUrl();
149
+ async getApiUrlAsync(...relativeEndpointPathSections) {
150
+ const apiBaseUrl = await this._getApiBaseUrlAsync();
146
151
  const domain = !apiBaseUrl ? '/' : `${this.removeEndsWithSlashChar(apiBaseUrl)}/`;
147
152
  const path = relativeEndpointPathSections.map(section => this.removeStartsWithSlashChar(this.removeEndsWithSlashChar(section))).join('/');
148
153
  return `${domain}${path}`;
@@ -163,6 +168,30 @@ export class ApiInitializationService {
163
168
  removeEndsWithSlashChar(str) {
164
169
  return !str.endsWith('/') ? str : str.substring(0, str.length - 1);
165
170
  }
171
+ // #endregion
172
+ // #region config App
173
+ appConfig;
174
+ /**
175
+ * Fetches initialization info (shared settings) from the server
176
+ * @returns Promise that resolves to shared settings or undefined if the request fails
177
+ */
178
+ async _getAppConfigAsync() {
179
+ try {
180
+ const response = await fetch(`${this._apiBaseUrl}/api/system/init`, { credentials: 'include' });
181
+ if (!response.ok)
182
+ throw new Error('Failed to get app config');
183
+ const apiResponse = await response.json();
184
+ // Check if the API response indicates success
185
+ if (!apiResponse.success || !apiResponse.result) {
186
+ throw new Error(apiResponse.error?.message || 'Server returned unsuccessful response');
187
+ }
188
+ // Return the settings from the nested structure
189
+ this.appConfig = apiResponse.result.settings;
190
+ }
191
+ catch (error) {
192
+ this.appConfig = undefined;
193
+ }
194
+ }
166
195
  }
167
196
  /**
168
197
  * Singleton instance of ApiInitializationService
@@ -1,12 +1,8 @@
1
- import { IIdentifiable, ApiSuccessResponse, ReadSelectedDefinitionDto, ReadMetadata, EmptyMetadata } from '../../../data';
1
+ import { ApiSuccessResponseDto, EmptyMetadataDto, ReadMetadataDto, ReadSelectedDefinitionDto } from '../../../data/api/dto';
2
+ import { IIdentifiable } from '../../../data/api/interface';
2
3
  import { IHttpService } from '../HttpService';
3
4
  /**
4
- * Generic API client for consuming any Cornerstone ReadController
5
- *
6
- * @export
7
- * @class ApiReadControllerClient
8
- * @template TKey - Type of the entity key (e.g., number, string, GUID, etc.)
9
- * @template TDto - Data Transfer Object representing the entity
5
+ * Base client for read-only API controllers
10
6
  */
11
7
  export declare class ApiReadControllerClient<TKey, TDto extends IIdentifiable<TKey>> {
12
8
  protected readonly baseControllerPath: string;
@@ -23,19 +19,22 @@ export declare class ApiReadControllerClient<TKey, TDto extends IIdentifiable<TK
23
19
  protected get httpService(): IHttpService;
24
20
  /**
25
21
  * Fetches all entities from the read controller.
26
- * @returns {Promise<ApiSuccessResponse<TDto[], ReadMetadata>>} List of all entities with metadata
22
+ * @param {AbortSignal} [signal] - Optional cancellation signal
23
+ * @returns {Promise<ApiSuccessResponseDto<TDto>[], ReadMetadataDto>>} List of all entities with metadata
27
24
  */
28
- readAll(): Promise<ApiSuccessResponse<TDto[], ReadMetadata>>;
25
+ readAllAsync(signal?: AbortSignal): Promise<ApiSuccessResponseDto<TDto[], ReadMetadataDto>>;
29
26
  /**
30
27
  * Fetches selected entities based on a filter definition.
31
28
  * @param {any} definition - The filter definition object
32
- * @returns {Promise<ApiSuccessResponse<TDto[], ReadMetadata>>} The result of the read operation with metadata
29
+ * @param {AbortSignal} [signal] - Optional cancellation signal
30
+ * @returns {Promise<ApiSuccessResponseDto<TDto>[], ReadMetadataDto>>} The result of the read operation with metadata
33
31
  */
34
- readSelected(definition: ReadSelectedDefinitionDto): Promise<ApiSuccessResponse<TDto[], ReadMetadata>>;
32
+ readSelectedAsync(definition: ReadSelectedDefinitionDto, signal?: AbortSignal): Promise<ApiSuccessResponseDto<TDto[], ReadMetadataDto>>;
35
33
  /**
36
34
  * Fetches a single entity by its ID.
37
35
  * @param {TKey} id - The ID of the entity
38
- * @returns {Promise<ApiSuccessResponse<TDto, EmptyMetadata>>} The requested entity
36
+ * @param {AbortSignal} [signal] - Optional cancellation signal
37
+ * @returns {Promise<ApiSuccessResponseDto<TDto, EmptyMetadataDto>>} The requested entity
39
38
  */
40
- readSingle(id: TKey): Promise<ApiSuccessResponse<TDto, EmptyMetadata>>;
39
+ readSingleAsync(id: TKey, signal?: AbortSignal): Promise<ApiSuccessResponseDto<TDto, EmptyMetadataDto>>;
41
40
  }