tm1npm 1.6.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/lib/services/ApplicationService.d.ts.map +1 -1
  3. package/lib/services/AsyncOperationService.d.ts +8 -1
  4. package/lib/services/AsyncOperationService.d.ts.map +1 -1
  5. package/lib/services/AsyncOperationService.js +69 -26
  6. package/lib/services/FileService.d.ts.map +1 -1
  7. package/lib/services/ProcessService.d.ts +18 -13
  8. package/lib/services/ProcessService.d.ts.map +1 -1
  9. package/lib/services/ProcessService.js +28 -17
  10. package/lib/services/RestService.d.ts +213 -25
  11. package/lib/services/RestService.d.ts.map +1 -1
  12. package/lib/services/RestService.js +840 -271
  13. package/lib/services/TM1Service.d.ts +42 -1
  14. package/lib/services/TM1Service.d.ts.map +1 -1
  15. package/lib/services/TM1Service.js +94 -4
  16. package/lib/tests/asyncOperationService.test.js +51 -45
  17. package/lib/tests/processService.comprehensive.test.js +2 -2
  18. package/lib/tests/processService.test.js +20 -6
  19. package/lib/tests/restService.test.d.ts +0 -4
  20. package/lib/tests/restService.test.d.ts.map +1 -1
  21. package/lib/tests/restService.test.js +1558 -143
  22. package/lib/tests/tm1Service.test.js +80 -8
  23. package/package.json +1 -1
  24. package/src/services/ApplicationService.ts +4 -4
  25. package/src/services/AsyncOperationService.ts +76 -29
  26. package/src/services/FileService.ts +3 -3
  27. package/src/services/ProcessService.ts +67 -37
  28. package/src/services/RestService.ts +1020 -278
  29. package/src/services/TM1Service.ts +124 -6
  30. package/src/tests/asyncOperationService.test.ts +52 -48
  31. package/src/tests/processService.comprehensive.test.ts +3 -3
  32. package/src/tests/processService.test.ts +21 -9
  33. package/src/tests/restService.test.ts +1844 -139
  34. package/src/tests/tm1Service.test.ts +95 -11
@@ -6,6 +6,7 @@
6
6
 
7
7
  import { TM1Service } from '../services/TM1Service';
8
8
  import { RestService, RestServiceConfig } from '../services/RestService';
9
+ import { User, UserType } from '../objects/User';
9
10
 
10
11
  // Mock all service dependencies
11
12
  jest.mock('../services/RestService');
@@ -22,6 +23,19 @@ jest.mock('../services/FileService');
22
23
  jest.mock('../services/SessionService');
23
24
  jest.mock('../services/ServerService');
24
25
  jest.mock('../services/MonitoringService');
26
+ jest.mock('../services/AnnotationService');
27
+ jest.mock('../services/ChoreService');
28
+ jest.mock('../services/GitService');
29
+ jest.mock('../services/ApplicationService');
30
+ jest.mock('../services/SandboxService');
31
+ jest.mock('../services/JobService');
32
+ jest.mock('../services/UserService');
33
+ jest.mock('../services/ThreadService');
34
+ jest.mock('../services/TransactionLogService');
35
+ jest.mock('../services/MessageLogService');
36
+ jest.mock('../services/ConfigurationService');
37
+ jest.mock('../services/AuditLogService');
38
+ jest.mock('../services/LoggerService');
25
39
 
26
40
  describe('TM1Service', () => {
27
41
  let tm1Service: TM1Service;
@@ -61,6 +75,8 @@ describe('TM1Service', () => {
61
75
  setSandbox: jest.fn(),
62
76
  getSandbox: jest.fn().mockReturnValue('test-sandbox'),
63
77
  isLoggedIn: jest.fn().mockReturnValue(true),
78
+ getVersion: jest.fn().mockResolvedValue('12.0.0'),
79
+ version: undefined,
64
80
  } as any;
65
81
 
66
82
  // Mock RestService constructor
@@ -83,6 +99,7 @@ describe('TM1Service', () => {
83
99
  expect(tm1Service.security).toBeDefined();
84
100
  expect(tm1Service.files).toBeDefined();
85
101
  expect(tm1Service.sessions).toBeDefined();
102
+ expect(tm1Service.applications).toBeDefined();
86
103
  });
87
104
 
88
105
  test('should create RestService with provided config', () => {
@@ -145,16 +162,18 @@ describe('TM1Service', () => {
145
162
  });
146
163
 
147
164
  describe('User and Authentication', () => {
148
- test('should get current user with whoami', async () => {
149
- // Mock security service getCurrentUser method
165
+ test('should get current user as User object with whoami', async () => {
166
+ const expectedUser = new User('test-user', ['ADMIN'], 'Test User', undefined, UserType.Admin, true);
150
167
  const mockSecurityService = {
151
- getCurrentUser: jest.fn().mockResolvedValue({ name: 'test-user' })
168
+ getCurrentUser: jest.fn().mockResolvedValue(expectedUser)
152
169
  };
153
170
  (tm1Service.security as any) = mockSecurityService;
154
171
 
155
172
  const result = await tm1Service.whoami();
156
-
157
- expect(result).toBe('test-user');
173
+
174
+ expect(result).toBeInstanceOf(User);
175
+ expect(result.name).toBe('test-user');
176
+ expect(result).toBe(expectedUser);
158
177
  expect(mockSecurityService.getCurrentUser).toHaveBeenCalledTimes(1);
159
178
  });
160
179
 
@@ -175,10 +194,11 @@ describe('TM1Service', () => {
175
194
 
176
195
  test('should re-authenticate successfully', async () => {
177
196
  await tm1Service.reAuthenticate();
178
-
197
+
179
198
  expect(mockRestService.disconnect).toHaveBeenCalledTimes(1);
180
199
  expect(mockRestService.connect).toHaveBeenCalledTimes(1);
181
200
  });
201
+
182
202
  });
183
203
 
184
204
  describe('Metadata and Version', () => {
@@ -191,13 +211,13 @@ describe('TM1Service', () => {
191
211
  expect(mockRestService.get).toHaveBeenCalledWith('/$metadata');
192
212
  });
193
213
 
194
- test('should get TM1 version', async () => {
195
- mockRestService.get.mockResolvedValueOnce(mockResponse({ value: '12.0.0' }));
214
+ test('should get TM1 version via cached RestService.getVersion', async () => {
215
+ mockRestService.getVersion.mockResolvedValueOnce('12.0.0');
196
216
 
197
217
  const result = await tm1Service.getVersion();
198
-
218
+
199
219
  expect(result).toBe('12.0.0');
200
- expect(mockRestService.get).toHaveBeenCalledWith('/Configuration/ProductVersion');
220
+ expect(mockRestService.getVersion).toHaveBeenCalledTimes(1);
201
221
  });
202
222
 
203
223
  test('should handle metadata retrieval errors', async () => {
@@ -209,7 +229,7 @@ describe('TM1Service', () => {
209
229
 
210
230
  test('should handle version retrieval errors', async () => {
211
231
  const versionError = new Error('Version not available');
212
- mockRestService.get.mockRejectedValueOnce(versionError);
232
+ mockRestService.getVersion.mockRejectedValueOnce(versionError);
213
233
 
214
234
  await expect(tm1Service.getVersion()).rejects.toThrow('Version not available');
215
235
  });
@@ -358,4 +378,68 @@ describe('TM1Service', () => {
358
378
  expect(monitoring1).toBe(monitoring2);
359
379
  });
360
380
  });
381
+
382
+ describe('Lazy Services (Issue #82)', () => {
383
+ const lazyServiceNames: Array<keyof TM1Service> = [
384
+ 'annotations',
385
+ 'chores',
386
+ 'git',
387
+ 'sandboxes',
388
+ 'jobs',
389
+ 'users',
390
+ 'threads',
391
+ 'transactionLogs',
392
+ 'messageLogs',
393
+ 'configuration',
394
+ 'auditLogs',
395
+ 'loggers',
396
+ ];
397
+
398
+ test.each(lazyServiceNames)('should lazy-initialize %s service', (serviceName) => {
399
+ const instance = tm1Service[serviceName];
400
+ expect(instance).toBeDefined();
401
+ });
402
+
403
+ test.each(lazyServiceNames)('should cache %s service instance across accesses', (serviceName) => {
404
+ const first = tm1Service[serviceName];
405
+ const second = tm1Service[serviceName];
406
+ expect(second).toBe(first);
407
+ });
408
+ });
409
+
410
+ describe('Version Getter (Issue #82)', () => {
411
+ test('should expose cached version via sync getter', () => {
412
+ Object.defineProperty(mockRestService, 'version', {
413
+ get: () => '11.8.0',
414
+ configurable: true,
415
+ });
416
+
417
+ expect(tm1Service.version).toBe('11.8.0');
418
+ });
419
+
420
+ test('should return undefined when version has not been fetched yet', () => {
421
+ Object.defineProperty(mockRestService, 'version', {
422
+ get: () => undefined,
423
+ configurable: true,
424
+ });
425
+
426
+ expect(tm1Service.version).toBeUndefined();
427
+ });
428
+ });
429
+
430
+ describe('reConnect (Issue #82)', () => {
431
+ test('should call connect without disconnecting (tm1py parity)', async () => {
432
+ await tm1Service.reConnect();
433
+
434
+ expect(mockRestService.connect).toHaveBeenCalledTimes(1);
435
+ expect(mockRestService.disconnect).not.toHaveBeenCalled();
436
+ });
437
+
438
+ test('should propagate errors from connect', async () => {
439
+ mockRestService.connect.mockRejectedValueOnce(new Error('Connect failed'));
440
+
441
+ await expect(tm1Service.reConnect()).rejects.toThrow('Connect failed');
442
+ expect(mockRestService.connect).toHaveBeenCalledTimes(1);
443
+ });
444
+ });
361
445
  });