@intellegens/cornerstone-client 0.0.18 → 0.0.19

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.
@@ -9,7 +9,7 @@ import { Claim } from "../../../data";
9
9
  * @param {Claim[]} claims The claims associated with the user.
10
10
  */
11
11
  export type User<TId> = {
12
- id: TId;
12
+ id: TId | undefined;
13
13
  email: string;
14
14
  claims: Claim[];
15
15
  };
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@intellegens/cornerstone-client",
3
- "version": "0.0.18",
3
+ "version": "0.0.19",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "scripts": {
7
+ "clean": "node -e \"require('fs-extra').emptyDir('./dist');\"",
7
8
  "test": "echo \"Error: no test specified\" && exit 1",
8
- "build": "npm run transpile-types && tsc && tsc-alias",
9
+ "build": "npm run clean && npm run transpile-types && tsc && tsc-alias",
9
10
  "demo": "npm run build && npx vite build && npx tsx ./demo",
10
11
  "transpile-types": "cd ../utils/cli && npm run cli zod-gen -- --input '../../client/src/data/_jsonschema' --output '../../client/src/data/_generated'"
11
12
  },
@@ -19,6 +20,7 @@
19
20
  "eslint": "^9.21.0",
20
21
  "eslint-config-prettier": "^10.0.1",
21
22
  "express": "^4.21.2",
23
+ "fs-extra": "^11.3.0",
22
24
  "globals": "^16.0.0",
23
25
  "prettier": "^3.5.2",
24
26
  "tsc-alias": "^1.8.11",
@@ -1,4 +1,4 @@
1
- export * from './ApiCrudControllerClient';
2
1
  export * from './ApiInitializationService';
3
2
  export * from './ApiReadControllerClient';
3
+ export * from './ApiCrudControllerClient';
4
4
  export * from './UserManagementControllerClient';
@@ -1,4 +1,4 @@
1
- export * from './ApiCrudControllerClient';
2
1
  export * from './ApiInitializationService';
3
2
  export * from './ApiReadControllerClient';
3
+ export * from './ApiCrudControllerClient';
4
4
  export * from './UserManagementControllerClient';
@@ -1,29 +0,0 @@
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
- }
@@ -1,74 +0,0 @@
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
- }
@@ -1,34 +0,0 @@
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
- }
@@ -1,74 +0,0 @@
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
- }
@@ -1,2 +0,0 @@
1
- export * from './ApiReadControllerClient';
2
- export * from './ApiCrudControllerClient';
@@ -1,2 +0,0 @@
1
- export * from './ApiReadControllerClient';
2
- export * from './ApiCrudControllerClient';
@@ -1,78 +0,0 @@
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;
@@ -1,155 +0,0 @@
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();