@intellegens/cornerstone-client 0.0.16 → 0.0.18

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.
@@ -0,0 +1,8 @@
1
+ export interface Role {
2
+ name: string;
3
+ claims: Claim[];
4
+ }
5
+ export interface Claim {
6
+ name: string;
7
+ value: string;
8
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,3 +1,4 @@
1
+ import { Claim } from "../../../data";
1
2
  /**
2
3
  * Represents a user with an identifier and email address.
3
4
  *
@@ -5,8 +6,10 @@
5
6
  *
6
7
  * @param {TId} id The unique identifier for the user.
7
8
  * @param {string} email The email address associated with the user.
9
+ * @param {Claim[]} claims The claims associated with the user.
8
10
  */
9
11
  export type User<TId> = {
10
12
  id: TId;
11
13
  email: string;
14
+ claims: Claim[];
12
15
  };
@@ -1,2 +1,3 @@
1
1
  export * from './User';
2
2
  export * from './UserInfo';
3
+ export * from './Role';
@@ -1,2 +1,3 @@
1
1
  export * from './User';
2
2
  export * from './UserInfo';
3
+ export * from './Role';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intellegens/cornerstone-client",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -0,0 +1,29 @@
1
+ import { ApiReadControllerClient } from '../..';
2
+ /**
3
+ * Generic API client for consuming any Cornerstone CrudController
4
+ *
5
+ * @export
6
+ * @class ApiReadControllerClient
7
+ * @template TKey - Type of the entity key (e.g., number, string, GUID, etc.)
8
+ * @template TDto - Data Transfer Object representing the entity
9
+ */
10
+ export declare class ApiCrudControllerClient<TKey, TDto> extends ApiReadControllerClient<TKey, TDto> {
11
+ /**
12
+ * Creates a new entity.
13
+ * @param dto - Insert request DTO
14
+ * @returns The created entity DTO
15
+ */
16
+ create(dto: TDto): Promise<TDto>;
17
+ /**
18
+ * Updates an existing entity.
19
+ * @param id - The ID of the entity to update
20
+ * @param dto - Update request DTO
21
+ * @returns The updated entity DTO
22
+ */
23
+ update(id: TKey, dto: TDto): Promise<TDto>;
24
+ /**
25
+ * Deletes an entity by ID.
26
+ * @param id - The ID of the entity to delete
27
+ */
28
+ delete(id: TKey): Promise<void>;
29
+ }
@@ -0,0 +1,74 @@
1
+ import { apiInitializationService, ApiReadControllerClient } from '../..';
2
+ /**
3
+ * Generic API client for consuming any Cornerstone CrudController
4
+ *
5
+ * @export
6
+ * @class ApiReadControllerClient
7
+ * @template TKey - Type of the entity key (e.g., number, string, GUID, etc.)
8
+ * @template TDto - Data Transfer Object representing the entity
9
+ */
10
+ export class ApiCrudControllerClient extends ApiReadControllerClient {
11
+ /**
12
+ * Creates a new entity.
13
+ * @param dto - Insert request DTO
14
+ * @returns The created entity DTO
15
+ */
16
+ async create(dto) {
17
+ try {
18
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/Create`);
19
+ const response = await fetch(url, {
20
+ method: 'POST',
21
+ headers: { 'Content-Type': 'application/json' },
22
+ body: JSON.stringify(dto),
23
+ credentials: 'include',
24
+ });
25
+ if (!response.ok)
26
+ throw new Error('Failed to create record');
27
+ return response.json();
28
+ }
29
+ catch (err) {
30
+ throw err instanceof Error ? err : new Error('Unknown error creating record');
31
+ }
32
+ }
33
+ /**
34
+ * Updates an existing entity.
35
+ * @param id - The ID of the entity to update
36
+ * @param dto - Update request DTO
37
+ * @returns The updated entity DTO
38
+ */
39
+ async update(id, dto) {
40
+ try {
41
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/Update?id=${encodeURIComponent(String(id))}`);
42
+ const response = await fetch(url, {
43
+ method: 'PUT',
44
+ headers: { 'Content-Type': 'application/json' },
45
+ body: JSON.stringify(dto),
46
+ credentials: 'include',
47
+ });
48
+ if (!response.ok)
49
+ throw new Error('Failed to update record');
50
+ return response.json();
51
+ }
52
+ catch (err) {
53
+ throw err instanceof Error ? err : new Error('Unknown error updating record');
54
+ }
55
+ }
56
+ /**
57
+ * Deletes an entity by ID.
58
+ * @param id - The ID of the entity to delete
59
+ */
60
+ async delete(id) {
61
+ try {
62
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/Delete?id=${encodeURIComponent(String(id))}`);
63
+ const response = await fetch(url, {
64
+ method: 'DELETE',
65
+ credentials: 'include',
66
+ });
67
+ if (!response.ok)
68
+ throw new Error('Failed to delete record');
69
+ }
70
+ catch (err) {
71
+ throw err instanceof Error ? err : new Error('Unknown error deleting record');
72
+ }
73
+ }
74
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Central API configuration service, fetches and exposes Cornerstone API configuration
3
+ *
4
+ * @export
5
+ * @class ApiInitializationService
6
+ */
7
+ export declare class ApiInitializationService {
8
+ /**
9
+ * Initializes the API configuration
10
+ *
11
+ * This method calls all methods that need to be called during the API configuration phase:
12
+ * - Starts detection of API base URL.
13
+ *
14
+ * @async
15
+ * @return {Promise<void>} Resolves when initialization is complete.
16
+ */
17
+ initialize(): Promise<void>;
18
+ private _apiBaseUrlPromise;
19
+ /**
20
+ * If API base URL detection was completed
21
+ * IMPORTANT: This property is not meant to be used in normal cases - when ever possible use the .getApiUrl(relativeEndpointPath: string) method instead.
22
+ */
23
+ _apiBaseUrlDetected: boolean;
24
+ /**
25
+ * If API base URL detection was completed, this property will hold the method by which detection was performed
26
+ * IMPORTANT: This property is not meant to be used in normal cases - when ever possible use the .getApiUrl(relativeEndpointPath: string) method instead.
27
+ */
28
+ _apiBaseUrlDetectionMethod: string | undefined;
29
+ /**
30
+ * If API base URL detection was completed, this property will hold the detected API base URL
31
+ * IMPORTANT: This property is not meant to be used in normal cases - when ever possible use the .getApiUrl(relativeEndpointPath: string) method instead.
32
+ */
33
+ _apiBaseUrl: string | undefined;
34
+ /**
35
+ * If API base URL detection has failed, this property will hold the error with which it has failed
36
+ * IMPORTANT: This property is not meant to be used in normal cases - when ever possible use the .getApiUrl(relativeEndpointPath: string) method instead.
37
+ */
38
+ _apiBaseError: Error | undefined;
39
+ /**
40
+ * Tries detecting API base URL by multiple methods
41
+ *
42
+ * - Checks the response headers of the current URL for the `CORNERSTONE-API-BASEURL` header.
43
+ * - Attempts to load the `websettings.json` file and looks for an `api` field.
44
+ * - Defaults to `undefined`.
45
+ *
46
+ * IMPORTANT: This method is not meant to be used in normal cases - when ever possible use the .getApiUrl(relativeEndpointPath: string) method instead.
47
+ *
48
+ * @async
49
+ * @return {Promise<string | undefined>} Returns detected API base URL
50
+ * @throws {Error} Throws error if either of the detection methods fails
51
+ */
52
+ _getApiBaseUrl(): Promise<string | undefined>;
53
+ /**
54
+ * Composes a full API URL for a provided endpoint path.
55
+ *
56
+ * @async
57
+ * @param relativeEndpointPathSections Relative endpoint path sections
58
+ * @return {Promise<string | undefined>} Returns the API endpoint's URL
59
+ * @throws {Error} Throws error if API base URL detection fails
60
+ */
61
+ getApiUrl(...relativeEndpointPathSections: string[]): Promise<string>;
62
+ /**
63
+ * Removes starting '/' character
64
+ * @param str String to remove the starting '/' character from
65
+ * @returns String with starting '/' character removed
66
+ */
67
+ private removeStartsWithSlashChar;
68
+ /**
69
+ * Removes ending '/' character
70
+ * @param str String to remove the ending '/' character from
71
+ * @returns String with ending '/' character removed
72
+ */
73
+ private removeEndsWithSlashChar;
74
+ }
75
+ /**
76
+ * Singleton instance of ApiInitializationService
77
+ */
78
+ export declare const apiInitializationService: ApiInitializationService;
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Central API configuration service, fetches and exposes Cornerstone API configuration
3
+ *
4
+ * @export
5
+ * @class ApiInitializationService
6
+ */
7
+ export class ApiInitializationService {
8
+ /**
9
+ * Initializes the API configuration
10
+ *
11
+ * This method calls all methods that need to be called during the API configuration phase:
12
+ * - Starts detection of API base URL.
13
+ *
14
+ * @async
15
+ * @return {Promise<void>} Resolves when initialization is complete.
16
+ */
17
+ async initialize() {
18
+ // (Pre)detect API base URL
19
+ await this._getApiBaseUrl();
20
+ }
21
+ // #region API Base URL detection
22
+ _apiBaseUrlPromise = undefined;
23
+ /**
24
+ * If API base URL detection was completed
25
+ * IMPORTANT: This property is not meant to be used in normal cases - when ever possible use the .getApiUrl(relativeEndpointPath: string) method instead.
26
+ */
27
+ _apiBaseUrlDetected = false;
28
+ /**
29
+ * If API base URL detection was completed, this property will hold the method by which detection was performed
30
+ * IMPORTANT: This property is not meant to be used in normal cases - when ever possible use the .getApiUrl(relativeEndpointPath: string) method instead.
31
+ */
32
+ _apiBaseUrlDetectionMethod = undefined;
33
+ /**
34
+ * If API base URL detection was completed, this property will hold the detected API base URL
35
+ * IMPORTANT: This property is not meant to be used in normal cases - when ever possible use the .getApiUrl(relativeEndpointPath: string) method instead.
36
+ */
37
+ _apiBaseUrl = undefined;
38
+ /**
39
+ * If API base URL detection has failed, this property will hold the error with which it has failed
40
+ * IMPORTANT: This property is not meant to be used in normal cases - when ever possible use the .getApiUrl(relativeEndpointPath: string) method instead.
41
+ */
42
+ _apiBaseError = undefined;
43
+ /**
44
+ * Tries detecting API base URL by multiple methods
45
+ *
46
+ * - Checks the response headers of the current URL for the `CORNERSTONE-API-BASEURL` header.
47
+ * - Attempts to load the `websettings.json` file and looks for an `api` field.
48
+ * - Defaults to `undefined`.
49
+ *
50
+ * IMPORTANT: This method is not meant to be used in normal cases - when ever possible use the .getApiUrl(relativeEndpointPath: string) method instead.
51
+ *
52
+ * @async
53
+ * @return {Promise<string | undefined>} Returns detected API base URL
54
+ * @throws {Error} Throws error if either of the detection methods fails
55
+ */
56
+ async _getApiBaseUrl() {
57
+ // Check if API already detected; don't reattempt detection
58
+ if (this._apiBaseUrlDetected)
59
+ return this._apiBaseUrl;
60
+ // Check if detection already in progress; don't allow multiple detections in parallel
61
+ if (this._apiBaseUrlPromise)
62
+ return this._apiBaseUrlPromise;
63
+ // Detect API base URL
64
+ return (this._apiBaseUrlPromise = new Promise((resolve, reject) => (async () => {
65
+ // Reset
66
+ this._apiBaseUrlDetected = false;
67
+ this._apiBaseUrlDetectionMethod = undefined;
68
+ this._apiBaseUrl = undefined;
69
+ this._apiBaseError = undefined;
70
+ // Check CORNERSTONE-API-BASEURL header for API base URL
71
+ try {
72
+ const currentUrlResponse = await fetch(window.location.href, { method: 'GET' });
73
+ const apiHeader = currentUrlResponse.headers.get('CORNERSTONE-API-BASEURL');
74
+ if (apiHeader) {
75
+ this._apiBaseUrlDetected = true;
76
+ this._apiBaseUrlDetectionMethod = 'GET / Header:CORNERSTONE-API-BASEURL';
77
+ this._apiBaseUrl = apiHeader;
78
+ this._apiBaseError = undefined;
79
+ this._apiBaseUrlPromise = undefined;
80
+ return resolve(this._apiBaseUrl);
81
+ }
82
+ }
83
+ catch (err) {
84
+ this._apiBaseError = err instanceof Error ? err : new Error('Failed loading API base URL from response header!');
85
+ }
86
+ // Check ./websettings.json header for API base URL
87
+ try {
88
+ const webSettingsResponse = await fetch('./websettings.json', { method: 'GET' });
89
+ if (webSettingsResponse.status === 404)
90
+ return (this._apiBaseUrl = undefined);
91
+ const webSettings = await webSettingsResponse.json();
92
+ if (webSettings?.api) {
93
+ this._apiBaseUrlDetected = true;
94
+ this._apiBaseUrlDetectionMethod = 'GET websettings.json';
95
+ this._apiBaseUrl = webSettings.api;
96
+ this._apiBaseError = undefined;
97
+ this._apiBaseUrlPromise = undefined;
98
+ return resolve(this._apiBaseUrl);
99
+ }
100
+ }
101
+ catch (err) {
102
+ this._apiBaseError = err instanceof Error ? err : new Error('Failed loading API base URL from settings file!');
103
+ }
104
+ // Check if error caught during any of the detection methods
105
+ if (this._apiBaseError !== undefined) {
106
+ this._apiBaseUrlDetected = false;
107
+ this._apiBaseUrlDetectionMethod = undefined;
108
+ this._apiBaseUrl = undefined;
109
+ this._apiBaseUrlPromise = undefined;
110
+ return reject(this._apiBaseError);
111
+ }
112
+ // Default to no API found
113
+ this._apiBaseUrlDetected = true;
114
+ this._apiBaseUrlDetectionMethod = undefined;
115
+ this._apiBaseUrl = undefined;
116
+ this._apiBaseError = undefined;
117
+ this._apiBaseUrlPromise = undefined;
118
+ return resolve(this._apiBaseUrl);
119
+ })()));
120
+ }
121
+ /**
122
+ * Composes a full API URL for a provided endpoint path.
123
+ *
124
+ * @async
125
+ * @param relativeEndpointPathSections Relative endpoint path sections
126
+ * @return {Promise<string | undefined>} Returns the API endpoint's URL
127
+ * @throws {Error} Throws error if API base URL detection fails
128
+ */
129
+ async getApiUrl(...relativeEndpointPathSections) {
130
+ const apiBaseUrl = await this._getApiBaseUrl();
131
+ const domain = !apiBaseUrl ? '/' : `${this.removeEndsWithSlashChar(apiBaseUrl)}/`;
132
+ const path = relativeEndpointPathSections.map(section => this.removeStartsWithSlashChar(this.removeEndsWithSlashChar(section))).join('/');
133
+ return `${domain}${path}`;
134
+ }
135
+ /**
136
+ * Removes starting '/' character
137
+ * @param str String to remove the starting '/' character from
138
+ * @returns String with starting '/' character removed
139
+ */
140
+ removeStartsWithSlashChar(str) {
141
+ return !str.startsWith('/') ? str : str.substring(1);
142
+ }
143
+ /**
144
+ * Removes ending '/' character
145
+ * @param str String to remove the ending '/' character from
146
+ * @returns String with ending '/' character removed
147
+ */
148
+ removeEndsWithSlashChar(str) {
149
+ return !str.endsWith('/') ? str : str.substring(0, str.length - 1);
150
+ }
151
+ }
152
+ /**
153
+ * Singleton instance of ApiInitializationService
154
+ */
155
+ export const apiInitializationService = new ApiInitializationService();
@@ -0,0 +1,34 @@
1
+ import { IIdentifiable, ReadSelectedDefinition } from '../../../data';
2
+ /**
3
+ * Generic API client for consuming any Cornerstone ReadController
4
+ *
5
+ * @export
6
+ * @class ApiReadControllerClient
7
+ * @template TKey - Type of the entity key (e.g., number, string, GUID, etc.)
8
+ * @template TDto - Data Transfer Object representing the entity
9
+ */
10
+ export declare class ApiReadControllerClient<TKey, TDto = IIdentifiable<TKey>> {
11
+ protected readonly baseControllerPath: string;
12
+ /**
13
+ * Constructor
14
+ * @param baseControllerPath Base path to API controller
15
+ */
16
+ constructor(baseControllerPath: string);
17
+ /**
18
+ * Fetches selected entities based on a filter definition.
19
+ * @param {any} definition - The filter definition object
20
+ * @returns {Promise<TDto[]>} List of entities that match the selection criteria
21
+ */
22
+ readSelected(definition: ReadSelectedDefinition): Promise<TDto[]>;
23
+ /**
24
+ * Fetches a single entity by its ID.
25
+ * @param {TKey} id - The ID of the entity
26
+ * @returns {Promise<TDto | undefined>} The requested entity
27
+ */
28
+ readSingle(id: TKey): Promise<TDto>;
29
+ /**
30
+ * Fetches all entities from the read controller.
31
+ * @returns {Promise<TDto[]>} List of all entities
32
+ */
33
+ readAll(): Promise<TDto[]>;
34
+ }
@@ -0,0 +1,74 @@
1
+ import { apiInitializationService } from '../..';
2
+ /**
3
+ * Generic API client for consuming any Cornerstone ReadController
4
+ *
5
+ * @export
6
+ * @class ApiReadControllerClient
7
+ * @template TKey - Type of the entity key (e.g., number, string, GUID, etc.)
8
+ * @template TDto - Data Transfer Object representing the entity
9
+ */
10
+ export class ApiReadControllerClient {
11
+ baseControllerPath;
12
+ /**
13
+ * Constructor
14
+ * @param baseControllerPath Base path to API controller
15
+ */
16
+ constructor(baseControllerPath) {
17
+ this.baseControllerPath = baseControllerPath;
18
+ }
19
+ /**
20
+ * Fetches selected entities based on a filter definition.
21
+ * @param {any} definition - The filter definition object
22
+ * @returns {Promise<TDto[]>} List of entities that match the selection criteria
23
+ */
24
+ async readSelected(definition) {
25
+ try {
26
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/ReadSelected`);
27
+ const response = await fetch(url, {
28
+ method: 'POST',
29
+ headers: { 'Content-Type': 'application/json' },
30
+ body: JSON.stringify(definition),
31
+ credentials: 'include',
32
+ });
33
+ if (!response.ok)
34
+ throw new Error('Failed to fetch selected records');
35
+ return response.json();
36
+ }
37
+ catch (err) {
38
+ throw err instanceof Error ? err : new Error('Unknown error fetching selected records');
39
+ }
40
+ }
41
+ /**
42
+ * Fetches a single entity by its ID.
43
+ * @param {TKey} id - The ID of the entity
44
+ * @returns {Promise<TDto | undefined>} The requested entity
45
+ */
46
+ async readSingle(id) {
47
+ try {
48
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/ReadSingle?id=${encodeURIComponent(String(id))}`);
49
+ const response = await fetch(url, { credentials: 'include' });
50
+ if (!response.ok)
51
+ throw new Error('Failed to fetch single record');
52
+ return response.json();
53
+ }
54
+ catch (err) {
55
+ throw err instanceof Error ? err : new Error('Unknown error fetching single record');
56
+ }
57
+ }
58
+ /**
59
+ * Fetches all entities from the read controller.
60
+ * @returns {Promise<TDto[]>} List of all entities
61
+ */
62
+ async readAll() {
63
+ try {
64
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/ReadAll`);
65
+ const response = await fetch(url, { credentials: 'include' });
66
+ if (!response.ok)
67
+ throw new Error('Failed to fetch all records');
68
+ return response.json();
69
+ }
70
+ catch (err) {
71
+ throw err instanceof Error ? err : new Error('Unknown error fetching all records');
72
+ }
73
+ }
74
+ }
@@ -0,0 +1,35 @@
1
+ import { ApiCrudControllerClient } from '../..';
2
+ /**
3
+ * Client for user management operations
4
+ *
5
+ * @export
6
+ * @class UserManagementControllerClient
7
+ * @template TKey - Type of the entity key (e.g., number, string, GUID, etc.)
8
+ * @template TDto - Data Transfer Object representing the user entity
9
+ */
10
+ export declare class UserManagementControllerClient<TKey, TDto> extends ApiCrudControllerClient<TKey, TDto> {
11
+ /**
12
+ * Gets the roles assigned to a user
13
+ * @param id - The ID of the user
14
+ * @returns List of role names assigned to the user
15
+ */
16
+ getUserRoles(id: TKey): Promise<string[]>;
17
+ /**
18
+ * Gets the claims assigned to a user
19
+ * @param id - The ID of the user
20
+ * @returns List of claims assigned to the user
21
+ */
22
+ getUserClaims(id: TKey): Promise<Record<string, string>>;
23
+ /**
24
+ * Gets all available roles in the system
25
+ * @returns List of all role names
26
+ */
27
+ getAllRoles(): Promise<string[]>;
28
+ /**
29
+ * Changes the password for a user
30
+ * @param id - The ID of the user
31
+ * @param newPassword - The new password to set
32
+ * @returns Promise that resolves when the password is changed successfully
33
+ */
34
+ changePassword(id: TKey, newPassword: string): Promise<void>;
35
+ }
@@ -0,0 +1,93 @@
1
+ import { ApiCrudControllerClient, apiInitializationService } from '../..';
2
+ /**
3
+ * Client for user management operations
4
+ *
5
+ * @export
6
+ * @class UserManagementControllerClient
7
+ * @template TKey - Type of the entity key (e.g., number, string, GUID, etc.)
8
+ * @template TDto - Data Transfer Object representing the user entity
9
+ */
10
+ export class UserManagementControllerClient extends ApiCrudControllerClient {
11
+ /**
12
+ * Gets the roles assigned to a user
13
+ * @param id - The ID of the user
14
+ * @returns List of role names assigned to the user
15
+ */
16
+ async getUserRoles(id) {
17
+ try {
18
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/GetUserRoles${encodeURIComponent(String(id))}`);
19
+ const response = await fetch(url, {
20
+ credentials: 'include',
21
+ });
22
+ if (!response.ok)
23
+ throw new Error('Failed to fetch user roles');
24
+ return response.json();
25
+ }
26
+ catch (err) {
27
+ throw err instanceof Error ? err : new Error('Unknown error fetching user roles');
28
+ }
29
+ }
30
+ /**
31
+ * Gets the claims assigned to a user
32
+ * @param id - The ID of the user
33
+ * @returns List of claims assigned to the user
34
+ */
35
+ async getUserClaims(id) {
36
+ try {
37
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/GetUserClaims/${encodeURIComponent(String(id))}`);
38
+ const response = await fetch(url, {
39
+ credentials: 'include',
40
+ });
41
+ if (!response.ok)
42
+ throw new Error('Failed to fetch user claims');
43
+ return response.json();
44
+ }
45
+ catch (err) {
46
+ throw err instanceof Error ? err : new Error('Unknown error fetching user claims');
47
+ }
48
+ }
49
+ /**
50
+ * Gets all available roles in the system
51
+ * @returns List of all role names
52
+ */
53
+ async getAllRoles() {
54
+ try {
55
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/GetAllRoles`);
56
+ const response = await fetch(url, {
57
+ credentials: 'include',
58
+ });
59
+ if (!response.ok)
60
+ throw new Error('Failed to fetch all roles');
61
+ return response.json();
62
+ }
63
+ catch (err) {
64
+ throw err instanceof Error ? err : new Error('Unknown error fetching all roles');
65
+ }
66
+ }
67
+ /**
68
+ * Changes the password for a user
69
+ * @param id - The ID of the user
70
+ * @param newPassword - The new password to set
71
+ * @returns Promise that resolves when the password is changed successfully
72
+ */
73
+ async changePassword(id, newPassword) {
74
+ try {
75
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/ChangePassword/${encodeURIComponent(String(id))}`);
76
+ const response = await fetch(url, {
77
+ method: 'POST',
78
+ headers: {
79
+ 'Content-Type': 'application/json'
80
+ },
81
+ body: JSON.stringify(newPassword),
82
+ credentials: 'include',
83
+ });
84
+ if (!response.ok) {
85
+ const errorText = await response.text();
86
+ throw new Error(errorText || 'Failed to change password');
87
+ }
88
+ }
89
+ catch (err) {
90
+ throw err instanceof Error ? err : new Error('Unknown error changing password');
91
+ }
92
+ }
93
+ }
@@ -8,4 +8,22 @@ import { ApiReadControllerClient } from '../../..';
8
8
  * @template TDto - Data Transfer Object representing the entity
9
9
  */
10
10
  export declare class ApiCrudControllerClient<TKey, TDto> extends ApiReadControllerClient<TKey, TDto> {
11
+ /**
12
+ * Creates a new entity.
13
+ * @param dto - Insert request DTO
14
+ * @returns The created entity DTO
15
+ */
16
+ create(dto: TDto): Promise<TDto>;
17
+ /**
18
+ * Updates an existing entity.
19
+ * @param id - The ID of the entity to update
20
+ * @param dto - Update request DTO
21
+ * @returns The updated entity DTO
22
+ */
23
+ update(id: TKey, dto: TDto): Promise<TDto>;
24
+ /**
25
+ * Deletes an entity by ID.
26
+ * @param id - The ID of the entity to delete
27
+ */
28
+ delete(id: TKey): Promise<void>;
11
29
  }
@@ -1,4 +1,4 @@
1
- import { ApiReadControllerClient } from '../../..';
1
+ import { apiInitializationService, ApiReadControllerClient } from '../../..';
2
2
  /**
3
3
  * Generic API client for consuming any Cornerstone CrudController
4
4
  *
@@ -8,4 +8,67 @@ import { ApiReadControllerClient } from '../../..';
8
8
  * @template TDto - Data Transfer Object representing the entity
9
9
  */
10
10
  export class ApiCrudControllerClient extends ApiReadControllerClient {
11
+ /**
12
+ * Creates a new entity.
13
+ * @param dto - Insert request DTO
14
+ * @returns The created entity DTO
15
+ */
16
+ async create(dto) {
17
+ try {
18
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/Create`);
19
+ const response = await fetch(url, {
20
+ method: 'POST',
21
+ headers: { 'Content-Type': 'application/json' },
22
+ body: JSON.stringify(dto),
23
+ credentials: 'include',
24
+ });
25
+ if (!response.ok)
26
+ throw new Error('Failed to create record');
27
+ return response.json();
28
+ }
29
+ catch (err) {
30
+ throw err instanceof Error ? err : new Error('Unknown error creating record');
31
+ }
32
+ }
33
+ /**
34
+ * Updates an existing entity.
35
+ * @param id - The ID of the entity to update
36
+ * @param dto - Update request DTO
37
+ * @returns The updated entity DTO
38
+ */
39
+ async update(id, dto) {
40
+ try {
41
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/Update?id=${encodeURIComponent(String(id))}`);
42
+ const response = await fetch(url, {
43
+ method: 'PUT',
44
+ headers: { 'Content-Type': 'application/json' },
45
+ body: JSON.stringify(dto),
46
+ credentials: 'include',
47
+ });
48
+ if (!response.ok)
49
+ throw new Error('Failed to update record');
50
+ return response.json();
51
+ }
52
+ catch (err) {
53
+ throw err instanceof Error ? err : new Error('Unknown error updating record');
54
+ }
55
+ }
56
+ /**
57
+ * Deletes an entity by ID.
58
+ * @param id - The ID of the entity to delete
59
+ */
60
+ async delete(id) {
61
+ try {
62
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/Delete?id=${encodeURIComponent(String(id))}`);
63
+ const response = await fetch(url, {
64
+ method: 'DELETE',
65
+ credentials: 'include',
66
+ });
67
+ if (!response.ok)
68
+ throw new Error('Failed to delete record');
69
+ }
70
+ catch (err) {
71
+ throw err instanceof Error ? err : new Error('Unknown error deleting record');
72
+ }
73
+ }
11
74
  }
@@ -8,7 +8,7 @@ import { IIdentifiable, ReadSelectedDefinition } from '../../../../data';
8
8
  * @template TDto - Data Transfer Object representing the entity
9
9
  */
10
10
  export declare class ApiReadControllerClient<TKey, TDto = IIdentifiable<TKey>> {
11
- private readonly baseControllerPath;
11
+ protected readonly baseControllerPath: string;
12
12
  /**
13
13
  * Constructor
14
14
  * @param baseControllerPath Base path to API controller
@@ -1,2 +1,4 @@
1
- export * from './initialization';
2
- export * from './client';
1
+ export * from './ApiCrudControllerClient';
2
+ export * from './ApiInitializationService';
3
+ export * from './ApiReadControllerClient';
4
+ export * from './UserManagementControllerClient';
@@ -1,2 +1,4 @@
1
- export * from './initialization';
2
- export * from './client';
1
+ export * from './ApiCrudControllerClient';
2
+ export * from './ApiInitializationService';
3
+ export * from './ApiReadControllerClient';
4
+ export * from './UserManagementControllerClient';
@@ -0,0 +1,50 @@
1
+ import { User, UserInfo } from '../../../../data';
2
+ export { User, UserInfo };
3
+ /**
4
+ * AuthService class is responsible for managing user authentication operations.
5
+ * It supports login, logout, and checking the current user's details.
6
+ *
7
+ * @export
8
+ * @class AuthService
9
+ */
10
+ export declare class AuthService<TId, TUser extends User<TId> = User<TId>> {
11
+ /**
12
+ * Holds currently authenticated user's details
13
+ */
14
+ user: TUser | undefined;
15
+ /**
16
+ * Initializes the Authentication status by checking with the API if the current user is authenticated or not
17
+ *
18
+ * @async
19
+ * @return {Promise<void>} Resolves when initialization is complete.
20
+ */
21
+ initialize(): Promise<void>;
22
+ /**
23
+ * Checks if user is authenticated and retrieves the current user's details if they are
24
+ *
25
+ * @return {Promise<TUser>} Currently logged in user's details
26
+ * @throws {Error} Error if fetch fails
27
+ */
28
+ whoAmI(): Promise<TUser | undefined>;
29
+ /**
30
+ * Authenticates a user using their username and password, and retrieves user's details
31
+ *
32
+ * @param {string} username Login credentials: username
33
+ * @param {string} password Login credentials: password
34
+ * @return {Promise<TUser>} Currently logged in user's details
35
+ * @throws {Error} Error if fetch fails
36
+ */
37
+ signin(username: string, password: string): Promise<TUser>;
38
+ /**
39
+ * Deauthenticates current user
40
+ *
41
+ * @return {Promise<void>}
42
+ * @throws {Error} Error if fetch fails
43
+ */
44
+ signout(): Promise<void>;
45
+ /**
46
+ * If any API response returns an "Unauthenticated" response, call this method
47
+ * to update local authentication state to unauthenticated
48
+ */
49
+ _handleResponse401(): void;
50
+ }
@@ -0,0 +1,113 @@
1
+ import { apiInitializationService } from '../../..';
2
+ /**
3
+ * AuthService class is responsible for managing user authentication operations.
4
+ * It supports login, logout, and checking the current user's details.
5
+ *
6
+ * @export
7
+ * @class AuthService
8
+ */
9
+ export class AuthService {
10
+ /**
11
+ * Holds currently authenticated user's details
12
+ */
13
+ user = undefined;
14
+ /**
15
+ * Initializes the Authentication status by checking with the API if the current user is authenticated or not
16
+ *
17
+ * @async
18
+ * @return {Promise<void>} Resolves when initialization is complete.
19
+ */
20
+ async initialize() {
21
+ // Check user's authentication status
22
+ await this.whoAmI();
23
+ }
24
+ /**
25
+ * Checks if user is authenticated and retrieves the current user's details if they are
26
+ *
27
+ * @return {Promise<TUser>} Currently logged in user's details
28
+ * @throws {Error} Error if fetch fails
29
+ */
30
+ async whoAmI() {
31
+ try {
32
+ const url = await apiInitializationService.getApiUrl('/auth/whoami');
33
+ const response = await fetch(url, { credentials: 'include' });
34
+ if (response.ok) {
35
+ const info = await response.json();
36
+ return (this.user = info.user);
37
+ }
38
+ else if (response.status === 401) {
39
+ return (this.user = undefined);
40
+ }
41
+ else {
42
+ this.user = undefined;
43
+ throw new Error('Failed checking authentication status');
44
+ }
45
+ }
46
+ catch (error) {
47
+ throw error instanceof Error ? error : new Error('Failed checking authentication status');
48
+ }
49
+ }
50
+ /**
51
+ * Authenticates a user using their username and password, and retrieves user's details
52
+ *
53
+ * @param {string} username Login credentials: username
54
+ * @param {string} password Login credentials: password
55
+ * @return {Promise<TUser>} Currently logged in user's details
56
+ * @throws {Error} Error if fetch fails
57
+ */
58
+ async signin(username, password) {
59
+ try {
60
+ const url = await apiInitializationService.getApiUrl('/auth/signin');
61
+ const response = await fetch(url, {
62
+ method: 'POST',
63
+ headers: { 'Content-Type': 'application/json' },
64
+ body: JSON.stringify({ username, password }),
65
+ credentials: 'include',
66
+ });
67
+ if (response.ok) {
68
+ const user = await this.whoAmI();
69
+ if (user !== undefined) {
70
+ return (this.user = user);
71
+ }
72
+ else {
73
+ throw new Error('Failed signing in');
74
+ }
75
+ }
76
+ else {
77
+ throw new Error('Failed signing in');
78
+ }
79
+ }
80
+ catch (error) {
81
+ throw error instanceof Error ? error : new Error('Failed signing in');
82
+ }
83
+ }
84
+ /**
85
+ * Deauthenticates current user
86
+ *
87
+ * @return {Promise<void>}
88
+ * @throws {Error} Error if fetch fails
89
+ */
90
+ async signout() {
91
+ try {
92
+ const url = await apiInitializationService.getApiUrl('/auth/signout');
93
+ const response = await fetch(url, { credentials: 'include' });
94
+ if (response.ok) {
95
+ this.user = undefined;
96
+ return;
97
+ }
98
+ else {
99
+ throw new Error('Failed signing out');
100
+ }
101
+ }
102
+ catch (error) {
103
+ throw error instanceof Error ? error : new Error('Failed signing out');
104
+ }
105
+ }
106
+ /**
107
+ * If any API response returns an "Unauthenticated" response, call this method
108
+ * to update local authentication state to unauthenticated
109
+ */
110
+ _handleResponse401() {
111
+ this.user = undefined;
112
+ }
113
+ }
@@ -0,0 +1,39 @@
1
+ import { Role } from '../../../../data';
2
+ /**
3
+ * Client for authorization management operations
4
+ *
5
+ * @export
6
+ * @class AuthorizationManagementControllerClient
7
+ */
8
+ export declare class AuthorizationManagementControllerClient {
9
+ protected readonly baseControllerPath: string;
10
+ /**
11
+ * Constructor
12
+ * @param baseControllerPath Base path to API controller
13
+ */
14
+ constructor(baseControllerPath?: string);
15
+ /**
16
+ * Gets all roles in the system
17
+ * @param includeClaims - Whether to include claims in the response
18
+ * @returns List of all roles
19
+ */
20
+ getAllRoles(includeClaims: boolean): Promise<Role[]>;
21
+ /**
22
+ * Creates or updates a role
23
+ * @param roleDto - The role to create or update
24
+ * @returns The created or updated role
25
+ */
26
+ upsertRole(roleDto: Role): Promise<Role>;
27
+ /**
28
+ * Gets a role with its claims
29
+ * @param roleName - The name of the role
30
+ * @returns The role with its claims
31
+ */
32
+ getRoleWithClaims(roleName: string): Promise<Role>;
33
+ /**
34
+ * Deletes a role
35
+ * @param roleName - The name of the role to delete
36
+ * @returns Promise that resolves when the role is deleted successfully
37
+ */
38
+ deleteRole(roleName: string): Promise<void>;
39
+ }
@@ -0,0 +1,102 @@
1
+ import { apiInitializationService } from '../../..';
2
+ /**
3
+ * Client for authorization management operations
4
+ *
5
+ * @export
6
+ * @class AuthorizationManagementControllerClient
7
+ */
8
+ export class AuthorizationManagementControllerClient {
9
+ baseControllerPath;
10
+ /**
11
+ * Constructor
12
+ * @param baseControllerPath Base path to API controller
13
+ */
14
+ constructor(baseControllerPath = 'AuthorizationManagement') {
15
+ this.baseControllerPath = baseControllerPath;
16
+ }
17
+ /**
18
+ * Gets all roles in the system
19
+ * @param includeClaims - Whether to include claims in the response
20
+ * @returns List of all roles
21
+ */
22
+ async getAllRoles(includeClaims) {
23
+ try {
24
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/GetAllRoles?includeClaims=${includeClaims}`);
25
+ const response = await fetch(url, {
26
+ credentials: 'include',
27
+ });
28
+ if (!response.ok)
29
+ throw new Error('Failed to fetch all roles');
30
+ return response.json();
31
+ }
32
+ catch (err) {
33
+ throw err instanceof Error ? err : new Error('Unknown error fetching all roles');
34
+ }
35
+ }
36
+ /**
37
+ * Creates or updates a role
38
+ * @param roleDto - The role to create or update
39
+ * @returns The created or updated role
40
+ */
41
+ async upsertRole(roleDto) {
42
+ try {
43
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/UpsertRole`);
44
+ const response = await fetch(url, {
45
+ method: 'PUT',
46
+ headers: {
47
+ 'Content-Type': 'application/json'
48
+ },
49
+ body: JSON.stringify(roleDto),
50
+ credentials: 'include',
51
+ });
52
+ if (!response.ok) {
53
+ const errorText = await response.text();
54
+ throw new Error(errorText || 'Failed to upsert role');
55
+ }
56
+ return response.json();
57
+ }
58
+ catch (err) {
59
+ throw err instanceof Error ? err : new Error('Unknown error upserting role');
60
+ }
61
+ }
62
+ /**
63
+ * Gets a role with its claims
64
+ * @param roleName - The name of the role
65
+ * @returns The role with its claims
66
+ */
67
+ async getRoleWithClaims(roleName) {
68
+ try {
69
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/GetRoleWithClaims/${encodeURIComponent(roleName)}`);
70
+ const response = await fetch(url, {
71
+ credentials: 'include',
72
+ });
73
+ if (!response.ok)
74
+ throw new Error('Failed to fetch role with claims');
75
+ return response.json();
76
+ }
77
+ catch (err) {
78
+ throw err instanceof Error ? err : new Error('Unknown error fetching role with claims');
79
+ }
80
+ }
81
+ /**
82
+ * Deletes a role
83
+ * @param roleName - The name of the role to delete
84
+ * @returns Promise that resolves when the role is deleted successfully
85
+ */
86
+ async deleteRole(roleName) {
87
+ try {
88
+ const url = await apiInitializationService.getApiUrl(this.baseControllerPath, `/DeleteRole/${encodeURIComponent(roleName)}`);
89
+ const response = await fetch(url, {
90
+ method: 'DELETE',
91
+ credentials: 'include',
92
+ });
93
+ if (!response.ok) {
94
+ const errorText = await response.text();
95
+ throw new Error(errorText || 'Failed to delete role');
96
+ }
97
+ }
98
+ catch (err) {
99
+ throw err instanceof Error ? err : new Error('Unknown error deleting role');
100
+ }
101
+ }
102
+ }
@@ -0,0 +1,2 @@
1
+ export * from './AuthorizationManagementControllerClient';
2
+ export * from './AuthService';
@@ -0,0 +1,2 @@
1
+ export * from './AuthorizationManagementControllerClient';
2
+ export * from './AuthService';
@@ -1,50 +1 @@
1
- import { User, UserInfo } from '../../data';
2
- export { User, UserInfo };
3
- /**
4
- * AuthService class is responsible for managing user authentication operations.
5
- * It supports login, logout, and checking the current user's details.
6
- *
7
- * @export
8
- * @class AuthService
9
- */
10
- export declare class AuthService<TId, TUser = User<TId>> {
11
- /**
12
- * Holds currently authenticated user's details
13
- */
14
- user: TUser | undefined;
15
- /**
16
- * Initializes the Authentication status by checking with the API if the current user is authenticated or not
17
- *
18
- * @async
19
- * @return {Promise<void>} Resolves when initialization is complete.
20
- */
21
- initialize(): Promise<void>;
22
- /**
23
- * Checks if user is authenticated and retrieves the current user's details if they are
24
- *
25
- * @return {Promise<TUser>} Currently logged in user's details
26
- * @throws {Error} Error if fetch fails
27
- */
28
- whoAmI(): Promise<TUser | undefined>;
29
- /**
30
- * Authenticates a user using their username and password, and retrieves user's details
31
- *
32
- * @param {string} username Login credentials: username
33
- * @param {string} password Login credentials: password
34
- * @return {Promise<TUser>} Currently logged in user's details
35
- * @throws {Error} Error if fetch fails
36
- */
37
- signin(username: string, password: string): Promise<TUser>;
38
- /**
39
- * Deauthenticates current user
40
- *
41
- * @return {Promise<void>}
42
- * @throws {Error} Error if fetch fails
43
- */
44
- signout(): Promise<void>;
45
- /**
46
- * If any API response returns an "Unauthenticated" response, call this method
47
- * to update local authentication state to unauthenticated
48
- */
49
- _handleResponse401(): void;
50
- }
1
+ export * from './client';
@@ -1,113 +1 @@
1
- import { apiInitializationService } from '..';
2
- /**
3
- * AuthService class is responsible for managing user authentication operations.
4
- * It supports login, logout, and checking the current user's details.
5
- *
6
- * @export
7
- * @class AuthService
8
- */
9
- export class AuthService {
10
- /**
11
- * Holds currently authenticated user's details
12
- */
13
- user = undefined;
14
- /**
15
- * Initializes the Authentication status by checking with the API if the current user is authenticated or not
16
- *
17
- * @async
18
- * @return {Promise<void>} Resolves when initialization is complete.
19
- */
20
- async initialize() {
21
- // Check user's authentication status
22
- await this.whoAmI();
23
- }
24
- /**
25
- * Checks if user is authenticated and retrieves the current user's details if they are
26
- *
27
- * @return {Promise<TUser>} Currently logged in user's details
28
- * @throws {Error} Error if fetch fails
29
- */
30
- async whoAmI() {
31
- try {
32
- const url = await apiInitializationService.getApiUrl('/auth/whoami');
33
- const response = await fetch(url, { credentials: 'include' });
34
- if (response.ok) {
35
- const info = await response.json();
36
- return (this.user = info.user);
37
- }
38
- else if (response.status === 401) {
39
- return (this.user = undefined);
40
- }
41
- else {
42
- this.user = undefined;
43
- throw new Error('Failed checking authentication status');
44
- }
45
- }
46
- catch (error) {
47
- throw error instanceof Error ? error : new Error('Failed checking authentication status');
48
- }
49
- }
50
- /**
51
- * Authenticates a user using their username and password, and retrieves user's details
52
- *
53
- * @param {string} username Login credentials: username
54
- * @param {string} password Login credentials: password
55
- * @return {Promise<TUser>} Currently logged in user's details
56
- * @throws {Error} Error if fetch fails
57
- */
58
- async signin(username, password) {
59
- try {
60
- const url = await apiInitializationService.getApiUrl('/auth/signin');
61
- const response = await fetch(url, {
62
- method: 'POST',
63
- headers: { 'Content-Type': 'application/json' },
64
- body: JSON.stringify({ username, password }),
65
- credentials: 'include',
66
- });
67
- if (response.ok) {
68
- const user = await this.whoAmI();
69
- if (user !== undefined) {
70
- return (this.user = user);
71
- }
72
- else {
73
- throw new Error('Failed signing in');
74
- }
75
- }
76
- else {
77
- throw new Error('Failed signing in');
78
- }
79
- }
80
- catch (error) {
81
- throw error instanceof Error ? error : new Error('Failed signing in');
82
- }
83
- }
84
- /**
85
- * Deauthenticates current user
86
- *
87
- * @return {Promise<void>}
88
- * @throws {Error} Error if fetch fails
89
- */
90
- async signout() {
91
- try {
92
- const url = await apiInitializationService.getApiUrl('/auth/signout');
93
- const response = await fetch(url, { credentials: 'include' });
94
- if (response.ok) {
95
- this.user = undefined;
96
- return;
97
- }
98
- else {
99
- throw new Error('Failed signing out');
100
- }
101
- }
102
- catch (error) {
103
- throw error instanceof Error ? error : new Error('Failed signing out');
104
- }
105
- }
106
- /**
107
- * If any API response returns an "Unauthenticated" response, call this method
108
- * to update local authentication state to unauthenticated
109
- */
110
- _handleResponse401() {
111
- this.user = undefined;
112
- }
113
- }
1
+ export * from './client';