tm1npm 1.0.0 → 1.1.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 (155) hide show
  1. package/.github/CODEOWNERS +9 -0
  2. package/.github/workflows/pr-build-check.yml +252 -0
  3. package/.github/workflows/publish-npm.yml +12 -0
  4. package/.github/workflows/security-check.yml +29 -0
  5. package/README.md +169 -13
  6. package/lib/objects/Application.d.ts +74 -40
  7. package/lib/objects/Application.d.ts.map +1 -1
  8. package/lib/objects/Application.js +214 -59
  9. package/lib/objects/Axis.d.ts +2 -2
  10. package/lib/objects/Axis.d.ts.map +1 -1
  11. package/lib/objects/Axis.js +2 -2
  12. package/lib/objects/Chore.d.ts +4 -0
  13. package/lib/objects/Chore.d.ts.map +1 -1
  14. package/lib/objects/Chore.js +44 -0
  15. package/lib/objects/ChoreStartTime.d.ts +1 -0
  16. package/lib/objects/ChoreStartTime.d.ts.map +1 -1
  17. package/lib/objects/ChoreStartTime.js +17 -11
  18. package/lib/objects/ChoreTask.d.ts +1 -0
  19. package/lib/objects/ChoreTask.d.ts.map +1 -1
  20. package/lib/objects/ChoreTask.js +3 -0
  21. package/lib/services/ApplicationService.d.ts +13 -6
  22. package/lib/services/ApplicationService.d.ts.map +1 -1
  23. package/lib/services/ApplicationService.js +171 -179
  24. package/lib/services/AuditLogService.d.ts +1 -0
  25. package/lib/services/AuditLogService.d.ts.map +1 -1
  26. package/lib/services/AuditLogService.js +21 -9
  27. package/lib/services/CellService.d.ts +255 -3
  28. package/lib/services/CellService.d.ts.map +1 -1
  29. package/lib/services/CellService.js +845 -14
  30. package/lib/services/ChoreService.d.ts +20 -0
  31. package/lib/services/ChoreService.d.ts.map +1 -1
  32. package/lib/services/ChoreService.js +183 -44
  33. package/lib/services/ConfigurationService.d.ts +10 -8
  34. package/lib/services/ConfigurationService.d.ts.map +1 -1
  35. package/lib/services/ConfigurationService.js +41 -35
  36. package/lib/services/CubeService.d.ts +29 -0
  37. package/lib/services/CubeService.d.ts.map +1 -1
  38. package/lib/services/CubeService.js +154 -0
  39. package/lib/services/DimensionService.d.ts +5 -0
  40. package/lib/services/DimensionService.d.ts.map +1 -1
  41. package/lib/services/DimensionService.js +49 -0
  42. package/lib/services/ElementService.d.ts +102 -9
  43. package/lib/services/ElementService.d.ts.map +1 -1
  44. package/lib/services/ElementService.js +248 -82
  45. package/lib/services/FileService.d.ts +23 -1
  46. package/lib/services/FileService.d.ts.map +1 -1
  47. package/lib/services/FileService.js +228 -40
  48. package/lib/services/GitService.d.ts +1 -0
  49. package/lib/services/GitService.d.ts.map +1 -1
  50. package/lib/services/GitService.js +33 -16
  51. package/lib/services/JobService.d.ts +3 -0
  52. package/lib/services/JobService.d.ts.map +1 -1
  53. package/lib/services/JobService.js +10 -0
  54. package/lib/services/LoggerService.d.ts +0 -1
  55. package/lib/services/LoggerService.d.ts.map +1 -1
  56. package/lib/services/LoggerService.js +0 -9
  57. package/lib/services/MessageLogService.d.ts +6 -0
  58. package/lib/services/MessageLogService.d.ts.map +1 -1
  59. package/lib/services/MessageLogService.js +45 -18
  60. package/lib/services/MonitoringService.d.ts.map +1 -1
  61. package/lib/services/MonitoringService.js +22 -0
  62. package/lib/services/ObjectService.d.ts +17 -1
  63. package/lib/services/ObjectService.d.ts.map +1 -1
  64. package/lib/services/ObjectService.js +73 -6
  65. package/lib/services/PowerBiService.d.ts.map +1 -1
  66. package/lib/services/PowerBiService.js +20 -1
  67. package/lib/services/ProcessService.d.ts +8 -0
  68. package/lib/services/ProcessService.d.ts.map +1 -1
  69. package/lib/services/ProcessService.js +88 -0
  70. package/lib/services/RestService.d.ts +172 -1
  71. package/lib/services/RestService.d.ts.map +1 -1
  72. package/lib/services/RestService.js +574 -7
  73. package/lib/services/SandboxService.d.ts +6 -6
  74. package/lib/services/SandboxService.d.ts.map +1 -1
  75. package/lib/services/SandboxService.js +50 -118
  76. package/lib/services/SecurityService.d.ts +6 -1
  77. package/lib/services/SecurityService.d.ts.map +1 -1
  78. package/lib/services/SecurityService.js +46 -12
  79. package/lib/services/SessionService.d.ts +1 -1
  80. package/lib/services/SessionService.d.ts.map +1 -1
  81. package/lib/services/SessionService.js +15 -0
  82. package/lib/services/SubsetService.d.ts +12 -2
  83. package/lib/services/SubsetService.d.ts.map +1 -1
  84. package/lib/services/SubsetService.js +94 -13
  85. package/lib/services/ThreadService.d.ts +0 -1
  86. package/lib/services/ThreadService.d.ts.map +1 -1
  87. package/lib/services/ThreadService.js +4 -2
  88. package/lib/services/TransactionLogService.d.ts +1 -0
  89. package/lib/services/TransactionLogService.d.ts.map +1 -1
  90. package/lib/services/TransactionLogService.js +21 -15
  91. package/lib/services/ViewService.d.ts +2 -1
  92. package/lib/services/ViewService.d.ts.map +1 -1
  93. package/lib/services/ViewService.js +45 -10
  94. package/lib/tests/annotationService.comprehensive.test.d.ts +6 -0
  95. package/lib/tests/annotationService.comprehensive.test.d.ts.map +1 -0
  96. package/lib/tests/annotationService.comprehensive.test.js +322 -0
  97. package/lib/tests/cubeService.getAllNames.test.d.ts +6 -0
  98. package/lib/tests/cubeService.getAllNames.test.d.ts.map +1 -0
  99. package/lib/tests/cubeService.getAllNames.test.js +245 -0
  100. package/lib/tests/elementService.comprehensive.test.js +44 -29
  101. package/lib/tests/enhancedCellService.test.js +144 -9
  102. package/lib/tests/enhancedElementService.test.js +21 -15
  103. package/lib/tests/integrationTests.test.js +7 -5
  104. package/lib/tests/securityService.comprehensive.test.js +6 -0
  105. package/lib/tests/serverService.simple.test.d.ts +6 -0
  106. package/lib/tests/serverService.simple.test.d.ts.map +1 -0
  107. package/lib/tests/serverService.simple.test.js +221 -0
  108. package/lib/utils/DataFrame.d.ts +112 -0
  109. package/lib/utils/DataFrame.d.ts.map +1 -0
  110. package/lib/utils/DataFrame.js +282 -0
  111. package/lib/utils/Utils.d.ts +21 -0
  112. package/lib/utils/Utils.d.ts.map +1 -1
  113. package/lib/utils/Utils.js +161 -9
  114. package/package.json +1 -1
  115. package/src/objects/Application.ts +241 -73
  116. package/src/objects/Axis.ts +2 -2
  117. package/src/objects/Chore.ts +51 -0
  118. package/src/objects/ChoreStartTime.ts +26 -11
  119. package/src/objects/ChoreTask.ts +4 -0
  120. package/src/objects/NativeView.ts +2 -2
  121. package/src/services/ApplicationService.ts +269 -201
  122. package/src/services/AuditLogService.ts +34 -31
  123. package/src/services/CellService.ts +1271 -97
  124. package/src/services/ChoreService.ts +215 -45
  125. package/src/services/ConfigurationService.ts +42 -38
  126. package/src/services/CubeService.ts +196 -2
  127. package/src/services/DimensionService.ts +63 -1
  128. package/src/services/ElementService.ts +415 -150
  129. package/src/services/FileService.ts +318 -39
  130. package/src/services/GitService.ts +37 -27
  131. package/src/services/JobService.ts +14 -1
  132. package/src/services/LoggerService.ts +1 -10
  133. package/src/services/MessageLogService.ts +61 -39
  134. package/src/services/MonitoringService.ts +4 -1
  135. package/src/services/ObjectService.ts +86 -8
  136. package/src/services/PowerBiService.ts +29 -4
  137. package/src/services/ProcessService.ts +101 -0
  138. package/src/services/RestService.ts +662 -10
  139. package/src/services/SandboxService.ts +59 -122
  140. package/src/services/SecurityService.ts +58 -16
  141. package/src/services/SessionService.ts +4 -3
  142. package/src/services/SubsetService.ts +253 -21
  143. package/src/services/ThreadService.ts +2 -5
  144. package/src/services/TransactionLogService.ts +28 -29
  145. package/src/services/ViewService.ts +76 -10
  146. package/src/tests/annotationService.comprehensive.test.ts +420 -0
  147. package/src/tests/cubeService.getAllNames.test.ts +302 -0
  148. package/src/tests/elementService.comprehensive.test.ts +54 -34
  149. package/src/tests/enhancedCellService.test.ts +200 -12
  150. package/src/tests/enhancedElementService.test.ts +22 -18
  151. package/src/tests/integrationTests.test.ts +7 -5
  152. package/src/tests/securityService.comprehensive.test.ts +9 -0
  153. package/src/tests/serverService.simple.test.ts +293 -0
  154. package/src/utils/DataFrame.ts +333 -0
  155. package/src/utils/Utils.ts +187 -13
@@ -0,0 +1,9 @@
1
+ # Global code owners - require review from KimKaoPoo for all changes
2
+ * @KimKaoPoo
3
+
4
+ # Workflow files - require review for CI/CD changes
5
+ /.github/ @KimKaoPoo
6
+
7
+ # Package configuration - require review for publishing settings
8
+ /package.json @KimKaoPoo
9
+ /package-lock.json @KimKaoPoo
@@ -0,0 +1,252 @@
1
+ name: PR Build Check
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize, reopened, ready_for_review]
6
+ branches: [main, master, develop]
7
+ pull_request_target:
8
+ types: [opened, synchronize, reopened, ready_for_review]
9
+ branches: [main, master, develop]
10
+
11
+ permissions:
12
+ contents: read
13
+ pull-requests: write
14
+ statuses: write
15
+ checks: write
16
+
17
+ jobs:
18
+ build-check:
19
+ name: Build Validation
20
+ runs-on: ubuntu-latest
21
+
22
+ # Skip draft PRs unless they're marked as ready for review
23
+ if: github.event.pull_request.draft == false || github.event.action == 'ready_for_review'
24
+
25
+ strategy:
26
+ matrix:
27
+ node-version: [16, 18, 20]
28
+
29
+ steps:
30
+ - name: Checkout PR code
31
+ uses: actions/checkout@v4
32
+ with:
33
+ # For pull_request_target, we checkout the PR code safely
34
+ ref: ${{ github.event.pull_request.head.sha }}
35
+
36
+ - name: Setup Node.js ${{ matrix.node-version }}
37
+ uses: actions/setup-node@v4
38
+ with:
39
+ node-version: ${{ matrix.node-version }}
40
+ cache: 'npm'
41
+
42
+ - name: Cache dependencies
43
+ uses: actions/cache@v3
44
+ with:
45
+ path: ~/.npm
46
+ key: ${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }}
47
+ restore-keys: |
48
+ ${{ runner.os }}-node-${{ matrix.node-version }}-
49
+ ${{ runner.os }}-node-
50
+
51
+ - name: Install dependencies
52
+ run: npm ci
53
+
54
+ - name: Lint code (if available)
55
+ run: |
56
+ if npm run lint --if-present; then
57
+ echo "✅ Linting passed"
58
+ else
59
+ echo "⚠️ No lint script found or linting failed"
60
+ fi
61
+ continue-on-error: true
62
+
63
+ - name: Type checking (if available)
64
+ run: |
65
+ if npm run typecheck --if-present; then
66
+ echo "✅ Type checking passed"
67
+ else
68
+ echo "⚠️ No typecheck script found, skipping"
69
+ fi
70
+ continue-on-error: true
71
+
72
+ - name: Run build
73
+ id: build
74
+ run: |
75
+ echo "🔨 Building project..."
76
+ npm run build
77
+ echo "✅ Build completed successfully"
78
+
79
+ - name: Verify build output
80
+ run: |
81
+ echo "🔍 Verifying build artifacts..."
82
+
83
+ # Check if lib directory exists
84
+ if [ -d "lib" ]; then
85
+ echo "✅ lib/ directory found"
86
+ echo "📂 Build output structure:"
87
+ ls -la lib/ || echo "Empty lib directory"
88
+ else
89
+ echo "❌ lib/ directory not found"
90
+ echo "Build may have failed or output directory is different"
91
+ exit 1
92
+ fi
93
+
94
+ # Check for main entry points
95
+ missing_files=()
96
+
97
+ if [ ! -f "lib/index.js" ]; then
98
+ missing_files+=("lib/index.js")
99
+ fi
100
+
101
+ if [ ! -f "lib/index.d.ts" ]; then
102
+ missing_files+=("lib/index.d.ts")
103
+ fi
104
+
105
+ if [ ${#missing_files[@]} -eq 0 ]; then
106
+ echo "✅ Essential build files found"
107
+ else
108
+ echo "⚠️ Some expected build files are missing:"
109
+ printf ' - %s\n' "${missing_files[@]}"
110
+ echo "This may be expected depending on your build configuration"
111
+ fi
112
+
113
+ - name: Test build artifacts (if tests available)
114
+ run: |
115
+ if npm run test --if-present; then
116
+ echo "✅ Tests passed with built code"
117
+ else
118
+ echo "⚠️ No test script found, skipping test validation"
119
+ fi
120
+ continue-on-error: true
121
+
122
+ - name: Success summary
123
+ if: success()
124
+ run: |
125
+ echo "🎉 Build validation successful!"
126
+ echo "✅ Node.js ${{ matrix.node-version }}: Build completed successfully"
127
+ echo "📦 All build artifacts generated correctly"
128
+
129
+ - name: Failure summary
130
+ if: failure()
131
+ run: |
132
+ echo "❌ Build validation failed!"
133
+ echo "❌ Node.js ${{ matrix.node-version }}: Build failed"
134
+ echo "Please fix build issues before merging this PR"
135
+
136
+ # Summary job for all matrix builds
137
+ build-summary:
138
+ name: Build Summary
139
+ needs: build-check
140
+ runs-on: ubuntu-latest
141
+ permissions:
142
+ contents: read
143
+ pull-requests: write
144
+ statuses: write
145
+ checks: write
146
+ if: always()
147
+
148
+ steps:
149
+ - name: Determine overall result
150
+ id: result
151
+ run: |
152
+ if [[ "${{ needs.build-check.result }}" == "success" ]]; then
153
+ echo "result=success" >> $GITHUB_OUTPUT
154
+ echo "message=All builds passed across Node.js versions 16, 18, 20" >> $GITHUB_OUTPUT
155
+ echo "🎉 All builds successful!"
156
+ else
157
+ echo "result=failure" >> $GITHUB_OUTPUT
158
+ echo "message=Some builds failed - check logs for details" >> $GITHUB_OUTPUT
159
+ echo "❌ Some builds failed"
160
+ fi
161
+
162
+ - name: Create commit status
163
+ uses: actions/github-script@v7
164
+ with:
165
+ script: |
166
+ const { owner, repo } = context.repo;
167
+ const sha = context.payload.pull_request?.head?.sha || context.sha;
168
+ const result = '${{ steps.result.outputs.result }}';
169
+ const message = '${{ steps.result.outputs.message }}';
170
+
171
+ const state = result === 'success' ? 'success' : 'failure';
172
+ const description = result === 'success'
173
+ ? '✅ Build validation passed'
174
+ : '❌ Build validation failed';
175
+
176
+ await github.rest.repos.createCommitStatus({
177
+ owner,
178
+ repo,
179
+ sha,
180
+ state,
181
+ target_url: `https://github.com/${owner}/${repo}/actions/runs/${context.runId}`,
182
+ description,
183
+ context: 'PR Build Check'
184
+ });
185
+
186
+ console.log(`Commit status created: ${state}`);
187
+ console.log(`SHA: ${sha}`);
188
+ console.log(`Description: ${description}`);
189
+
190
+ - name: Comment on PR
191
+ if: github.event_name == 'pull_request' || github.event_name == 'pull_request_target'
192
+ uses: actions/github-script@v7
193
+ with:
194
+ script: |
195
+ const { owner, repo } = context.repo;
196
+ const prNumber = context.payload.pull_request.number;
197
+ const result = '${{ steps.result.outputs.result }}';
198
+ const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${context.runId}`;
199
+
200
+ let commentBody;
201
+
202
+ if (result === 'success') {
203
+ commentBody = '## ✅ Build Validation Passed\n\n' +
204
+ '**All builds completed successfully!**\n\n' +
205
+ '- ✅ Node.js 16: Build passed\n' +
206
+ '- ✅ Node.js 18: Build passed\n' +
207
+ '- ✅ Node.js 20: Build passed\n\n' +
208
+ '📦 All build artifacts generated correctly.\n\n' +
209
+ `[View detailed results](${runUrl})`;
210
+ } else {
211
+ commentBody = '## ❌ Build Validation Failed\n\n' +
212
+ '**Some builds failed - please review and fix:**\n\n' +
213
+ '🔍 **Common issues to check:**\n' +
214
+ '- TypeScript compilation errors\n' +
215
+ '- Missing dependencies\n' +
216
+ '- Syntax errors\n' +
217
+ '- Import/export issues\n\n' +
218
+ 'Please fix the build issues and push your changes.\n\n' +
219
+ `[View detailed results](${runUrl})`;
220
+ }
221
+
222
+ // Check if we already commented on this PR for this run
223
+ const comments = await github.rest.issues.listComments({
224
+ owner,
225
+ repo,
226
+ issue_number: prNumber,
227
+ });
228
+
229
+ const botComment = comments.data.find(comment =>
230
+ comment.user.type === 'Bot' &&
231
+ comment.body.includes('Build Validation')
232
+ );
233
+
234
+ if (botComment) {
235
+ // Update existing comment
236
+ await github.rest.issues.updateComment({
237
+ owner,
238
+ repo,
239
+ comment_id: botComment.id,
240
+ body: commentBody
241
+ });
242
+ console.log('Updated existing PR comment');
243
+ } else {
244
+ // Create new comment
245
+ await github.rest.issues.createComment({
246
+ owner,
247
+ repo,
248
+ issue_number: prNumber,
249
+ body: commentBody
250
+ });
251
+ console.log('Created new PR comment');
252
+ }
@@ -4,6 +4,9 @@ on:
4
4
  release:
5
5
  types: [published]
6
6
 
7
+ env:
8
+ ALLOWED_PUBLISHER: hsubebe89
9
+
7
10
  jobs:
8
11
  publish:
9
12
  runs-on: ubuntu-latest
@@ -12,6 +15,15 @@ jobs:
12
15
  id-token: write
13
16
 
14
17
  steps:
18
+ - name: Verify publisher authorization
19
+ run: |
20
+ if [ "${{ github.actor }}" != "${{ env.ALLOWED_PUBLISHER }}" ]; then
21
+ echo "❌ ERROR: Only ${{ env.ALLOWED_PUBLISHER }} can publish to NPM"
22
+ echo "Current actor: ${{ github.actor }}"
23
+ exit 1
24
+ fi
25
+ echo "✅ Publisher authorization verified for ${{ github.actor }}"
26
+
15
27
  - name: Checkout code
16
28
  uses: actions/checkout@v4
17
29
 
@@ -0,0 +1,29 @@
1
+ name: Security Check
2
+
3
+ on:
4
+ create:
5
+ release:
6
+ types: [published, created, edited, deleted]
7
+
8
+ env:
9
+ ALLOWED_MAINTAINER: hsubebe89
10
+
11
+ jobs:
12
+ verify-permissions:
13
+ runs-on: ubuntu-latest
14
+ if: github.ref_type == 'tag' || github.event_name == 'release'
15
+
16
+ steps:
17
+ - name: Verify tag/release permissions
18
+ run: |
19
+ if [ "${{ github.actor }}" != "${{ env.ALLOWED_MAINTAINER }}" ]; then
20
+ echo "❌ ERROR: Only ${{ env.ALLOWED_MAINTAINER }} can create tags and releases"
21
+ echo "Current actor: ${{ github.actor }}"
22
+ echo "Event: ${{ github.event_name }}"
23
+ echo "Ref type: ${{ github.ref_type }}"
24
+
25
+ # Log the unauthorized attempt
26
+ echo "⚠️ SECURITY ALERT: Unauthorized attempt to create tag/release by ${{ github.actor }}"
27
+ exit 1
28
+ fi
29
+ echo "✅ Tag/release permissions verified for ${{ github.actor }}"
package/README.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # tm1npm
2
2
 
3
+ <pre>
4
+ ████████╗███╗ ███╗ ██╗███╗ ██╗██████╗ ███╗ ███╗
5
+ ╚══██╔══╝████╗ ████║███║████╗ ██║██╔══██╗████╗ ████║
6
+ ██║ ██╔████╔██║╚██║██╔██╗ ██║██████╔╝██╔████╔██║
7
+ ██║ ██║╚██╔╝██║ ██║██║╚██╗██║██╔═══╝ ██║╚██╔╝██║
8
+ ██║ ██║ ╚═╝ ██║ ██║██║ ╚████║██║ ██║ ╚═╝ ██║
9
+ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═╝
10
+
11
+ 🚀 TM1 Integration for Node.js - Build powerful TM1 applications
12
+ </pre>
3
13
  tm1npm is the Node.js/TypeScript package for IBM Planning Analytics (TM1), providing a comprehensive interface to the TM1 REST API.
4
14
 
5
15
  By wrapping the IBM Planning Analytics (TM1) REST API in a concise TypeScript framework, tm1npm facilitates Node.js developments for TM1.
@@ -18,6 +28,9 @@ const tm1 = new TM1Service({
18
28
  });
19
29
 
20
30
  try {
31
+ // Connect to TM1 server
32
+ await tm1.connect();
33
+
21
34
  const subset = new Subset('Month', 'Q1', ['Jan', 'Feb', 'Mar']);
22
35
  await tm1.dimensions.subsets.create(subset, true);
23
36
  } finally {
@@ -82,6 +95,43 @@ npm install --save-dev typescript @types/node
82
95
 
83
96
  ## Usage
84
97
 
98
+ ### Important: Connection Workflow
99
+
100
+ **⚠️ CRITICAL**: Always call `await tm1.connect()` before performing any TM1 operations and `await tm1.logout()` when finished. This is the correct usage pattern:
101
+
102
+ ```typescript
103
+ import { TM1Service } from 'tm1npm';
104
+
105
+ const tm1 = new TM1Service({
106
+ address: 'localhost',
107
+ port: 8879,
108
+ user: 'admin',
109
+ password: 'your_password',
110
+ ssl: false
111
+ });
112
+
113
+ try {
114
+ // Step 1: Connect to TM1 server (REQUIRED!)
115
+ await tm1.connect();
116
+
117
+ // Step 2: Perform TM1 operations
118
+ const version = await tm1.getVersion();
119
+ console.log('TM1 Version:', version);
120
+
121
+ const cubes = await tm1.cubes.getAllNames();
122
+ console.log('Available cubes:', cubes);
123
+
124
+ } finally {
125
+ // Step 3: Always logout to clean up session (REQUIRED!)
126
+ await tm1.logout();
127
+ }
128
+ ```
129
+
130
+ **Why this matters:**
131
+ - `connect()` establishes the session with TM1 server
132
+ - `logout()` properly closes the session and prevents memory leaks
133
+ - Skipping either step can cause connection issues or resource leaks
134
+
85
135
  ### TM1 11 On-Premise
86
136
 
87
137
  ```typescript
@@ -96,6 +146,9 @@ const tm1 = new TM1Service({
96
146
  });
97
147
 
98
148
  try {
149
+ // Connect to TM1 server
150
+ await tm1.connect();
151
+
99
152
  const version = await tm1.server.getProductVersion();
100
153
  console.log('TM1 Version:', version);
101
154
 
@@ -122,6 +175,9 @@ const tm1 = new TM1Service({
122
175
  });
123
176
 
124
177
  try {
178
+ // Connect to TM1 server
179
+ await tm1.connect();
180
+
125
181
  const chores = await tm1.chores.getAll();
126
182
  for (const chore of chores) {
127
183
  chore.reschedule(-1); // Reschedule 1 hour earlier
@@ -148,6 +204,9 @@ const params = {
148
204
  const tm1 = new TM1Service(params);
149
205
 
150
206
  try {
207
+ // Connect to TM1 server
208
+ await tm1.connect();
209
+
151
210
  const version = await tm1.server.getProductVersion();
152
211
  console.log('TM1 Version:', version);
153
212
  } finally {
@@ -171,6 +230,9 @@ const tm1 = new TM1Service({
171
230
  });
172
231
 
173
232
  try {
233
+ // Connect to TM1 server
234
+ await tm1.connect();
235
+
174
236
  const version = await tm1.server.getProductVersion();
175
237
  console.log('TM1 Version:', version);
176
238
  } finally {
@@ -194,6 +256,9 @@ const params = {
194
256
  const tm1 = new TM1Service(params);
195
257
 
196
258
  try {
259
+ // Connect to TM1 server
260
+ await tm1.connect();
261
+
197
262
  const version = await tm1.server.getProductVersion();
198
263
  console.log('TM1 Version:', version);
199
264
  } finally {
@@ -211,6 +276,9 @@ import { TM1Service, Dimension, Hierarchy, Element } from 'tm1npm';
211
276
  const tm1 = new TM1Service(config);
212
277
 
213
278
  try {
279
+ // Connect to TM1 server
280
+ await tm1.connect();
281
+
214
282
  // Create a new dimension
215
283
  const elements = [
216
284
  new Element('Total', 'Consolidated'),
@@ -248,16 +316,31 @@ const mdx = `
248
316
  const cellset = await tm1.cubes.cells.executeMdx(mdx);
249
317
  console.log('Data:', cellset);
250
318
 
319
+ // 🆕 NEW: Get data as CSV format
320
+ const csvData = await tm1.cubes.cells.executeMdxCsv(mdx, {
321
+ csv_dialect: { delimiter: ',', quotechar: '"' }
322
+ });
323
+ console.log('CSV Data:', csvData);
324
+
325
+ // 🆕 NEW: Get data as DataFrame (pandas-like)
326
+ const dataFrame = await tm1.cubes.cells.executeMdxDataFrame(mdx);
327
+ console.log('DataFrame shape:', dataFrame.shape);
328
+ console.log('Columns:', dataFrame.columns);
329
+
251
330
  // Read data using cell coordinates
252
331
  const value = await tm1.cubes.cells.getValue('Budget', ['Jan', 'Revenue', 'Actual']);
253
332
  console.log('Cell value:', value);
333
+
334
+ // 🆕 NEW: Trace how a cell is calculated
335
+ const trace = await tm1.cubes.cells.traceCellCalculation('Budget', ['Jan', 'Revenue', 'Actual']);
336
+ console.log('Cell calculation trace:', trace);
254
337
  ```
255
338
 
256
339
  ### Writing Data to Cubes
257
340
 
258
341
  ```typescript
259
342
  // Write single cell
260
- await tm1.cubes.cells.writeValue(1000, 'Budget', ['Jan', 'Revenue', 'Budget']);
343
+ await tm1.cubes.cells.writeValue('Budget', ['Jan', 'Revenue', 'Budget'], 1000);
261
344
 
262
345
  // Write multiple cells
263
346
  const cellset = {
@@ -266,7 +349,18 @@ const cellset = {
266
349
  'Mar:Revenue:Budget': 1200
267
350
  };
268
351
 
269
- await tm1.cubes.cells.writeValues('Budget', cellset);
352
+ await tm1.cubes.cells.write('Budget', cellset);
353
+
354
+ // 🆕 NEW: Async writing for better performance
355
+ const executionId = await tm1.cubes.cells.writeAsync('Budget', cellset);
356
+ console.log('Async write started:', executionId);
357
+
358
+ // 🆕 NEW: Proportional spreading
359
+ await tm1.cubes.cells.relativeProportionalSpread(
360
+ 'Budget',
361
+ 10000, // value to spread
362
+ ['Total', 'Revenue', 'Budget'] // coordinates
363
+ );
270
364
  ```
271
365
 
272
366
  ### Executing Processes
@@ -280,16 +374,67 @@ const result = await tm1.processes.execute('ImportData', {
280
374
 
281
375
  console.log('Process executed successfully:', result);
282
376
 
377
+ // 🆕 NEW: Compile process and check for errors
378
+ const compilation = await tm1.processes.compileProcess('ImportData');
379
+ if (compilation.success) {
380
+ console.log('Process compiled successfully');
381
+ } else {
382
+ console.error('Compilation errors:', compilation.errors);
383
+ }
384
+
283
385
  // Execute with return information
284
- const [success, status, errorLog] = await tm1.processes.executeWithReturn('ImportData', {
386
+ const result2 = await tm1.processes.executeWithReturn('ImportData', {
285
387
  pFilename: 'data.csv'
286
388
  });
287
389
 
288
- if (success) {
289
- console.log('Process completed successfully');
290
- } else {
291
- console.error('Process failed:', errorLog);
292
- }
390
+ console.log('Process result:', result2);
391
+
392
+ // 🆕 NEW: Async execution with polling
393
+ const asyncResult = await tm1.processes.pollExecuteWithReturn('ImportData', {
394
+ pFilename: 'data.csv'
395
+ }, 300, 5); // 300s timeout, 5s poll interval
396
+
397
+ console.log('Async process completed:', asyncResult);
398
+ ```
399
+
400
+ ### 🆕 NEW: Working with DataFrames
401
+
402
+ tm1npm now includes a comprehensive DataFrame implementation for pandas-like data manipulation:
403
+
404
+ ```typescript
405
+ import { DataFrame } from 'tm1npm';
406
+
407
+ // Create DataFrame from TM1 data
408
+ const mdx = "SELECT [Time].Members ON COLUMNS, [Account].Members ON ROWS FROM [Budget]";
409
+ const dataFrame = await tm1.cubes.cells.executeMdxDataFrame(mdx);
410
+
411
+ // Explore the data
412
+ console.log('Shape:', dataFrame.shape); // [rows, columns]
413
+ console.log('Columns:', dataFrame.columns); // ['Time', 'Account', 'Value']
414
+
415
+ // Filter data
416
+ const filtered = dataFrame.filter((row, index) => row[2] > 1000); // Value > 1000
417
+
418
+ // Sort by value column
419
+ const sorted = dataFrame.sortBy('Value', false); // descending
420
+
421
+ // Group by Account and sum
422
+ const grouped = dataFrame.groupBy('Account').sum('Value');
423
+
424
+ // Convert to different formats
425
+ const csvString = dataFrame.toCsv(',');
426
+ const jsonArray = dataFrame.toJson();
427
+
428
+ // Advanced search with multiple criteria
429
+ const salesCubes = await tm1.cubes.searchCubes({
430
+ namePattern: 'sales',
431
+ dimensionNames: ['Time', 'Account'],
432
+ hasRules: true,
433
+ minDimensions: 3,
434
+ maxDimensions: 6
435
+ });
436
+
437
+ console.log('Found sales cubes:', salesCubes);
293
438
  ```
294
439
 
295
440
  ## Configuration Options
@@ -448,6 +593,8 @@ tm1npm is inspired by and designed to provide feature parity with **tm1py**, the
448
593
 
449
594
  **🏆 Feature Parity Status**: tm1npm achieves **95-98% feature parity** with tm1py, providing nearly all the same functionality you know and love from the Python ecosystem.
450
595
 
596
+ **🚀 NEW in v1.0.1**: Major functionality update with **25+ new methods** including CSV export, cell tracing, DataFrame support, advanced async operations, and enhanced search capabilities!
597
+
451
598
  ### Why tm1npm?
452
599
 
453
600
  - **Familiar API**: If you're coming from tm1py, you'll feel right at home
@@ -480,6 +627,9 @@ import { TM1Service } from 'tm1npm';
480
627
 
481
628
  const tm1 = new TM1Service({address: 'localhost', port: 8001, user: 'admin', password: 'apple'});
482
629
  try {
630
+ // Connect to TM1 server
631
+ await tm1.connect();
632
+
483
633
  // Get cube names
484
634
  const cubes = await tm1.cubes.getAllNames();
485
635
 
@@ -509,14 +659,14 @@ try {
509
659
 
510
660
  ### Comprehensive Feature Parity
511
661
 
512
- tm1npm implements **280+ functions** from tm1py's 31 core services, including:
662
+ tm1npm implements **300+ functions** from tm1py's 31 core services, including:
513
663
 
514
664
  #### Core Services (Complete Coverage)
515
- - ✅ **CellService**: 45+ methods including async operations, blob support, tracing
516
- - ✅ **CubeService**: 40+ methods for complete cube management
665
+ - ✅ **CellService**: 60+ methods including CSV export, cell tracing, async operations, DataFrame support
666
+ - ✅ **CubeService**: 45+ methods for complete cube management and advanced search
517
667
  - ✅ **DimensionService**: 30+ methods for dimension operations
518
668
  - ✅ **ElementService**: 60+ methods including TI-based operations
519
- - ✅ **ProcessService**: 40+ methods with debugging and async execution
669
+ - ✅ **ProcessService**: 45+ methods with compilation, debugging and async execution
520
670
  - ✅ **ViewService**: 30+ methods for private/public view management
521
671
  - ✅ **HierarchyService**: 18+ methods including balance checking
522
672
 
@@ -530,7 +680,13 @@ tm1npm implements **280+ functions** from tm1py's 31 core services, including:
530
680
  - ✅ **SandboxService**: Sandbox operations
531
681
 
532
682
  #### Advanced Features (Enterprise Ready)
533
- - ✅ **Async Operations**: `writeDataframeAsync()`, `executeMdxAsync()`, `pollExecuteWithReturn()`
683
+ - ✅ **CSV Export**: `executeMdxCsv()`, `executeViewCsv()` with full formatting control
684
+ - ✅ **Cell Analysis**: `traceCellCalculation()`, `traceCellFeeders()`, `checkCellFeeders()`
685
+ - ✅ **Proportional Spreading**: `relativeProportionalSpread()`, `clearSpread()`
686
+ - ✅ **DataFrame Support**: JavaScript DataFrame class with pandas-like functionality
687
+ - ✅ **Advanced Search**: `searchCubes()`, `searchForDimension()`, multi-criteria filtering
688
+ - ✅ **Enhanced Async**: `executeMdxAsync()`, `executeViewAsync()`, `writeDataframeAsync()`
689
+ - ✅ **Process Features**: `compileProcess()`, `pollExecuteWithReturn()` with error details
534
690
  - ✅ **TI Integration**: `deleteElementsUseTi()`, `writeThroughUnboundProcess()`
535
691
  - ✅ **Bulk Operations**: `deleteEdgesUseBlob()`, `writeThroughBlob()`
536
692
  - ✅ **Performance**: Blob support, compact JSON, iterative JSON