docpouch-client 1.0.1 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,630 +1,630 @@
1
- # docpouch-client
2
-
3
- A TypeScript client library for interacting with the [docPouch](https://github.com/BFH-JTF/doc-pouch) database API.
4
- Supports JWT and OIDC (OpenID Connect) authentication.
5
-
6
- ## Table of Contents
7
-
8
- - [Description](#description)
9
- - [Installation](#installation)
10
- - [Usage](#usage)
11
- - [Initializing the Client](#initializing-the-client)
12
- - [JWT Authentication](#jwt-authentication)
13
- - [OIDC Authentication](#oidc-authentication)
14
- - [OIDC Dynamic Client Registration](#oidc-dynamic-client-registration)
15
- - [User Management](#user-management)
16
- - [Document Management](#document-management)
17
- - [Data Structure Management](#data-structure-management)
18
- - [Real-Time Synchronization](#real-time-synchronization)
19
- - [Error Handling](#error-handling)
20
- - [API Reference](#api-reference)
21
- - [Types](#types)
22
- - [License](#license)
23
-
24
- ## Description
25
-
26
- docpouch-client provides a simple and intuitive interface to access the docPouch API, allowing you to manage users,
27
- documents, and data structures. It supports real-time synchronization via WebSockets and two authentication
28
- methods: traditional JWT (username/password) and OpenID Connect (OIDC).
29
-
30
- ## Installation
31
-
32
- ```bash
33
- npm install docpouch-client
34
- ```
35
-
36
- ## Usage
37
-
38
- ### Initializing the Client
39
-
40
- ```typescript
41
- import docPouchClient from 'docpouch-client';
42
-
43
- // Initialize the client with the server URL
44
- const client = new docPouchClient('https://your-docpouch-server.com', 80);
45
-
46
- // Initialize with a callback for real-time updates
47
- const client = new docPouchClient('https://your-docpouch-server.com', 80,
48
- (event, data) => {
49
- console.log(`Received event: ${event}`, data);
50
- }
51
- );
52
- ```
53
-
54
- ### JWT Authentication
55
-
56
- ```typescript
57
- // Login to get an authentication token
58
- const loginResponse = await client.login({
59
- name: 'username',
60
- password: 'password'
61
- });
62
-
63
- if (loginResponse) {
64
- console.log('Login successful!');
65
- console.log(`Token: ${loginResponse.token}`);
66
- } else {
67
- console.log('Login failed');
68
- }
69
-
70
- // Set an existing token
71
- client.setToken('your-auth-token');
72
-
73
- // Check authentication state
74
- console.log(client.isAuthenticated()); // boolean
75
- console.log(client.getAuthMethod()); // 'jwt' | 'oidc' | 'none'
76
- console.log(client.getToken()); // string | null
77
- ```
78
-
79
- ### OIDC Authentication
80
-
81
- ```typescript
82
- // Initiate OIDC login (redirects the browser to the identity provider)
83
- await client.loginWithOidc({
84
- issuer: 'https://your-oidc-provider.com',
85
- clientId: 'your-client-id',
86
- redirectUri: 'https://yourapp.com/callback',
87
- scopes: ['openid', 'profile', 'email']
88
- });
89
-
90
- // Handle the OIDC callback on your redirect page
91
- const handled = await client.handleOidcCallback();
92
- if (handled) {
93
- console.log('OIDC login successful');
94
- }
95
-
96
- // The access token is automatically refreshed when needed
97
- const validToken = await client.ensureValidOidcToken();
98
-
99
- // Log out (clears tokens, disconnects WebSocket, cleans up URL params)
100
- await client.logout();
101
- ```
102
-
103
- ### OIDC Dynamic Client Registration
104
-
105
- ```typescript
106
- // Register a new OIDC client
107
- const registered = await client.registerOidcClient({
108
- client_name: 'My Application',
109
- redirect_uris: ['https://yourapp.com/callback'],
110
- grant_types: ['authorization_code'],
111
- response_types: ['code'],
112
- token_endpoint_auth_method: 'client_secret_basic'
113
- });
114
- console.log(registered.client_id);
115
-
116
- // Retrieve an existing client registration
117
- const clientInfo = await client.getOidcClient('client-id');
118
-
119
- // Update a client registration
120
- await client.updateOidcClient('client-id', {
121
- client_name: 'Updated Application Name'
122
- });
123
-
124
- // Delete a client registration
125
- await client.deleteOidcClient('client-id');
126
- ```
127
-
128
- ### User Management
129
-
130
- ```typescript
131
- // List all users
132
- const users = await client.listUsers();
133
-
134
- // Create a new user
135
- const newUser = await client.createUser({
136
- name: 'newuser',
137
- password: 'password',
138
- department: 'IT',
139
- group: 'Developers',
140
- isAdmin: false
141
- });
142
-
143
- // Update a user
144
- await client.updateUser('user-id', {
145
- department: 'Engineering',
146
- group: 'Frontend'
147
- });
148
-
149
- // Remove a user
150
- await client.removeUser('user-id');
151
- ```
152
-
153
- ### Document Management
154
-
155
- ```typescript
156
- // Create a new document
157
- const newDocument = await client.createDocument({
158
- _id: 'document-id',
159
- owner: 'user-id',
160
- title: 'Mission Statement',
161
- type: 17,
162
- subType: 11,
163
- content: '{"msg": "We strive for a world that..."}',
164
- shareWithGroup: false,
165
- shareWithDepartment: false,
166
- public: false
167
- });
168
-
169
- // Update a document
170
- await client.updateDocument('document-id', {
171
- _id: 'document-id',
172
- owner: 'user-id',
173
- title: 'Updated Mission Statement',
174
- type: 17,
175
- subType: 11,
176
- content: '{"msg": "Our updated mission..."}',
177
- shareWithGroup: false,
178
- shareWithDepartment: false,
179
- public: false
180
- });
181
-
182
- // Delete a document
183
- await client.removeDocument('document-id');
184
-
185
- // List all documents
186
- const allDocuments = await client.listDocuments();
187
-
188
- // Fetch documents by query
189
- const documents = await client.fetchDocuments({type: 17, subType: 11});
190
- ```
191
-
192
- ### Data Structure Management
193
-
194
- ```typescript
195
- // Create a new data structure
196
- const newStructure = await client.createStructure({
197
- name: "Data resulting from Vision-Mission-Value-Canvas",
198
- fields: [
199
- {
200
- name: "mission_value_statement",
201
- displayName: "Mission value statement",
202
- type: "string"
203
- },
204
- ]
205
- });
206
-
207
- // Update a data structure
208
- await client.updateStructure('structure-id', {
209
- _id: 'structure-id',
210
- name: 'Updated Structure Title',
211
- description: 'Updated structure description',
212
- type: 17,
213
- subType: 11,
214
- fields: [
215
- {name: 'new_field', displayName: 'New Field Name', type: 'number'}
216
- ]
217
- });
218
-
219
- // Delete a data structure
220
- await client.removeStructure('structure-id');
221
-
222
- // List all data structures
223
- const structures = await client.getStructures();
224
- ```
225
-
226
- ### Real-Time Synchronization
227
-
228
- ```typescript
229
- // Enable real-time sync (WebSocket connection is established automatically)
230
- client.setRealTimeSync(true);
231
-
232
- // Disable real-time sync
233
- client.setRealTimeSync(false);
234
-
235
- // Debug the socket connection state
236
- client.debugSocketConnection();
237
-
238
- // Get the client library version
239
- console.log(client.getVersion());
240
- ```
241
-
242
- ## Error Handling
243
-
244
- All API methods throw exceptions on failure. Use try/catch to handle errors:
245
-
246
- ```typescript
247
- try {
248
- const documents = await client.listDocuments();
249
- } catch (error) {
250
- if (error instanceof Error) {
251
- console.error(`API error: ${error.message}`);
252
- // error.message will be something like "API error: 401 Unauthorized"
253
- }
254
- }
255
- ```
256
-
257
- Authentication failures (HTTP 401/403) automatically clear the stored JWT token.
258
-
259
- ## API Reference
260
-
261
- ### Client Class
262
-
263
- #### Constructor
264
-
265
- - `new docPouchClient(host: string, port?: number, callback?: (event: I_EventString, data: I_WsMessage) => void)`
266
-
267
- #### Methods
268
-
269
- **Authentication & Session**
270
-
271
- - `login(credentials: I_UserLogin): Promise<I_LoginResponse | null>` — JWT login
272
- - `setToken(token: string | null): void` — Set or clear the JWT token
273
- - `getToken(): string | null` — Returns the active token (JWT or OIDC)
274
- - `getAuthMethod(): 'jwt' | 'oidc' | 'none'` — Returns current auth method
275
- - `isAuthenticated(): boolean` — Checks if the client is authenticated
276
- - `logout(): Promise<void>` — Clears all tokens and disconnects WebSocket
277
- - `getVersion(): string` — Returns the package version
278
-
279
- **OIDC Authentication**
280
-
281
- - `loginWithOidc(config: I_OidcConfig): Promise<void>` — Initiates OIDC authorization code flow (PKCE)
282
- - `handleOidcCallback(): Promise<boolean>` — Handles the OIDC redirect callback
283
- - `ensureValidOidcToken(): Promise<string>` — Returns a valid OIDC access token, refreshing if needed
284
-
285
- **OIDC Dynamic Client Registration**
286
-
287
- -
288
- `registerOidcClient(registration: I_OidcClientRegistration, registrationToken?: string): Promise<I_OidcClientResponse>`
289
- - `getOidcClient(clientId: string, registrationToken?: string): Promise<I_OidcClientResponse>`
290
- -
291
- `updateOidcClient(clientId: string, registration: I_OidcClientRegistration, registrationToken?: string): Promise<I_OidcClientResponse>`
292
- - `deleteOidcClient(clientId: string, registrationToken?: string): Promise<void>`
293
-
294
- **Real-Time Sync**
295
- - `setRealTimeSync(newRealTimeSync: boolean): void`
296
- - `debugSocketConnection(): void`
297
-
298
- **User Management**
299
- - `listUsers(): Promise<I_UserEntry[]>`
300
- - `updateUser(userID: string, userData: I_UserUpdate): Promise<void>`
301
- - `createUser(userData: I_UserCreation): Promise<I_UserDisplay>`
302
- - `removeUser(userID: string): Promise<void>`
303
-
304
- **Document Management**
305
- - `createDocument(document: I_DocumentEntry): Promise<I_DocumentEntry>`
306
- - `listDocuments(): Promise<I_DocumentEntry[]>`
307
- - `fetchDocuments(queryObject: I_DocumentQuery): Promise<I_DocumentEntry[]>`
308
- - `updateDocument(documentID: string, documentData: I_DocumentEntry): Promise<void>`
309
- - `removeDocument(documentID: string): Promise<void>`
310
-
311
- **Data Structure Management**
312
- - `createStructure(structure: I_StructureCreation): Promise<I_DataStructure>`
313
- - `getStructures(): Promise<I_DataStructure[]>`
314
- - `updateStructure(structureID: string, structureData: I_DataStructure): Promise<void>`
315
- - `removeStructure(structureID: string): Promise<void>`
316
-
317
- ## Types
318
-
319
- ### I_UserEntry
320
-
321
- ```typescript
322
- {
323
- _id: string;
324
- name: string;
325
- password: string;
326
- email?: string;
327
- department: string;
328
- group: string;
329
- isAdmin: boolean;
330
- }
331
- ```
332
-
333
- ### I_UserLogin
334
-
335
- ```typescript
336
- {
337
- name: string;
338
- password: string;
339
- }
340
- ```
341
-
342
- ### I_UserDisplay
343
-
344
- ```typescript
345
- {
346
- _id: string;
347
- username: string;
348
- department: string;
349
- group: string;
350
- email?: string;
351
- }
352
- ```
353
-
354
- ### I_UserCreation
355
-
356
- ```typescript
357
- {
358
- name: string;
359
- password: string;
360
- email?: string;
361
- department: string;
362
- group: string;
363
- isAdmin: boolean;
364
- }
365
- ```
366
-
367
- ### I_UserUpdate
368
-
369
- ```typescript
370
- {
371
- _id?: string;
372
- name?: string;
373
- password?: string;
374
- email?: string;
375
- department?: string;
376
- group?: string;
377
- isAdmin?: boolean;
378
- }
379
- ```
380
-
381
- ### I_LoginResponse
382
-
383
- ```typescript
384
- {
385
- _id: string;
386
- token?: string;
387
- isAdmin: boolean;
388
- userName: string;
389
- expiresIn?: number;
390
- }
391
- ```
392
-
393
- ### I_OidcConfig
394
-
395
- ```typescript
396
- {
397
- issuer: string;
398
- clientId: string;
399
- redirectUri: string;
400
- scopes?: string[];
401
- clientSecret?: string;
402
- }
403
- ```
404
-
405
- ### I_OidcTokenResponse
406
-
407
- ```typescript
408
- {
409
- accessToken: string;
410
- refreshToken?: string;
411
- idToken?: string;
412
- expiresIn: number;
413
- tokenType: string;
414
- scope: string;
415
- }
416
- ```
417
-
418
- ### I_OidcUserInfo
419
-
420
- ```typescript
421
- {
422
- sub: string;
423
- name?: string;
424
- email?: string;
425
- }
426
- ```
427
-
428
- ### I_OidcClientRegistration
429
-
430
- ```typescript
431
- {
432
- client_name: string;
433
- redirect_uris: string[];
434
- grant_types?: string[];
435
- response_types?: string[];
436
- scope?: string;
437
- token_endpoint_auth_method?: 'client_secret_basic' | 'client_secret_post' | 'none';
438
- application_type?: 'web' | 'native';
439
- logo_uri?: string;
440
- client_uri?: string;
441
- policy_uri?: string;
442
- tos_uri?: string;
443
- }
444
- ```
445
-
446
- ### I_OidcClientResponse
447
-
448
- ```typescript
449
- {
450
- client_id: string;
451
- client_secret?: string;
452
- client_secret_expires_at?: number;
453
- client_id_issued_at?: number;
454
- registration_access_token?: string;
455
- registration_client_uri?: string;
456
- client_name?: string;
457
- redirect_uris?: string[];
458
- grant_types?: string[];
459
- response_types?: string[];
460
- scope?: string;
461
- token_endpoint_auth_method?: string;
462
- }
463
- ```
464
-
465
- ### I_AuthState
466
-
467
- ```typescript
468
- {
469
- method: 'jwt' | 'oidc' | 'none';
470
- token: string | null;
471
- isAdmin: boolean;
472
- userName: string;
473
- }
474
- ```
475
-
476
- ### I_DocumentEntry
477
-
478
- ```typescript
479
- {
480
- _id: string;
481
- owner: string;
482
- title: string;
483
- description?: string;
484
- type: number;
485
- subType: number;
486
- content: any;
487
- shareWithGroup: boolean;
488
- shareWithDepartment: boolean;
489
- public: boolean;
490
- }
491
- ```
492
-
493
- ### I_DocumentCreation
494
-
495
- ```typescript
496
- {
497
- title: string;
498
- description?: string;
499
- type: number;
500
- subType: number;
501
- content: any;
502
- shareWithGroup: boolean;
503
- shareWithDepartment: boolean;
504
- public: boolean;
505
- }
506
- ```
507
-
508
- ### I_DocumentCreationOwned
509
-
510
- ```typescript
511
- {
512
- owner: string;
513
- title: string;
514
- description?: string;
515
- type: number;
516
- subType: number;
517
- content: any;
518
- shareWithGroup: boolean;
519
- shareWithDepartment: boolean;
520
- public: boolean;
521
- }
522
- ```
523
-
524
- ### I_DocumentUpdate
525
-
526
- ```typescript
527
- {
528
- _id?: string;
529
- owner?: string;
530
- title?: string;
531
- type?: number;
532
- subType?: number;
533
- shareWithGroup?: boolean;
534
- shareWithDepartment?: boolean;
535
- public?: boolean;
536
- content?: any;
537
- description?: string;
538
- }
539
- ```
540
-
541
- ### I_DocumentQuery
542
-
543
- ```typescript
544
- {
545
- _id?: string;
546
- owner?: string;
547
- title?: string;
548
- type?: number;
549
- subType?: number;
550
- shareWithGroup?: boolean;
551
- shareWithDepartment?: boolean;
552
- public?: boolean;
553
- }
554
- ```
555
-
556
- ### I_DataStructure
557
-
558
- ```typescript
559
- {
560
- _id?: string;
561
- name: string;
562
- description: string;
563
- type: number;
564
- subType: number;
565
- fields: I_StructureField[];
566
- }
567
- ```
568
-
569
- ### I_StructureCreation
570
-
571
- ```typescript
572
- {
573
- name: string;
574
- description?: string;
575
- fields: I_StructureField[];
576
- }
577
- ```
578
-
579
- ### I_StructureUpdate
580
-
581
- ```typescript
582
- {
583
- _id?: string;
584
- name?: string;
585
- description?: string;
586
- fields?: I_StructureField[];
587
- }
588
- ```
589
-
590
- ### I_StructureField
591
-
592
- ```typescript
593
- {
594
- name: string;
595
- displayName: string;
596
- type: string;
597
- items?: string;
598
- }
599
- ```
600
-
601
- ### I_EventString
602
-
603
- ```typescript
604
- 'heartbeatPong' | 'heartbeatPing' | 'newDocument' | 'newStructure' |
605
- 'newUser' | 'newType' | 'removedID' | 'changedDocument' |
606
- 'changedStructure' | 'changedUser' | 'changedType' | 'removedUser' |
607
- 'removedStructure' | 'removedDocument' | 'removedType'
608
- ```
609
-
610
- ### I_WsMessage
611
-
612
- ```typescript
613
- {
614
- newDocument?: I_DocumentEntry;
615
- newStructure?: I_DataStructure;
616
- newUser?: I_UserEntry;
617
- removedID?: string;
618
- changedDocument?: I_DocumentUpdate;
619
- changedStructure?: I_StructureUpdate;
620
- changedUser?: I_UserUpdate;
621
- confirmSubscription?: boolean;
622
- confirmUnsubscription?: boolean;
623
- heartbeatPing?: number;
624
- heartbeatPong?: number;
625
- }
626
- ```
627
-
628
- ## License
629
-
630
- [MIT](LICENSE)
1
+ # docpouch-client
2
+
3
+ A TypeScript client library for interacting with the [docPouch](https://github.com/BFH-JTF/doc-pouch) database API.
4
+ Supports JWT and OIDC (OpenID Connect) authentication.
5
+
6
+ ## Table of Contents
7
+
8
+ - [Description](#description)
9
+ - [Installation](#installation)
10
+ - [Usage](#usage)
11
+ - [Initializing the Client](#initializing-the-client)
12
+ - [JWT Authentication](#jwt-authentication)
13
+ - [OIDC Authentication](#oidc-authentication)
14
+ - [OIDC Dynamic Client Registration](#oidc-dynamic-client-registration)
15
+ - [User Management](#user-management)
16
+ - [Document Management](#document-management)
17
+ - [Data Structure Management](#data-structure-management)
18
+ - [Real-Time Synchronization](#real-time-synchronization)
19
+ - [Error Handling](#error-handling)
20
+ - [API Reference](#api-reference)
21
+ - [Types](#types)
22
+ - [License](#license)
23
+
24
+ ## Description
25
+
26
+ docpouch-client provides a simple and intuitive interface to access the docPouch API, allowing you to manage users,
27
+ documents, and data structures. It supports real-time synchronization via WebSockets and two authentication
28
+ methods: traditional JWT (username/password) and OpenID Connect (OIDC).
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ npm install docpouch-client
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ ### Initializing the Client
39
+
40
+ ```typescript
41
+ import docPouchClient from 'docpouch-client';
42
+
43
+ // Initialize the client with the server URL
44
+ const client = new docPouchClient('https://your-docpouch-server.com', 80);
45
+
46
+ // Initialize with a callback for real-time updates
47
+ const client = new docPouchClient('https://your-docpouch-server.com', 80,
48
+ (event, data) => {
49
+ console.log(`Received event: ${event}`, data);
50
+ }
51
+ );
52
+ ```
53
+
54
+ ### JWT Authentication
55
+
56
+ ```typescript
57
+ // Login to get an authentication token
58
+ const loginResponse = await client.login({
59
+ name: 'username',
60
+ password: 'password'
61
+ });
62
+
63
+ if (loginResponse) {
64
+ console.log('Login successful!');
65
+ console.log(`Token: ${loginResponse.token}`);
66
+ } else {
67
+ console.log('Login failed');
68
+ }
69
+
70
+ // Set an existing token
71
+ client.setToken('your-auth-token');
72
+
73
+ // Check authentication state
74
+ console.log(client.isAuthenticated()); // boolean
75
+ console.log(client.getAuthMethod()); // 'jwt' | 'oidc' | 'none'
76
+ console.log(client.getToken()); // string | null
77
+ ```
78
+
79
+ ### OIDC Authentication
80
+
81
+ ```typescript
82
+ // Initiate OIDC login (redirects the browser to the identity provider)
83
+ await client.loginWithOidc({
84
+ issuer: 'https://your-oidc-provider.com',
85
+ clientId: 'your-client-id',
86
+ redirectUri: 'https://yourapp.com/callback',
87
+ scopes: ['openid', 'profile', 'email']
88
+ });
89
+
90
+ // Handle the OIDC callback on your redirect page
91
+ const handled = await client.handleOidcCallback();
92
+ if (handled) {
93
+ console.log('OIDC login successful');
94
+ }
95
+
96
+ // The access token is automatically refreshed when needed
97
+ const validToken = await client.ensureValidOidcToken();
98
+
99
+ // Log out (clears tokens, disconnects WebSocket, cleans up URL params)
100
+ await client.logout();
101
+ ```
102
+
103
+ ### OIDC Dynamic Client Registration
104
+
105
+ ```typescript
106
+ // Register a new OIDC client
107
+ const registered = await client.registerOidcClient({
108
+ client_name: 'My Application',
109
+ redirect_uris: ['https://yourapp.com/callback'],
110
+ grant_types: ['authorization_code'],
111
+ response_types: ['code'],
112
+ token_endpoint_auth_method: 'client_secret_basic'
113
+ });
114
+ console.log(registered.client_id);
115
+
116
+ // Retrieve an existing client registration
117
+ const clientInfo = await client.getOidcClient('client-id');
118
+
119
+ // Update a client registration
120
+ await client.updateOidcClient('client-id', {
121
+ client_name: 'Updated Application Name'
122
+ });
123
+
124
+ // Delete a client registration
125
+ await client.deleteOidcClient('client-id');
126
+ ```
127
+
128
+ ### User Management
129
+
130
+ ```typescript
131
+ // List all users
132
+ const users = await client.listUsers();
133
+
134
+ // Create a new user
135
+ const newUser = await client.createUser({
136
+ name: 'newuser',
137
+ password: 'password',
138
+ department: 'IT',
139
+ group: 'Developers',
140
+ isAdmin: false
141
+ });
142
+
143
+ // Update a user
144
+ await client.updateUser('user-id', {
145
+ department: 'Engineering',
146
+ group: 'Frontend'
147
+ });
148
+
149
+ // Remove a user
150
+ await client.removeUser('user-id');
151
+ ```
152
+
153
+ ### Document Management
154
+
155
+ ```typescript
156
+ // Create a new document
157
+ const newDocument = await client.createDocument({
158
+ _id: 'document-id',
159
+ owner: 'user-id',
160
+ title: 'Mission Statement',
161
+ type: 17,
162
+ subType: 11,
163
+ content: '{"msg": "We strive for a world that..."}',
164
+ shareWithGroup: false,
165
+ shareWithDepartment: false,
166
+ public: false
167
+ });
168
+
169
+ // Update a document
170
+ await client.updateDocument('document-id', {
171
+ _id: 'document-id',
172
+ owner: 'user-id',
173
+ title: 'Updated Mission Statement',
174
+ type: 17,
175
+ subType: 11,
176
+ content: '{"msg": "Our updated mission..."}',
177
+ shareWithGroup: false,
178
+ shareWithDepartment: false,
179
+ public: false
180
+ });
181
+
182
+ // Delete a document
183
+ await client.removeDocument('document-id');
184
+
185
+ // List all documents
186
+ const allDocuments = await client.listDocuments();
187
+
188
+ // Fetch documents by query
189
+ const documents = await client.fetchDocuments({type: 17, subType: 11});
190
+ ```
191
+
192
+ ### Data Structure Management
193
+
194
+ ```typescript
195
+ // Create a new data structure
196
+ const newStructure = await client.createStructure({
197
+ name: "Data resulting from Vision-Mission-Value-Canvas",
198
+ fields: [
199
+ {
200
+ name: "mission_value_statement",
201
+ displayName: "Mission value statement",
202
+ type: "string"
203
+ },
204
+ ]
205
+ });
206
+
207
+ // Update a data structure
208
+ await client.updateStructure('structure-id', {
209
+ _id: 'structure-id',
210
+ name: 'Updated Structure Title',
211
+ description: 'Updated structure description',
212
+ type: 17,
213
+ subType: 11,
214
+ fields: [
215
+ {name: 'new_field', displayName: 'New Field Name', type: 'number'}
216
+ ]
217
+ });
218
+
219
+ // Delete a data structure
220
+ await client.removeStructure('structure-id');
221
+
222
+ // List all data structures
223
+ const structures = await client.getStructures();
224
+ ```
225
+
226
+ ### Real-Time Synchronization
227
+
228
+ ```typescript
229
+ // Enable real-time sync (WebSocket connection is established automatically)
230
+ client.setRealTimeSync(true);
231
+
232
+ // Disable real-time sync
233
+ client.setRealTimeSync(false);
234
+
235
+ // Debug the socket connection state
236
+ client.debugSocketConnection();
237
+
238
+ // Get the client library version
239
+ console.log(client.getVersion());
240
+ ```
241
+
242
+ ## Error Handling
243
+
244
+ All API methods throw exceptions on failure. Use try/catch to handle errors:
245
+
246
+ ```typescript
247
+ try {
248
+ const documents = await client.listDocuments();
249
+ } catch (error) {
250
+ if (error instanceof Error) {
251
+ console.error(`API error: ${error.message}`);
252
+ // error.message will be something like "API error: 401 Unauthorized"
253
+ }
254
+ }
255
+ ```
256
+
257
+ Authentication failures (HTTP 401/403) automatically clear the stored JWT token.
258
+
259
+ ## API Reference
260
+
261
+ ### Client Class
262
+
263
+ #### Constructor
264
+
265
+ - `new docPouchClient(host: string, port?: number, callback?: (event: I_EventString, data: I_WsMessage) => void)`
266
+
267
+ #### Methods
268
+
269
+ **Authentication & Session**
270
+
271
+ - `login(credentials: I_UserLogin): Promise<I_LoginResponse | null>` — JWT login
272
+ - `setToken(token: string | null): void` — Set or clear the JWT token
273
+ - `getToken(): string | null` — Returns the active token (JWT or OIDC)
274
+ - `getAuthMethod(): 'jwt' | 'oidc' | 'none'` — Returns current auth method
275
+ - `isAuthenticated(): boolean` — Checks if the client is authenticated
276
+ - `logout(): Promise<void>` — Clears all tokens and disconnects WebSocket
277
+ - `getVersion(): string` — Returns the package version
278
+
279
+ **OIDC Authentication**
280
+
281
+ - `loginWithOidc(config: I_OidcConfig): Promise<void>` — Initiates OIDC authorization code flow (PKCE)
282
+ - `handleOidcCallback(): Promise<boolean>` — Handles the OIDC redirect callback
283
+ - `ensureValidOidcToken(): Promise<string>` — Returns a valid OIDC access token, refreshing if needed
284
+
285
+ **OIDC Dynamic Client Registration**
286
+
287
+ -
288
+ `registerOidcClient(registration: I_OidcClientRegistration, registrationToken?: string): Promise<I_OidcClientResponse>`
289
+ - `getOidcClient(clientId: string, registrationToken?: string): Promise<I_OidcClientResponse>`
290
+ -
291
+ `updateOidcClient(clientId: string, registration: I_OidcClientRegistration, registrationToken?: string): Promise<I_OidcClientResponse>`
292
+ - `deleteOidcClient(clientId: string, registrationToken?: string): Promise<void>`
293
+
294
+ **Real-Time Sync**
295
+ - `setRealTimeSync(newRealTimeSync: boolean): void`
296
+ - `debugSocketConnection(): void`
297
+
298
+ **User Management**
299
+ - `listUsers(): Promise<I_UserEntry[]>`
300
+ - `updateUser(userID: string, userData: I_UserUpdate): Promise<void>`
301
+ - `createUser(userData: I_UserCreation): Promise<I_UserDisplay>`
302
+ - `removeUser(userID: string): Promise<void>`
303
+
304
+ **Document Management**
305
+ - `createDocument(document: I_DocumentEntry): Promise<I_DocumentEntry>`
306
+ - `listDocuments(): Promise<I_DocumentEntry[]>`
307
+ - `fetchDocuments(queryObject: I_DocumentQuery): Promise<I_DocumentEntry[]>`
308
+ - `updateDocument(documentID: string, documentData: I_DocumentEntry): Promise<void>`
309
+ - `removeDocument(documentID: string): Promise<void>`
310
+
311
+ **Data Structure Management**
312
+ - `createStructure(structure: I_StructureCreation): Promise<I_DataStructure>`
313
+ - `getStructures(): Promise<I_DataStructure[]>`
314
+ - `updateStructure(structureID: string, structureData: I_DataStructure): Promise<void>`
315
+ - `removeStructure(structureID: string): Promise<void>`
316
+
317
+ ## Types
318
+
319
+ ### I_UserEntry
320
+
321
+ ```typescript
322
+ {
323
+ _id: string;
324
+ name: string;
325
+ password: string;
326
+ email?: string;
327
+ department: string;
328
+ group: string;
329
+ isAdmin: boolean;
330
+ }
331
+ ```
332
+
333
+ ### I_UserLogin
334
+
335
+ ```typescript
336
+ {
337
+ name: string;
338
+ password: string;
339
+ }
340
+ ```
341
+
342
+ ### I_UserDisplay
343
+
344
+ ```typescript
345
+ {
346
+ _id: string;
347
+ username: string;
348
+ department: string;
349
+ group: string;
350
+ email?: string;
351
+ }
352
+ ```
353
+
354
+ ### I_UserCreation
355
+
356
+ ```typescript
357
+ {
358
+ name: string;
359
+ password: string;
360
+ email?: string;
361
+ department: string;
362
+ group: string;
363
+ isAdmin: boolean;
364
+ }
365
+ ```
366
+
367
+ ### I_UserUpdate
368
+
369
+ ```typescript
370
+ {
371
+ _id?: string;
372
+ name?: string;
373
+ password?: string;
374
+ email?: string;
375
+ department?: string;
376
+ group?: string;
377
+ isAdmin?: boolean;
378
+ }
379
+ ```
380
+
381
+ ### I_LoginResponse
382
+
383
+ ```typescript
384
+ {
385
+ _id: string;
386
+ token?: string;
387
+ isAdmin: boolean;
388
+ userName: string;
389
+ expiresIn?: number;
390
+ }
391
+ ```
392
+
393
+ ### I_OidcConfig
394
+
395
+ ```typescript
396
+ {
397
+ issuer: string;
398
+ clientId: string;
399
+ redirectUri: string;
400
+ scopes?: string[];
401
+ clientSecret?: string;
402
+ }
403
+ ```
404
+
405
+ ### I_OidcTokenResponse
406
+
407
+ ```typescript
408
+ {
409
+ accessToken: string;
410
+ refreshToken?: string;
411
+ idToken?: string;
412
+ expiresIn: number;
413
+ tokenType: string;
414
+ scope: string;
415
+ }
416
+ ```
417
+
418
+ ### I_OidcUserInfo
419
+
420
+ ```typescript
421
+ {
422
+ sub: string;
423
+ name?: string;
424
+ email?: string;
425
+ }
426
+ ```
427
+
428
+ ### I_OidcClientRegistration
429
+
430
+ ```typescript
431
+ {
432
+ client_name: string;
433
+ redirect_uris: string[];
434
+ grant_types?: string[];
435
+ response_types?: string[];
436
+ scope?: string;
437
+ token_endpoint_auth_method?: 'client_secret_basic' | 'client_secret_post' | 'none';
438
+ application_type?: 'web' | 'native';
439
+ logo_uri?: string;
440
+ client_uri?: string;
441
+ policy_uri?: string;
442
+ tos_uri?: string;
443
+ }
444
+ ```
445
+
446
+ ### I_OidcClientResponse
447
+
448
+ ```typescript
449
+ {
450
+ client_id: string;
451
+ client_secret?: string;
452
+ client_secret_expires_at?: number;
453
+ client_id_issued_at?: number;
454
+ registration_access_token?: string;
455
+ registration_client_uri?: string;
456
+ client_name?: string;
457
+ redirect_uris?: string[];
458
+ grant_types?: string[];
459
+ response_types?: string[];
460
+ scope?: string;
461
+ token_endpoint_auth_method?: string;
462
+ }
463
+ ```
464
+
465
+ ### I_AuthState
466
+
467
+ ```typescript
468
+ {
469
+ method: 'jwt' | 'oidc' | 'none';
470
+ token: string | null;
471
+ isAdmin: boolean;
472
+ userName: string;
473
+ }
474
+ ```
475
+
476
+ ### I_DocumentEntry
477
+
478
+ ```typescript
479
+ {
480
+ _id: string;
481
+ owner: string;
482
+ title: string;
483
+ description?: string;
484
+ type: number;
485
+ subType: number;
486
+ content: any;
487
+ shareWithGroup: boolean;
488
+ shareWithDepartment: boolean;
489
+ public: boolean;
490
+ }
491
+ ```
492
+
493
+ ### I_DocumentCreation
494
+
495
+ ```typescript
496
+ {
497
+ title: string;
498
+ description?: string;
499
+ type: number;
500
+ subType: number;
501
+ content: any;
502
+ shareWithGroup: boolean;
503
+ shareWithDepartment: boolean;
504
+ public: boolean;
505
+ }
506
+ ```
507
+
508
+ ### I_DocumentCreationOwned
509
+
510
+ ```typescript
511
+ {
512
+ owner: string;
513
+ title: string;
514
+ description?: string;
515
+ type: number;
516
+ subType: number;
517
+ content: any;
518
+ shareWithGroup: boolean;
519
+ shareWithDepartment: boolean;
520
+ public: boolean;
521
+ }
522
+ ```
523
+
524
+ ### I_DocumentUpdate
525
+
526
+ ```typescript
527
+ {
528
+ _id?: string;
529
+ owner?: string;
530
+ title?: string;
531
+ type?: number;
532
+ subType?: number;
533
+ shareWithGroup?: boolean;
534
+ shareWithDepartment?: boolean;
535
+ public?: boolean;
536
+ content?: any;
537
+ description?: string;
538
+ }
539
+ ```
540
+
541
+ ### I_DocumentQuery
542
+
543
+ ```typescript
544
+ {
545
+ _id?: string;
546
+ owner?: string;
547
+ title?: string;
548
+ type?: number;
549
+ subType?: number;
550
+ shareWithGroup?: boolean;
551
+ shareWithDepartment?: boolean;
552
+ public?: boolean;
553
+ }
554
+ ```
555
+
556
+ ### I_DataStructure
557
+
558
+ ```typescript
559
+ {
560
+ _id?: string;
561
+ name: string;
562
+ description: string;
563
+ type: number;
564
+ subType: number;
565
+ fields: I_StructureField[];
566
+ }
567
+ ```
568
+
569
+ ### I_StructureCreation
570
+
571
+ ```typescript
572
+ {
573
+ name: string;
574
+ description?: string;
575
+ fields: I_StructureField[];
576
+ }
577
+ ```
578
+
579
+ ### I_StructureUpdate
580
+
581
+ ```typescript
582
+ {
583
+ _id?: string;
584
+ name?: string;
585
+ description?: string;
586
+ fields?: I_StructureField[];
587
+ }
588
+ ```
589
+
590
+ ### I_StructureField
591
+
592
+ ```typescript
593
+ {
594
+ name: string;
595
+ displayName: string;
596
+ type: string;
597
+ items?: string;
598
+ }
599
+ ```
600
+
601
+ ### I_EventString
602
+
603
+ ```typescript
604
+ 'heartbeatPong' | 'heartbeatPing' | 'newDocument' | 'newStructure' |
605
+ 'newUser' | 'newType' | 'removedID' | 'changedDocument' |
606
+ 'changedStructure' | 'changedUser' | 'changedType' | 'removedUser' |
607
+ 'removedStructure' | 'removedDocument' | 'removedType'
608
+ ```
609
+
610
+ ### I_WsMessage
611
+
612
+ ```typescript
613
+ {
614
+ newDocument?: I_DocumentEntry;
615
+ newStructure?: I_DataStructure;
616
+ newUser?: I_UserEntry;
617
+ removedID?: string;
618
+ changedDocument?: I_DocumentUpdate;
619
+ changedStructure?: I_StructureUpdate;
620
+ changedUser?: I_UserUpdate;
621
+ confirmSubscription?: boolean;
622
+ confirmUnsubscription?: boolean;
623
+ heartbeatPing?: number;
624
+ heartbeatPong?: number;
625
+ }
626
+ ```
627
+
628
+ ## License
629
+
630
+ [MIT](LICENSE)