@taiga-ai/mcp-server 0.4.0-dev.382 → 0.4.0-dev.386

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.js CHANGED
@@ -28,7 +28,7 @@ var TaigaClient = class {
28
28
  const response = await fetch(url, {
29
29
  method,
30
30
  headers,
31
- body: body ? JSON.stringify(body) : void 0
31
+ body: body ? JSON.stringify(body) : null
32
32
  });
33
33
  if (!response.ok) {
34
34
  const text = await response.text().catch(() => "");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taiga-ai/mcp-server",
3
- "version": "0.4.0-dev.382",
3
+ "version": "0.4.0-dev.386",
4
4
  "description": "MCP server for Taiga -- gives AI assistants access to documents and products",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -26,6 +26,7 @@
26
26
  "zod": "^4.4.3"
27
27
  },
28
28
  "devDependencies": {
29
+ "@tsconfig/strictest": "^2.0.8",
29
30
  "@types/node": "^22.20.1",
30
31
  "rolldown": "^1.2.3",
31
32
  "typescript": "^7.0.2",
@@ -57,7 +57,7 @@ describe('TaigaClient', () => {
57
57
  await client.listProducts();
58
58
 
59
59
  // Assert
60
- const headers = spy.mock.calls[0][1].headers;
60
+ const headers = spy.mock.calls[0]![1].headers;
61
61
  expect(headers.Authorization).toBe('Bearer taiga_sk_live_secret42');
62
62
  });
63
63
 
@@ -66,7 +66,7 @@ describe('TaigaClient', () => {
66
66
 
67
67
  await makeClient().listProducts();
68
68
 
69
- expect(spy.mock.calls[0][1].headers['User-Agent']).toBe(`taiga-ai-mcp-server/${pkg.version}`);
69
+ expect(spy.mock.calls[0]![1].headers['User-Agent']).toBe(`taiga-ai-mcp-server/${pkg.version}`);
70
70
  });
71
71
  });
72
72
 
@@ -113,7 +113,7 @@ describe('TaigaClient', () => {
113
113
 
114
114
  await client.listProducts();
115
115
 
116
- expect(spy.mock.calls[0][0]).toBe('https://api.test.com/v1/products');
116
+ expect(spy.mock.calls[0]![0]).toBe('https://api.test.com/v1/products');
117
117
  });
118
118
 
119
119
  it('should omit query string when no optional params are provided', async () => {
@@ -121,7 +121,7 @@ describe('TaigaClient', () => {
121
121
 
122
122
  await makeClient().listProducts();
123
123
 
124
- expect(spy.mock.calls[0][0]).toBe('https://api.test.com/v1/products');
124
+ expect(spy.mock.calls[0]![0]).toBe('https://api.test.com/v1/products');
125
125
  });
126
126
 
127
127
  it('should include all optional filters as query params', async () => {
@@ -129,7 +129,7 @@ describe('TaigaClient', () => {
129
129
 
130
130
  await makeClient().listProducts({ factoryId: 't1', status: 'active', limit: 10 });
131
131
 
132
- const url = spy.mock.calls[0][0] as string;
132
+ const url = spy.mock.calls[0]![0] as string;
133
133
  expect(url).toContain('factoryId=t1');
134
134
  expect(url).toContain('status=active');
135
135
  expect(url).toContain('limit=10');
@@ -140,7 +140,7 @@ describe('TaigaClient', () => {
140
140
 
141
141
  await makeClient().listBacklogItems('proj-1', { limit: 20 });
142
142
 
143
- const url = spy.mock.calls[0][0] as string;
143
+ const url = spy.mock.calls[0]![0] as string;
144
144
  expect(url).toContain('/v1/products/proj-1/backlog');
145
145
  expect(url).toContain('limit=20');
146
146
  });
@@ -150,7 +150,7 @@ describe('TaigaClient', () => {
150
150
 
151
151
  await makeClient().listEnvironments('proj-1');
152
152
 
153
- expect(spy.mock.calls[0][0]).toBe('https://api.test.com/v1/products/proj-1/environments');
153
+ expect(spy.mock.calls[0]![0]).toBe('https://api.test.com/v1/products/proj-1/environments');
154
154
  });
155
155
  });
156
156
 
@@ -211,7 +211,7 @@ describe('TaigaClient', () => {
211
211
 
212
212
  const result = await makeClient().getProduct('p1');
213
213
 
214
- expect(spy.mock.calls[0][0]).toBe('https://api.test.com/v1/products/p1');
214
+ expect(spy.mock.calls[0]![0]).toBe('https://api.test.com/v1/products/p1');
215
215
  expect(result.data).toEqual({ id: 'p1', name: 'Alpha' });
216
216
  });
217
217
 
@@ -220,7 +220,7 @@ describe('TaigaClient', () => {
220
220
 
221
221
  await makeClient().getTenantDocument('security_policy');
222
222
 
223
- expect(spy.mock.calls[0][0]).toBe('https://api.test.com/v1/tenants/current/documents/security_policy');
223
+ expect(spy.mock.calls[0]![0]).toBe('https://api.test.com/v1/tenants/current/documents/security_policy');
224
224
  });
225
225
 
226
226
  it('should PUT a document draft with the provided body', async () => {
@@ -228,9 +228,9 @@ describe('TaigaClient', () => {
228
228
 
229
229
  await makeClient().saveTenantDocumentDraft('security_policy', { data: { title: 'New' } });
230
230
 
231
- expect(spy.mock.calls[0][1].method).toBe('PUT');
232
- expect(spy.mock.calls[0][0]).toContain('/tenants/current/documents/security_policy/draft');
233
- expect(JSON.parse(spy.mock.calls[0][1].body)).toEqual({
231
+ expect(spy.mock.calls[0]![1].method).toBe('PUT');
232
+ expect(spy.mock.calls[0]![0]).toContain('/tenants/current/documents/security_policy/draft');
233
+ expect(JSON.parse(spy.mock.calls[0]![1].body)).toEqual({
234
234
  data: { title: 'New' },
235
235
  });
236
236
  });
@@ -240,7 +240,7 @@ describe('TaigaClient', () => {
240
240
 
241
241
  await makeClient().getBacklogItem('item-1');
242
242
 
243
- expect(spy.mock.calls[0][0]).toBe('https://api.test.com/v1/backlog/item-1');
243
+ expect(spy.mock.calls[0]![0]).toBe('https://api.test.com/v1/backlog/item-1');
244
244
  });
245
245
 
246
246
  it('should GET factories with optional limit', async () => {
@@ -248,7 +248,7 @@ describe('TaigaClient', () => {
248
248
 
249
249
  await makeClient().listFactories({ limit: 50 });
250
250
 
251
- expect(spy.mock.calls[0][0]).toContain('/v1/factories?limit=50');
251
+ expect(spy.mock.calls[0]![0]).toContain('/v1/factories?limit=50');
252
252
  });
253
253
 
254
254
  it('should GET documents from tenant path with optional limit', async () => {
@@ -256,7 +256,7 @@ describe('TaigaClient', () => {
256
256
 
257
257
  await makeClient().listTenantDocuments({ limit: 5 });
258
258
 
259
- expect(spy.mock.calls[0][0]).toContain('/v1/tenants/current/documents?limit=5');
259
+ expect(spy.mock.calls[0]![0]).toContain('/v1/tenants/current/documents?limit=5');
260
260
  });
261
261
  });
262
262
  });
package/src/client.ts CHANGED
@@ -26,7 +26,7 @@ export class TaigaClient {
26
26
  const response = await fetch(url, {
27
27
  method,
28
28
  headers,
29
- body: body ? JSON.stringify(body) : undefined,
29
+ body: body ? JSON.stringify(body) : null,
30
30
  });
31
31
 
32
32
  if (!response.ok) {
@@ -60,7 +60,11 @@ export class TaigaClient {
60
60
  // Products
61
61
  // ---------------------------------------------------------------------------
62
62
 
63
- async listProducts(opts?: { factoryId?: string; status?: string; limit?: number }) {
63
+ async listProducts(opts?: {
64
+ factoryId?: string | undefined;
65
+ status?: string | undefined;
66
+ limit?: number | undefined;
67
+ }) {
64
68
  const params = new URLSearchParams();
65
69
  if (opts?.factoryId) params.set('factoryId', opts.factoryId);
66
70
  if (opts?.status) params.set('status', opts.status);
@@ -77,7 +81,7 @@ export class TaigaClient {
77
81
  // Documents (tenant-level policies)
78
82
  // ---------------------------------------------------------------------------
79
83
 
80
- async listTenantDocuments(opts?: { limit?: number }) {
84
+ async listTenantDocuments(opts?: { limit?: number | undefined }) {
81
85
  const params = new URLSearchParams();
82
86
  if (opts?.limit) params.set('limit', String(opts.limit));
83
87
  const qs = params.toString();
@@ -99,7 +103,7 @@ export class TaigaClient {
99
103
  // Factory Documents
100
104
  // ---------------------------------------------------------------------------
101
105
 
102
- async listFactoryDocuments(factoryId: string, opts?: { limit?: number }) {
106
+ async listFactoryDocuments(factoryId: string, opts?: { limit?: number | undefined }) {
103
107
  const params = new URLSearchParams();
104
108
  if (opts?.limit) params.set('limit', String(opts.limit));
105
109
  const qs = params.toString();
@@ -121,7 +125,7 @@ export class TaigaClient {
121
125
  // Product Documents
122
126
  // ---------------------------------------------------------------------------
123
127
 
124
- async listProductDocuments(productId: string, opts?: { limit?: number }) {
128
+ async listProductDocuments(productId: string, opts?: { limit?: number | undefined }) {
125
129
  const params = new URLSearchParams();
126
130
  if (opts?.limit) params.set('limit', String(opts.limit));
127
131
  const qs = params.toString();
@@ -214,7 +218,7 @@ export class TaigaClient {
214
218
  // Backlog
215
219
  // ---------------------------------------------------------------------------
216
220
 
217
- async listBacklogItems(productId: string, opts?: { limit?: number }) {
221
+ async listBacklogItems(productId: string, opts?: { limit?: number | undefined }) {
218
222
  const params = new URLSearchParams();
219
223
  if (opts?.limit) params.set('limit', String(opts.limit));
220
224
  const qs = params.toString();
@@ -240,7 +244,7 @@ export class TaigaClient {
240
244
  // Factories
241
245
  // ---------------------------------------------------------------------------
242
246
 
243
- async listFactories(opts?: { limit?: number }) {
247
+ async listFactories(opts?: { limit?: number | undefined }) {
244
248
  const params = new URLSearchParams();
245
249
  if (opts?.limit) params.set('limit', String(opts.limit));
246
250
  const qs = params.toString();
@@ -110,7 +110,7 @@ function toolNames(tools: { name: string }[]) {
110
110
  /** Extract parsed JSON from the first text content block of a tool call result. */
111
111
  function parseToolResult(result: Record<string, unknown>) {
112
112
  const content = result.content as { type: string; text: string }[];
113
- return JSON.parse(content[0].text);
113
+ return JSON.parse(content[0]!.text);
114
114
  }
115
115
 
116
116
  // ---------------------------------------------------------------------------
package/tsconfig.json CHANGED
@@ -1,17 +1,19 @@
1
1
  {
2
+ "extends": "@tsconfig/strictest/tsconfig.json",
2
3
  "compilerOptions": {
3
4
  "target": "ES2022",
4
5
  "module": "ESNext",
5
6
  "moduleResolution": "bundler",
6
7
  "declaration": true,
7
8
  "declarationMap": true,
8
- "strict": true,
9
- "skipLibCheck": true,
10
9
  "outDir": "./dist",
11
10
  "rootDir": "./src",
12
- "esModuleInterop": true,
13
11
  "resolveJsonModule": true,
14
- "types": ["node"]
12
+ "types": ["node"],
13
+
14
+ // Preset flags this package still fails (PRO-2509). Each line is deleted
15
+ // by the issue named beside it; no new line is added here.
16
+ "noPropertyAccessFromIndexSignature": false // PRO-2519
15
17
  },
16
18
  "include": ["src"],
17
19
  "exclude": ["node_modules", "dist"],