docpouch-client 0.8.7 → 0.8.9

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/dist/index.d.ts CHANGED
@@ -178,7 +178,7 @@ export interface I_StructureCreation {
178
178
  fields: I_StructureField[];
179
179
  }
180
180
  export interface I_StructureUpdate {
181
- _id: string;
181
+ _id?: string;
182
182
  name?: string;
183
183
  description?: string;
184
184
  fields?: I_StructureField[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docpouch-client",
3
- "version": "0.8.7",
3
+ "version": "0.8.9",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {
package/src/index.ts CHANGED
@@ -388,7 +388,7 @@ export default class docPouchClient {
388
388
  // Common type definitions for both frontend and backend
389
389
 
390
390
  // User related types
391
- export interface I_UserEntry extends I_UserCreation{
391
+ export interface I_UserEntry extends I_UserCreation {
392
392
  _id: string;
393
393
  }
394
394
 
@@ -431,7 +431,7 @@ export interface I_LoginResponse {
431
431
  }
432
432
 
433
433
  // Document related types
434
- export interface I_DocumentEntry extends I_DocumentCreationOwned{
434
+ export interface I_DocumentEntry extends I_DocumentCreationOwned {
435
435
  _id: string;
436
436
  }
437
437
 
@@ -450,7 +450,7 @@ export interface I_DocumentCreationOwned extends I_DocumentCreation {
450
450
  owner: string;
451
451
  }
452
452
 
453
- export interface I_DocumentUpdate extends I_DocumentQuery{
453
+ export interface I_DocumentUpdate extends I_DocumentQuery {
454
454
  _id: string;
455
455
  content?: any;
456
456
  description?: string;
@@ -496,7 +496,7 @@ export interface I_StructureCreation {
496
496
  }
497
497
 
498
498
  export interface I_StructureUpdate {
499
- _id: string;
499
+ _id?: string;
500
500
  name?: string;
501
501
  description?: string;
502
502
  fields?: I_StructureField[];
package/tsconfig.json CHANGED
@@ -17,5 +17,9 @@
17
17
  "allowSyntheticDefaultImports": true
18
18
  },
19
19
  "include": ["**/*.ts", "**/*.tsx"],
20
- "exclude": ["node_modules", "**/*.test.ts", "./dist/**/*"]
20
+ "exclude": [
21
+ "node_modules",
22
+ "**/*.test.ts",
23
+ "./dist/**/*"
24
+ ]
21
25
  }
@@ -1,489 +0,0 @@
1
- import docPouchClient from '../index.js';
2
- import packetJson from '../../package.json';
3
- import {
4
- I_UserLogin,
5
- I_UserCreation,
6
- I_UserUpdate,
7
- I_DocumentEntry,
8
- I_DocumentQuery,
9
- I_StructureCreation,
10
- I_DataStructure,
11
- } from '../types.js';
12
-
13
- // Mock socket.io-client
14
- jest.mock('socket.io-client', () => {
15
- const mockSocket = {
16
- connect: jest.fn(),
17
- emit: jest.fn(),
18
- onAny: jest.fn(),
19
- };
20
- return {
21
- io: jest.fn(() => mockSocket),
22
- Socket: jest.requireActual('socket.io-client').Socket,
23
- };
24
- });
25
-
26
- // Mock fetch API
27
- global.fetch = jest.fn();
28
- const mockFetch = global.fetch as jest.Mock;
29
-
30
- describe('Index Class', () => {
31
- let index: docPouchClient;
32
- const baseUrl = 'http://example.com';
33
-
34
- beforeEach(() => {
35
- // Reset mocks before each test
36
- jest.clearAllMocks();
37
- mockFetch.mockClear();
38
-
39
- // Create a new instance of Index for each test
40
- index = new docPouchClient(baseUrl);
41
-
42
- // Mock successful fetch response
43
- mockFetch.mockImplementation(() =>
44
- Promise.resolve({
45
- ok: true,
46
- status: 200,
47
- statusText: 'OK',
48
- json: () => Promise.resolve({}),
49
- })
50
- );
51
- });
52
-
53
- // Test constructor
54
- describe('constructor', () => {
55
- it('should initialize with the provided baseUrl', () => {
56
- expect(index.baseUrl).toBe(baseUrl);
57
- });
58
-
59
- it('should initialize socket with autoConnect: false by default', () => {
60
- expect(require('socket.io-client').io).toHaveBeenCalledWith(baseUrl, { autoConnect: false });
61
- });
62
-
63
- it('should connect socket and set up event handler when callback is provided', () => {
64
- const mockCallback = jest.fn();
65
- const indexWithCallback = new docPouchClient(baseUrl, mockCallback);
66
-
67
- expect(indexWithCallback.socket.connect).toHaveBeenCalled();
68
- expect(indexWithCallback.socket.onAny).toHaveBeenCalled();
69
- });
70
- });
71
-
72
- // Test utility methods
73
- describe('utility methods', () => {
74
- it('should set and get token correctly', () => {
75
- const token = 'test-token';
76
- index.setToken(token);
77
- expect(index.getToken()).toBe(token);
78
- });
79
-
80
- it('should return null when token is not set', () => {
81
- expect(index.getToken()).toBeNull();
82
- });
83
-
84
- it('should return the correct version', () => {
85
- // Mock package.json
86
- jest.mock('../../package.json', () => ({ version: packetJson.version }), { virtual: true });
87
-
88
- // We need to re-create the index instance to pick up the mocked package.json
89
- const newIndex = new docPouchClient(baseUrl);
90
- expect(newIndex.getVersion()).toBe(packetJson.version);
91
- });
92
- });
93
-
94
- // Test user administration endpoints
95
- describe('user administration endpoints', () => {
96
- it('should login successfully and store token', async () => {
97
- const credentials: I_UserLogin = { name: 'testuser', password: 'password' };
98
- const mockResponse = { token: 'test-token', isAdmin: true };
99
-
100
- mockFetch.mockImplementationOnce(() =>
101
- Promise.resolve({
102
- ok: true,
103
- status: 200,
104
- statusText: 'OK',
105
- json: () => Promise.resolve(mockResponse),
106
- })
107
- );
108
-
109
- const result = await index.login(credentials);
110
-
111
- expect(mockFetch).toHaveBeenCalledWith(
112
- `${baseUrl}/users/login`,
113
- expect.objectContaining({
114
- method: 'POST',
115
- body: JSON.stringify(credentials),
116
- })
117
- );
118
- expect(result).toEqual(mockResponse);
119
- expect(index.getToken()).toBe('test-token');
120
- });
121
-
122
- it('should return null when login fails', async () => {
123
- const credentials: I_UserLogin = { name: 'testuser', password: 'wrong-password' };
124
-
125
- mockFetch.mockImplementationOnce(() =>
126
- Promise.resolve({
127
- ok: true,
128
- status: 200,
129
- statusText: 'OK',
130
- json: () => Promise.resolve({}),
131
- })
132
- );
133
-
134
- const result = await index.login(credentials);
135
-
136
- expect(result).toBeNull();
137
- });
138
-
139
- it('should list users', async () => {
140
- const mockUsers = [{ _id: '1', name: 'user1', password: 'pass1', department: 'dept1', group: 'group1', isAdmin: false }];
141
-
142
- mockFetch.mockImplementationOnce(() =>
143
- Promise.resolve({
144
- ok: true,
145
- status: 200,
146
- statusText: 'OK',
147
- json: () => Promise.resolve(mockUsers),
148
- })
149
- );
150
-
151
- const result = await index.listUsers();
152
-
153
- expect(mockFetch).toHaveBeenCalledWith(
154
- `${baseUrl}/users/list`,
155
- expect.objectContaining({
156
- method: 'GET',
157
- })
158
- );
159
- expect(result).toEqual(mockUsers);
160
- });
161
-
162
- it('should update a user', async () => {
163
- const userId = '1';
164
- const userData: I_UserUpdate = { name: 'updated-user', department: 'new-dept' };
165
-
166
- await index.updateUser(userId, userData);
167
-
168
- expect(mockFetch).toHaveBeenCalledWith(
169
- `${baseUrl}/users/update/${userId}`,
170
- expect.objectContaining({
171
- method: 'PATCH',
172
- body: JSON.stringify(userData),
173
- })
174
- );
175
- });
176
-
177
- it('should create a user', async () => {
178
- const userData: I_UserCreation = {
179
- name: 'newuser',
180
- password: 'password',
181
- department: 'dept',
182
- group: 'group',
183
- isAdmin: false
184
- };
185
- const mockResponse = { _id: '2', username: 'newuser', department: 'dept', group: 'group' };
186
-
187
- mockFetch.mockImplementationOnce(() =>
188
- Promise.resolve({
189
- ok: true,
190
- status: 200,
191
- statusText: 'OK',
192
- json: () => Promise.resolve(mockResponse),
193
- })
194
- );
195
-
196
- const result = await index.createUser(userData);
197
-
198
- expect(mockFetch).toHaveBeenCalledWith(
199
- `${baseUrl}/users/create`,
200
- expect.objectContaining({
201
- method: 'POST',
202
- body: JSON.stringify(userData),
203
- })
204
- );
205
- expect(result).toEqual(mockResponse);
206
- });
207
-
208
- it('should remove a user', async () => {
209
- const userId = '1';
210
-
211
- await index.removeUser(userId);
212
-
213
- expect(mockFetch).toHaveBeenCalledWith(
214
- `${baseUrl}/users/remove/${userId}`,
215
- expect.objectContaining({
216
- method: 'DELETE',
217
- })
218
- );
219
- });
220
- });
221
-
222
- // Test document management endpoints
223
- describe('document management endpoints', () => {
224
- it('should create a document', async () => {
225
- const document: I_DocumentEntry = {
226
- _id: '1',
227
- title: 'Test Document',
228
- type: 1,
229
- subType: 2,
230
- content: { data: 'test content' },
231
- owner: 'user1'
232
- };
233
-
234
- mockFetch.mockImplementationOnce(() =>
235
- Promise.resolve({
236
- ok: true,
237
- status: 200,
238
- statusText: 'OK',
239
- json: () => Promise.resolve(document),
240
- })
241
- );
242
-
243
- const result = await index.createDocument(document);
244
-
245
- expect(mockFetch).toHaveBeenCalledWith(
246
- `${baseUrl}/docs/create`,
247
- expect.objectContaining({
248
- method: 'POST',
249
- body: JSON.stringify(document),
250
- })
251
- );
252
- expect(result).toEqual(document);
253
- });
254
-
255
- it('should list documents', async () => {
256
- const mockDocuments = [
257
- { _id: '1', title: 'Doc1', type: 1, subType: 1, content: {}, owner: 'user1' },
258
- { _id: '2', title: 'Doc2', type: 2, subType: 2, content: {}, owner: 'user2' }
259
- ];
260
-
261
- mockFetch.mockImplementationOnce(() =>
262
- Promise.resolve({
263
- ok: true,
264
- status: 200,
265
- statusText: 'OK',
266
- json: () => Promise.resolve(mockDocuments),
267
- })
268
- );
269
-
270
- const result = await index.listDocuments();
271
-
272
- expect(mockFetch).toHaveBeenCalledWith(
273
- `${baseUrl}/docs/list`,
274
- expect.objectContaining({
275
- method: 'GET',
276
- })
277
- );
278
- expect(result).toEqual(mockDocuments);
279
- });
280
-
281
- it('should fetch documents based on query', async () => {
282
- const query: I_DocumentQuery = { type: 1, owner: 'user1' };
283
- const mockDocuments = [
284
- { _id: '1', title: 'Doc1', type: 1, subType: 1, content: {}, owner: 'user1' }
285
- ];
286
-
287
- mockFetch.mockImplementationOnce(() =>
288
- Promise.resolve({
289
- ok: true,
290
- status: 200,
291
- statusText: 'OK',
292
- json: () => Promise.resolve(mockDocuments),
293
- })
294
- );
295
-
296
- const result = await index.fetchDocument(query);
297
-
298
- expect(mockFetch).toHaveBeenCalledWith(
299
- `${baseUrl}/docs/fetch/`,
300
- expect.objectContaining({
301
- method: 'POST',
302
- body: JSON.stringify(query),
303
- })
304
- );
305
- expect(result).toEqual(mockDocuments);
306
- });
307
-
308
- it('should update a document', async () => {
309
- const documentId = '1';
310
- const documentData: I_DocumentEntry = {
311
- _id: '1',
312
- title: 'Updated Document',
313
- type: 1,
314
- subType: 2,
315
- content: { data: 'updated content' },
316
- owner: 'user1'
317
- };
318
-
319
- await index.updateDocument(documentId, documentData);
320
-
321
- expect(mockFetch).toHaveBeenCalledWith(
322
- `${baseUrl}/docs/update/${documentId}`,
323
- expect.objectContaining({
324
- method: 'PATCH',
325
- body: JSON.stringify(documentData),
326
- })
327
- );
328
- });
329
-
330
- it('should remove a document', async () => {
331
- const documentId = '1';
332
-
333
- await index.removeDocument(documentId);
334
-
335
- expect(mockFetch).toHaveBeenCalledWith(
336
- `${baseUrl}/docs/remove/${documentId}`,
337
- expect.objectContaining({
338
- method: 'DELETE',
339
- })
340
- );
341
- });
342
- });
343
-
344
- // Test data structure endpoints
345
- describe('data structure endpoints', () => {
346
- it('should create a structure', async () => {
347
- const structure: I_StructureCreation = {
348
- name: 'Test Structure',
349
- description: 'Test Description',
350
- fields: [{ name: 'field1', type: 'string' }]
351
- };
352
- const mockResponse: I_DataStructure = {
353
- _id: '1',
354
- name: 'Test Structure',
355
- description: 'Test Description',
356
- fields: [{ name: 'field1', type: 'string' }]
357
- };
358
-
359
- mockFetch.mockImplementationOnce(() =>
360
- Promise.resolve({
361
- ok: true,
362
- status: 200,
363
- statusText: 'OK',
364
- json: () => Promise.resolve(mockResponse),
365
- })
366
- );
367
-
368
- const result = await index.createStructure(structure);
369
-
370
- expect(mockFetch).toHaveBeenCalledWith(
371
- `${baseUrl}/structures/create`,
372
- expect.objectContaining({
373
- method: 'POST',
374
- body: JSON.stringify(structure),
375
- })
376
- );
377
- expect(result).toEqual(mockResponse);
378
- });
379
-
380
- it('should get structures', async () => {
381
- const mockStructures = [
382
- { _id: '1', name: 'Structure1', description: 'Desc1', fields: [] },
383
- { _id: '2', name: 'Structure2', description: 'Desc2', fields: [] }
384
- ];
385
-
386
- mockFetch.mockImplementationOnce(() =>
387
- Promise.resolve({
388
- ok: true,
389
- status: 200,
390
- statusText: 'OK',
391
- json: () => Promise.resolve(mockStructures),
392
- })
393
- );
394
-
395
- const result = await index.getStructures();
396
-
397
- expect(mockFetch).toHaveBeenCalledWith(
398
- `${baseUrl}/structures/list`,
399
- expect.objectContaining({
400
- method: 'GET',
401
- })
402
- );
403
- expect(result).toEqual(mockStructures);
404
- });
405
-
406
- it('should update a structure', async () => {
407
- const structureId = '1';
408
- const structureData: I_DataStructure = {
409
- name: 'Updated Structure',
410
- description: 'Updated Description',
411
- fields: [{ name: 'updatedField', type: 'number' }]
412
- };
413
-
414
- await index.updateStructure(structureId, structureData);
415
-
416
- expect(mockFetch).toHaveBeenCalledWith(
417
- `${baseUrl}/structures/update/${structureId}`,
418
- expect.objectContaining({
419
- method: 'PATCH',
420
- body: JSON.stringify(structureData),
421
- })
422
- );
423
- });
424
-
425
- it('should remove a structure', async () => {
426
- const structureId = '1';
427
-
428
- await index.removeStructure(structureId);
429
-
430
- expect(mockFetch).toHaveBeenCalledWith(
431
- `${baseUrl}/structures/remove/${structureId}`,
432
- expect.objectContaining({
433
- method: 'DELETE',
434
- })
435
- );
436
- });
437
- });
438
-
439
- // Test error handling
440
- describe('error handling', () => {
441
- it('should throw an error when API request fails', async () => {
442
- mockFetch.mockImplementationOnce(() =>
443
- Promise.resolve({
444
- ok: false,
445
- status: 500,
446
- statusText: 'Internal Server Error',
447
- })
448
- );
449
-
450
- await expect(index.listUsers()).rejects.toThrow('API error: 500 Internal Server Error');
451
- });
452
-
453
- it('should clear token when receiving 401 or 403 status', async () => {
454
- // Set a token first
455
- index.setToken('test-token');
456
-
457
- // Mock 401 response
458
- mockFetch.mockImplementationOnce(() =>
459
- Promise.resolve({
460
- ok: false,
461
- status: 401,
462
- statusText: 'Unauthorized',
463
- })
464
- );
465
-
466
- await expect(index.listUsers()).rejects.toThrow('API error: 401 Unauthorized');
467
- expect(index.getToken()).toBeNull();
468
- });
469
- });
470
-
471
- // Test WebSocket functionality
472
- describe('WebSocket functionality', () => {
473
- it('should connect socket when callback is provided', () => {
474
- const mockCallback = jest.fn();
475
- const indexWithCallback = new docPouchClient(baseUrl, mockCallback);
476
-
477
- // Verify that connect was called
478
- expect(indexWithCallback.socket.connect).toHaveBeenCalled();
479
- });
480
-
481
- it('should set up event handler when callback is provided', () => {
482
- const mockCallback = jest.fn();
483
- const indexWithCallback = new docPouchClient(baseUrl, mockCallback);
484
-
485
- // Verify that onAny was called
486
- expect(indexWithCallback.socket.onAny).toHaveBeenCalled();
487
- });
488
- });
489
- });