tm1npm 1.5.3 → 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.
- package/CHANGELOG.md +89 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/services/ApplicationService.d.ts +19 -3
- package/lib/services/ApplicationService.d.ts.map +1 -1
- package/lib/services/ApplicationService.js +232 -6
- package/lib/services/AsyncOperationService.d.ts +8 -1
- package/lib/services/AsyncOperationService.d.ts.map +1 -1
- package/lib/services/AsyncOperationService.js +69 -26
- package/lib/services/ElementService.d.ts +67 -1
- package/lib/services/ElementService.d.ts.map +1 -1
- package/lib/services/ElementService.js +214 -0
- package/lib/services/FileService.d.ts.map +1 -1
- package/lib/services/HierarchyService.d.ts +26 -0
- package/lib/services/HierarchyService.d.ts.map +1 -1
- package/lib/services/HierarchyService.js +306 -0
- package/lib/services/ProcessService.d.ts +40 -22
- package/lib/services/ProcessService.d.ts.map +1 -1
- package/lib/services/ProcessService.js +118 -111
- package/lib/services/RestService.d.ts +213 -25
- package/lib/services/RestService.d.ts.map +1 -1
- package/lib/services/RestService.js +841 -263
- package/lib/services/SubsetService.d.ts +2 -0
- package/lib/services/SubsetService.d.ts.map +1 -1
- package/lib/services/SubsetService.js +33 -0
- package/lib/services/TM1Service.d.ts +44 -1
- package/lib/services/TM1Service.d.ts.map +1 -1
- package/lib/services/TM1Service.js +96 -4
- package/lib/services/index.d.ts +1 -1
- package/lib/services/index.d.ts.map +1 -1
- package/lib/tests/100PercentParityCheck.test.js +23 -6
- package/lib/tests/applicationService.issue38.test.d.ts +5 -0
- package/lib/tests/applicationService.issue38.test.d.ts.map +1 -0
- package/lib/tests/applicationService.issue38.test.js +237 -0
- package/lib/tests/asyncOperationService.test.js +51 -45
- package/lib/tests/bugfix28.test.js +12 -4
- package/lib/tests/elementService.issue37.test.d.ts +5 -0
- package/lib/tests/elementService.issue37.test.d.ts.map +1 -0
- package/lib/tests/elementService.issue37.test.js +413 -0
- package/lib/tests/elementService.issue38.test.d.ts +5 -0
- package/lib/tests/elementService.issue38.test.d.ts.map +1 -0
- package/lib/tests/elementService.issue38.test.js +79 -0
- package/lib/tests/hierarchyService.issue38.test.d.ts +5 -0
- package/lib/tests/hierarchyService.issue38.test.d.ts.map +1 -0
- package/lib/tests/hierarchyService.issue38.test.js +460 -0
- package/lib/tests/processService.comprehensive.test.js +9 -9
- package/lib/tests/processService.test.js +234 -0
- package/lib/tests/restService.test.d.ts +0 -4
- package/lib/tests/restService.test.d.ts.map +1 -1
- package/lib/tests/restService.test.js +1558 -143
- package/lib/tests/subsetService.issue38.test.d.ts +5 -0
- package/lib/tests/subsetService.issue38.test.d.ts.map +1 -0
- package/lib/tests/subsetService.issue38.test.js +113 -0
- package/lib/tests/tm1Service.test.js +80 -8
- package/package.json +1 -1
- package/src/index.ts +1 -1
- package/src/services/ApplicationService.ts +282 -10
- package/src/services/AsyncOperationService.ts +76 -29
- package/src/services/ElementService.ts +322 -1
- package/src/services/FileService.ts +3 -3
- package/src/services/HierarchyService.ts +419 -1
- package/src/services/ProcessService.ts +185 -142
- package/src/services/RestService.ts +1021 -267
- package/src/services/SubsetService.ts +48 -0
- package/src/services/TM1Service.ts +127 -6
- package/src/services/index.ts +1 -1
- package/src/tests/100PercentParityCheck.test.ts +29 -8
- package/src/tests/applicationService.issue38.test.ts +293 -0
- package/src/tests/asyncOperationService.test.ts +52 -48
- package/src/tests/bugfix28.test.ts +12 -4
- package/src/tests/elementService.issue37.test.ts +571 -0
- package/src/tests/elementService.issue38.test.ts +103 -0
- package/src/tests/hierarchyService.issue38.test.ts +599 -0
- package/src/tests/processService.comprehensive.test.ts +10 -10
- package/src/tests/processService.test.ts +295 -3
- package/src/tests/restService.test.ts +1844 -139
- package/src/tests/subsetService.issue38.test.ts +182 -0
- package/src/tests/tm1Service.test.ts +95 -11
|
@@ -381,8 +381,11 @@ describe('AsyncOperationService', () => {
|
|
|
381
381
|
});
|
|
382
382
|
asyncService.updateOperationStatus(id3, OperationStatus.COMPLETED);
|
|
383
383
|
|
|
384
|
+
// HTTP 202 = still running on the /_async endpoint.
|
|
384
385
|
mockRestService.get = jest.fn().mockResolvedValue({
|
|
385
|
-
|
|
386
|
+
status: 202,
|
|
387
|
+
headers: {},
|
|
388
|
+
data: {}
|
|
386
389
|
});
|
|
387
390
|
|
|
388
391
|
const activeOps = await asyncService.listActiveAsyncOperations();
|
|
@@ -641,91 +644,92 @@ describe('AsyncOperationService', () => {
|
|
|
641
644
|
});
|
|
642
645
|
});
|
|
643
646
|
|
|
647
|
+
// Status is inferred from the /_async('{id}') HTTP status code and the
|
|
648
|
+
// v12 `asyncresult` header; there is no `.Status` envelope on the new endpoint.
|
|
649
|
+
// These tests bypass createAsyncOperation (which tags operations as
|
|
650
|
+
// trackedLocally: true) to exercise the server-polling branch directly.
|
|
644
651
|
describe('Server Status Mapping', () => {
|
|
645
|
-
|
|
646
|
-
|
|
652
|
+
const injectServerOperation = (id: string) => {
|
|
653
|
+
(asyncService as any).operations.set(id, {
|
|
654
|
+
id,
|
|
647
655
|
type: OperationType.PROCESS_EXECUTION,
|
|
648
|
-
name: 'TestProcess'
|
|
656
|
+
name: 'TestProcess',
|
|
657
|
+
status: OperationStatus.RUNNING,
|
|
658
|
+
startTime: new Date(),
|
|
659
|
+
trackedLocally: false
|
|
649
660
|
});
|
|
661
|
+
};
|
|
650
662
|
|
|
651
|
-
|
|
663
|
+
test('should map HTTP 200 without asyncresult header to COMPLETED', async () => {
|
|
664
|
+
injectServerOperation('srv-1');
|
|
652
665
|
|
|
653
666
|
mockRestService.get = jest.fn().mockResolvedValue({
|
|
654
|
-
|
|
667
|
+
status: 200,
|
|
668
|
+
headers: {},
|
|
669
|
+
data: { value: 42 }
|
|
655
670
|
});
|
|
656
671
|
|
|
657
|
-
const status = await asyncService.getAsyncOperationStatus(
|
|
672
|
+
const status = await asyncService.getAsyncOperationStatus('srv-1');
|
|
658
673
|
expect(status).toBe(OperationStatus.COMPLETED);
|
|
659
674
|
|
|
660
|
-
const operation = asyncService.getOperation(
|
|
675
|
+
const operation = asyncService.getOperation('srv-1');
|
|
661
676
|
expect(operation?.result).toEqual({ value: 42 });
|
|
662
677
|
});
|
|
663
678
|
|
|
664
|
-
test('should map
|
|
665
|
-
|
|
666
|
-
type: OperationType.PROCESS_EXECUTION,
|
|
667
|
-
name: 'TestProcess'
|
|
668
|
-
});
|
|
669
|
-
|
|
670
|
-
asyncService.updateOperationStatus(operationId, OperationStatus.RUNNING);
|
|
679
|
+
test('should map HTTP 200 with non-2xx asyncresult header to FAILED', async () => {
|
|
680
|
+
injectServerOperation('srv-2');
|
|
671
681
|
|
|
672
682
|
mockRestService.get = jest.fn().mockResolvedValue({
|
|
673
|
-
|
|
683
|
+
status: 200,
|
|
684
|
+
headers: { asyncresult: '500 Internal Server Error' },
|
|
685
|
+
data: {}
|
|
674
686
|
});
|
|
675
687
|
|
|
676
|
-
const status = await asyncService.getAsyncOperationStatus(
|
|
688
|
+
const status = await asyncService.getAsyncOperationStatus('srv-2');
|
|
677
689
|
expect(status).toBe(OperationStatus.FAILED);
|
|
678
690
|
|
|
679
|
-
const operation = asyncService.getOperation(
|
|
680
|
-
expect(operation?.error).toBe('
|
|
691
|
+
const operation = asyncService.getOperation('srv-2');
|
|
692
|
+
expect(operation?.error).toBe('500 Internal Server Error');
|
|
681
693
|
});
|
|
682
694
|
|
|
683
|
-
test('should map
|
|
684
|
-
|
|
685
|
-
type: OperationType.PROCESS_EXECUTION,
|
|
686
|
-
name: 'TestProcess'
|
|
687
|
-
});
|
|
695
|
+
test('should map thrown TM1RestException to FAILED', async () => {
|
|
696
|
+
injectServerOperation('srv-3');
|
|
688
697
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
});
|
|
698
|
+
const { TM1RestException } = require('../exceptions/TM1Exception');
|
|
699
|
+
mockRestService.get = jest.fn().mockRejectedValue(
|
|
700
|
+
new TM1RestException('Server error', 500)
|
|
701
|
+
);
|
|
694
702
|
|
|
695
|
-
const status = await asyncService.getAsyncOperationStatus(
|
|
696
|
-
expect(status).toBe(OperationStatus.
|
|
703
|
+
const status = await asyncService.getAsyncOperationStatus('srv-3');
|
|
704
|
+
expect(status).toBe(OperationStatus.FAILED);
|
|
697
705
|
});
|
|
698
706
|
|
|
699
|
-
test('should map
|
|
700
|
-
|
|
701
|
-
type: OperationType.PROCESS_EXECUTION,
|
|
702
|
-
name: 'TestProcess'
|
|
703
|
-
});
|
|
704
|
-
|
|
705
|
-
asyncService.updateOperationStatus(operationId, OperationStatus.RUNNING);
|
|
707
|
+
test('should map HTTP 202 to RUNNING', async () => {
|
|
708
|
+
injectServerOperation('srv-4');
|
|
706
709
|
|
|
707
710
|
mockRestService.get = jest.fn().mockResolvedValue({
|
|
708
|
-
|
|
711
|
+
status: 202,
|
|
712
|
+
headers: {},
|
|
713
|
+
data: {}
|
|
709
714
|
});
|
|
710
715
|
|
|
711
|
-
const status = await asyncService.getAsyncOperationStatus(
|
|
712
|
-
expect(status).toBe(OperationStatus.
|
|
716
|
+
const status = await asyncService.getAsyncOperationStatus('srv-4');
|
|
717
|
+
expect(status).toBe(OperationStatus.RUNNING);
|
|
713
718
|
});
|
|
714
719
|
|
|
715
|
-
test('
|
|
720
|
+
test('locally-tracked operations skip server polling and return cached status', async () => {
|
|
716
721
|
const operationId = await asyncService.createAsyncOperation({
|
|
717
722
|
type: OperationType.PROCESS_EXECUTION,
|
|
718
|
-
name: '
|
|
723
|
+
name: 'LocalProcess'
|
|
719
724
|
});
|
|
720
|
-
|
|
721
725
|
asyncService.updateOperationStatus(operationId, OperationStatus.RUNNING);
|
|
722
726
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
});
|
|
727
|
+
const getSpy = jest.fn();
|
|
728
|
+
mockRestService.get = getSpy;
|
|
726
729
|
|
|
727
730
|
const status = await asyncService.getAsyncOperationStatus(operationId);
|
|
728
|
-
expect(status).toBe(OperationStatus.
|
|
731
|
+
expect(status).toBe(OperationStatus.RUNNING);
|
|
732
|
+
expect(getSpy).not.toHaveBeenCalled();
|
|
729
733
|
});
|
|
730
734
|
});
|
|
731
735
|
|
|
@@ -11,6 +11,7 @@ import { SubsetService } from '../services/SubsetService';
|
|
|
11
11
|
import { ApplicationService } from '../services/ApplicationService';
|
|
12
12
|
import { SessionService } from '../services/SessionService';
|
|
13
13
|
import { RestService } from '../services/RestService';
|
|
14
|
+
import { TM1RestException } from '../exceptions/TM1Exception';
|
|
14
15
|
import { Subset } from '../objects/Subset';
|
|
15
16
|
import { CubeApplication, ApplicationTypes } from '../objects/Application';
|
|
16
17
|
|
|
@@ -166,13 +167,20 @@ describe('Bug #12 - ApplicationService getNames() should not inject /api/v1/ pre
|
|
|
166
167
|
});
|
|
167
168
|
|
|
168
169
|
test('getNames() with isPrivate should use PrivateContents', async () => {
|
|
169
|
-
|
|
170
|
+
// _resolvePath probes public path first (returns 404), then tries private
|
|
171
|
+
const notFound = new TM1RestException('Not Found', 404, { status: 404 });
|
|
172
|
+
mockRest.get
|
|
173
|
+
.mockRejectedValueOnce(notFound) // public probe → 404
|
|
174
|
+
.mockRejectedValueOnce(notFound) // private probe → 404 (falls through to findBoundary)
|
|
175
|
+
.mockResolvedValueOnce(createMockResponse({ value: [] })) // boundary probe succeeds
|
|
176
|
+
.mockResolvedValueOnce(createMockResponse({ value: [{ Name: 'App1' }] })); // actual getNames
|
|
170
177
|
|
|
171
178
|
await appService.getNames('Planning', true);
|
|
172
179
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
expect(
|
|
180
|
+
// The final GET should target PrivateContents
|
|
181
|
+
const lastCall = mockRest.get.mock.calls[mockRest.get.mock.calls.length - 1][0] as string;
|
|
182
|
+
expect(lastCall).not.toContain('/api/v1/');
|
|
183
|
+
expect(lastCall).toContain('PrivateContents');
|
|
176
184
|
});
|
|
177
185
|
|
|
178
186
|
test('getNames() with empty path', async () => {
|