@dichovsky/testrail-api-client 1.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/src/types.ts ADDED
@@ -0,0 +1,853 @@
1
+ /**
2
+ * TestRail API client configuration options
3
+ */
4
+ export interface TestRailConfig {
5
+ /** TestRail instance URL (e.g., https://example.testrail.io) */
6
+ baseUrl: string;
7
+ /** TestRail user email for authentication */
8
+ email: string;
9
+ /** TestRail API key or password */
10
+ apiKey: string;
11
+ /** Request timeout in milliseconds (default: 30000ms) */
12
+ timeout?: number;
13
+ /** Maximum number of retry attempts for failed requests (default: 3) */
14
+ maxRetries?: number;
15
+ /** Enable caching for static resources (default: true) */
16
+ enableCache?: boolean;
17
+ /** Cache TTL in milliseconds (default: 300000ms = 5 minutes) */
18
+ cacheTtl?: number;
19
+ /**
20
+ * Cache cleanup interval in milliseconds (default: 60000ms = 1 minute).
21
+ * Set to 0 to disable periodic cleanup.
22
+ */
23
+ cacheCleanupInterval?: number;
24
+ /**
25
+ * Maximum number of entries in the cache (default: 1000).
26
+ * Set to 0 for unlimited (not recommended).
27
+ */
28
+ maxCacheSize?: number;
29
+ /** Rate limiting configuration (default: 100 requests per minute) */
30
+ rateLimiter?: RateLimiterConfig;
31
+ /**
32
+ * Allow HTTP (non-TLS) connections. Credentials are sent in cleartext over HTTP.
33
+ * Only enable in isolated development environments. Default: false.
34
+ */
35
+ allowInsecure?: boolean;
36
+ /**
37
+ * Allow requests to private/loopback/link-local hosts (e.g. localhost, 192.168.x.x).
38
+ * Only enable when TestRail is hosted on a private network. Default: false.
39
+ */
40
+ allowPrivateHosts?: boolean;
41
+ }
42
+
43
+ export interface Case {
44
+ id: number;
45
+ title: string;
46
+ section_id: number;
47
+ template_id?: number;
48
+ type_id?: number;
49
+ priority_id?: number;
50
+ milestone_id?: number;
51
+ refs?: string;
52
+ created_by: number;
53
+ created_on: number; // Unix timestamp
54
+ updated_by: number;
55
+ updated_on: number; // Unix timestamp
56
+ estimate?: string; // e.g. "5m"
57
+ estimate_forecast?: string;
58
+ suite_id: number;
59
+ display_order?: number;
60
+ is_deleted?: number;
61
+ custom_fields?: Record<string, unknown>;
62
+ }
63
+
64
+ export interface Suite {
65
+ id: number;
66
+ name: string;
67
+ description?: string;
68
+ project_id: number;
69
+ is_master?: boolean;
70
+ is_baseline?: boolean;
71
+ is_completed?: boolean;
72
+ completed_on?: number; // Unix timestamp
73
+ url: string;
74
+ }
75
+
76
+ export interface AddSuitePayload {
77
+ name: string;
78
+ description?: string;
79
+ }
80
+
81
+ export interface UpdateSuitePayload {
82
+ name?: string;
83
+ description?: string;
84
+ }
85
+
86
+ export interface Section {
87
+ id: number;
88
+ suite_id: number;
89
+ name: string;
90
+ description?: string;
91
+ parent_id?: number;
92
+ display_order: number;
93
+ depth: number;
94
+ }
95
+
96
+ export interface Project {
97
+ id: number;
98
+ name: string;
99
+ announcement?: string;
100
+ show_announcement?: boolean;
101
+ is_completed?: boolean;
102
+ completed_on?: number; // Unix timestamp
103
+ /** 1=single suite, 2=single suite+baselines, 3=multiple suites */
104
+ suite_mode: number;
105
+ url: string;
106
+ }
107
+
108
+ export interface Plan {
109
+ id: number;
110
+ name: string;
111
+ description?: string;
112
+ milestone_id?: number;
113
+ assignedto_id?: number;
114
+ is_completed: boolean;
115
+ completed_on?: number; // Unix timestamp
116
+ passed_count: number;
117
+ blocked_count: number;
118
+ untested_count: number;
119
+ retest_count: number;
120
+ failed_count: number;
121
+ custom_status1_count?: number;
122
+ custom_status2_count?: number;
123
+ custom_status3_count?: number;
124
+ custom_status4_count?: number;
125
+ custom_status5_count?: number;
126
+ custom_status6_count?: number;
127
+ custom_status7_count?: number;
128
+ project_id: number;
129
+ created_on: number; // Unix timestamp
130
+ created_by: number;
131
+ url: string;
132
+ entries?: PlanEntry[];
133
+ }
134
+
135
+ export interface PlanEntry {
136
+ id: string; // GUID
137
+ suite_id: number;
138
+ name: string;
139
+ description?: string;
140
+ assignedto_id?: number;
141
+ include_all: boolean;
142
+ case_ids?: number[];
143
+ config_ids?: number[];
144
+ runs: Run[];
145
+ }
146
+
147
+ export interface Run {
148
+ id: number;
149
+ suite_id: number;
150
+ name: string;
151
+ description?: string;
152
+ milestone_id?: number;
153
+ assignedto_id?: number;
154
+ include_all: boolean;
155
+ is_completed: boolean;
156
+ completed_on?: number; // Unix timestamp
157
+ config?: string;
158
+ config_ids?: number[];
159
+ passed_count: number;
160
+ blocked_count: number;
161
+ untested_count: number;
162
+ retest_count: number;
163
+ failed_count: number;
164
+ custom_status1_count?: number;
165
+ custom_status2_count?: number;
166
+ custom_status3_count?: number;
167
+ custom_status4_count?: number;
168
+ custom_status5_count?: number;
169
+ custom_status6_count?: number;
170
+ custom_status7_count?: number;
171
+ project_id: number;
172
+ plan_id?: number;
173
+ created_on: number; // Unix timestamp
174
+ created_by: number;
175
+ refs?: string;
176
+ url: string;
177
+ }
178
+
179
+ export interface Test {
180
+ id: number;
181
+ case_id: number;
182
+ status_id: number;
183
+ assignedto_id?: number;
184
+ run_id: number;
185
+ title: string;
186
+ template_id?: number;
187
+ type_id?: number;
188
+ priority_id?: number;
189
+ estimate?: string;
190
+ estimate_forecast?: string;
191
+ refs?: string;
192
+ milestone_id?: number;
193
+ custom_fields?: Record<string, unknown>;
194
+ }
195
+
196
+ export interface Result {
197
+ id?: number;
198
+ test_id?: number;
199
+ /** e.g., 1=Passed */
200
+ status_id: number;
201
+ comment?: string;
202
+ version?: string;
203
+ elapsed?: string; // e.g. "5m 30s"
204
+ defects?: string;
205
+ assignedto_id?: number;
206
+ created_by?: number;
207
+ created_on?: number; // Unix timestamp
208
+ custom_fields?: Record<string, unknown>;
209
+ }
210
+
211
+ export interface Milestone {
212
+ id: number;
213
+ name: string;
214
+ description?: string;
215
+ start_on?: number; // Unix timestamp
216
+ started_on?: number; // Unix timestamp
217
+ is_completed: boolean;
218
+ completed_on?: number; // Unix timestamp
219
+ due_on?: number; // Unix timestamp
220
+ project_id: number;
221
+ parent_id?: number;
222
+ refs?: string;
223
+ url: string;
224
+ milestones?: Milestone[];
225
+ }
226
+
227
+ export interface User {
228
+ id: number;
229
+ name: string;
230
+ email: string;
231
+ is_active: boolean;
232
+ role_id?: number;
233
+ role?: string;
234
+ }
235
+
236
+ export interface Status {
237
+ id: number;
238
+ name: string;
239
+ label: string;
240
+ color_dark: number;
241
+ color_medium: number;
242
+ color_bright: number;
243
+ is_system: boolean;
244
+ is_untested: boolean;
245
+ is_final: boolean;
246
+ }
247
+
248
+ export interface Priority {
249
+ id: number;
250
+ name: string;
251
+ short_name: string;
252
+ is_default: boolean;
253
+ priority: number; // weight/level
254
+ }
255
+
256
+ export interface AddCasePayload {
257
+ title: string;
258
+ template_id?: number;
259
+ type_id?: number;
260
+ priority_id?: number;
261
+ estimate?: string;
262
+ milestone_id?: number;
263
+ refs?: string;
264
+ custom_fields?: Record<string, unknown>;
265
+ }
266
+
267
+ export interface UpdateCasePayload {
268
+ title?: string;
269
+ template_id?: number;
270
+ type_id?: number;
271
+ priority_id?: number;
272
+ estimate?: string;
273
+ milestone_id?: number;
274
+ refs?: string;
275
+ custom_fields?: Record<string, unknown>;
276
+ }
277
+
278
+ /**
279
+ * Filter options for `getCases()`.
280
+ * All date filters accept Unix timestamps (seconds since epoch).
281
+ */
282
+ export interface GetCasesOptions {
283
+ /** Return only cases belonging to this suite */
284
+ suiteId?: number;
285
+ /** Return only cases in this section */
286
+ sectionId?: number;
287
+ /** Return only cases of this type (from `getCaseTypes()`) */
288
+ typeId?: number;
289
+ /** Return only cases with this priority (from `getPriorities()`) */
290
+ priorityId?: number;
291
+ /** Return only cases using this template (from `getTemplates()`) */
292
+ templateId?: number;
293
+ /** Return only cases linked to this milestone */
294
+ milestoneId?: number;
295
+ /** Return only cases created after this Unix timestamp */
296
+ createdAfter?: number;
297
+ /** Return only cases created before this Unix timestamp */
298
+ createdBefore?: number;
299
+ /** Return only cases updated after this Unix timestamp */
300
+ updatedAfter?: number;
301
+ /** Return only cases updated before this Unix timestamp */
302
+ updatedBefore?: number;
303
+ /** Maximum number of cases to return */
304
+ limit?: number;
305
+ /** Pagination offset */
306
+ offset?: number;
307
+ }
308
+
309
+ export interface AddPlanPayload {
310
+ name: string;
311
+ description?: string;
312
+ milestone_id?: number;
313
+ entries?: AddPlanEntryPayload[];
314
+ }
315
+
316
+ export interface UpdatePlanPayload {
317
+ name?: string;
318
+ description?: string;
319
+ milestone_id?: number;
320
+ assignedto_id?: number;
321
+ }
322
+
323
+ export interface AddPlanEntryPayload {
324
+ suite_id: number;
325
+ name?: string;
326
+ description?: string;
327
+ assignedto_id?: number;
328
+ include_all?: boolean;
329
+ case_ids?: number[];
330
+ config_ids?: number[];
331
+ runs?: AddRunPayload[];
332
+ }
333
+
334
+ export interface UpdatePlanEntryPayload {
335
+ suite_id?: number;
336
+ name?: string;
337
+ description?: string;
338
+ assignedto_id?: number;
339
+ include_all?: boolean;
340
+ case_ids?: number[];
341
+ config_ids?: number[];
342
+ runs?: AddRunPayload[];
343
+ }
344
+
345
+ export interface AddRunPayload {
346
+ suite_id?: number;
347
+ name: string;
348
+ description?: string;
349
+ milestone_id?: number;
350
+ assignedto_id?: number;
351
+ include_all?: boolean;
352
+ case_ids?: number[];
353
+ refs?: string;
354
+ }
355
+
356
+ export interface UpdateRunPayload {
357
+ name?: string;
358
+ description?: string;
359
+ milestone_id?: number;
360
+ assignedto_id?: number;
361
+ include_all?: boolean;
362
+ case_ids?: number[];
363
+ refs?: string;
364
+ }
365
+
366
+ export interface AddResultPayload {
367
+ /** e.g., 1=Passed */
368
+ status_id: number;
369
+ comment?: string;
370
+ version?: string;
371
+ elapsed?: string; // e.g. "5m 30s"
372
+ defects?: string;
373
+ assignedto_id?: number;
374
+ custom_fields?: Record<string, unknown>;
375
+ }
376
+
377
+ export interface AddResultsForCasesPayload {
378
+ results: AddResultForCasePayload[];
379
+ }
380
+
381
+ export interface AddResultForCasePayload extends AddResultPayload {
382
+ case_id: number;
383
+ }
384
+
385
+ export interface AddSectionPayload {
386
+ name: string;
387
+ suite_id?: number;
388
+ parent_id?: number;
389
+ description?: string;
390
+ }
391
+
392
+ export interface UpdateSectionPayload {
393
+ name?: string;
394
+ description?: string;
395
+ }
396
+
397
+ export interface AddMilestonePayload {
398
+ name: string;
399
+ description?: string;
400
+ /** Unix timestamp */
401
+ due_on?: number;
402
+ /** Unix timestamp */
403
+ start_on?: number;
404
+ parent_id?: number;
405
+ refs?: string;
406
+ }
407
+
408
+ export interface UpdateMilestonePayload {
409
+ name?: string;
410
+ description?: string;
411
+ /** Unix timestamp */
412
+ due_on?: number;
413
+ /** Unix timestamp */
414
+ start_on?: number;
415
+ parent_id?: number;
416
+ refs?: string;
417
+ is_completed?: boolean;
418
+ is_started?: boolean;
419
+ }
420
+
421
+ export interface GetRunsOptions {
422
+ /** Return only runs created after this Unix timestamp */
423
+ createdAfter?: number;
424
+ /** Return only runs created before this Unix timestamp */
425
+ createdBefore?: number;
426
+ /** Return only runs created by these user IDs (comma-separated list accepted by the API) */
427
+ createdBy?: number[];
428
+ /** `true` to return only completed runs, `false` for active runs */
429
+ isCompleted?: boolean;
430
+ /** Return only runs linked to this milestone ID */
431
+ milestoneId?: number;
432
+ /** Return only runs whose refs field contains this string */
433
+ refsFilter?: string;
434
+ /** Return only runs for this suite ID */
435
+ suiteId?: number;
436
+ /** Maximum number of runs to return */
437
+ limit?: number;
438
+ /** Pagination offset */
439
+ offset?: number;
440
+ }
441
+
442
+ export interface ResultFieldConfig {
443
+ context: {
444
+ is_global: boolean;
445
+ project_ids: number[];
446
+ };
447
+ options: {
448
+ is_required: boolean;
449
+ default_value: string;
450
+ items?: string;
451
+ format?: string;
452
+ rows?: string;
453
+ };
454
+ }
455
+
456
+ export interface ResultField {
457
+ id: number;
458
+ /** System-level name, e.g. "custom_defects" */
459
+ system_name: string;
460
+ /** Human-readable label */
461
+ label: string;
462
+ /** Short name used as the key in result payloads */
463
+ name: string;
464
+ /** Field type identifier (1=String, 2=Integer, 3=Text, 5=Checkbox, 6=Dropdown, …) */
465
+ type_id: number;
466
+ display_order: number;
467
+ /** One or more context/options configurations */
468
+ configs: ResultFieldConfig[];
469
+ is_active: boolean;
470
+ include_all: boolean;
471
+ template_ids: number[];
472
+ description?: string;
473
+ }
474
+
475
+ // ── Case Fields & Types ───────────────────────────────────────────────────────
476
+
477
+ /** Context/options configuration block shared by CaseField entries */
478
+ export interface CaseFieldConfig {
479
+ context: {
480
+ is_global: boolean;
481
+ project_ids: number[];
482
+ };
483
+ options: {
484
+ is_required: boolean;
485
+ default_value: string;
486
+ items?: string;
487
+ format?: string;
488
+ rows?: string;
489
+ };
490
+ }
491
+
492
+ /** Custom case field definition returned by get_case_fields */
493
+ export interface CaseField {
494
+ id: number;
495
+ /** System-level name, e.g. "custom_steps" */
496
+ system_name: string;
497
+ /** Human-readable label */
498
+ label: string;
499
+ /** Short name used as the key in case payloads */
500
+ name: string;
501
+ /** Field type identifier (1=String, 2=Integer, 3=Text, 5=Checkbox, 6=Dropdown, …) */
502
+ type_id: number;
503
+ display_order: number;
504
+ /** One or more context/options configurations */
505
+ configs: CaseFieldConfig[];
506
+ is_active: boolean;
507
+ include_all: boolean;
508
+ template_ids: number[];
509
+ description?: string;
510
+ }
511
+
512
+ /** Case type definition returned by get_case_types */
513
+ export interface CaseType {
514
+ id: number;
515
+ name: string;
516
+ is_default: boolean;
517
+ }
518
+
519
+ // ── Templates ─────────────────────────────────────────────────────────────────
520
+
521
+ /** Case template returned by get_templates (requires TestRail 5.2+) */
522
+ export interface Template {
523
+ id: number;
524
+ name: string;
525
+ is_default: boolean;
526
+ }
527
+
528
+ // ── Configurations ────────────────────────────────────────────────────────────
529
+
530
+ /** An individual configuration (e.g. "Windows 10", "Chrome") within a group */
531
+ export interface Configuration {
532
+ id: number;
533
+ name: string;
534
+ group_id: number;
535
+ }
536
+
537
+ /** A configuration group (e.g. "Operating Systems", "Browsers") */
538
+ export interface ConfigurationGroup {
539
+ id: number;
540
+ name: string;
541
+ project_id: number;
542
+ configs: Configuration[];
543
+ }
544
+
545
+ export interface AddConfigurationGroupPayload {
546
+ /** Name of the new configuration group */
547
+ name: string;
548
+ }
549
+
550
+ export interface UpdateConfigurationGroupPayload {
551
+ /** New name for the configuration group */
552
+ name?: string;
553
+ }
554
+
555
+ export interface AddConfigurationPayload {
556
+ /** Name of the new configuration */
557
+ name: string;
558
+ }
559
+
560
+ export interface UpdateConfigurationPayload {
561
+ /** New name for the configuration */
562
+ name?: string;
563
+ }
564
+
565
+ export interface CacheEntry<T> {
566
+ data: T;
567
+ expiry: number; // Unix timestamp in ms
568
+ }
569
+
570
+ export interface RateLimiterConfig {
571
+ maxRequests: number;
572
+ windowMs: number;
573
+ }
574
+
575
+ export interface AddProjectPayload {
576
+ name: string;
577
+ announcement?: string;
578
+ show_announcement?: boolean;
579
+ suite_mode?: number;
580
+ }
581
+
582
+ export interface UpdateProjectPayload {
583
+ name?: string;
584
+ announcement?: string;
585
+ show_announcement?: boolean;
586
+ suite_mode?: number;
587
+ }
588
+
589
+ /**
590
+ * Filter options for `getPlans()`.
591
+ * All date filters accept Unix timestamps (seconds).
592
+ */
593
+ export interface GetPlansOptions {
594
+ /** Only return plans created after this Unix timestamp */
595
+ created_after?: number;
596
+ /** Only return plans created before this Unix timestamp */
597
+ created_before?: number;
598
+ /** Only return plans created by these user IDs */
599
+ created_by?: number[];
600
+ /** Filter by completion status: 1 = completed, 0 = active */
601
+ is_completed?: 0 | 1;
602
+ /** Only return plans with these milestone IDs */
603
+ milestone_id?: number[];
604
+ /** Maximum number of plans to return */
605
+ limit?: number;
606
+ /** Offset for pagination */
607
+ offset?: number;
608
+ }
609
+
610
+ /**
611
+ * Filter options for `getTests()`.
612
+ */
613
+ export interface GetTestsOptions {
614
+ /** Only return tests with these status IDs */
615
+ status_id?: number[];
616
+ /** Maximum number of tests to return */
617
+ limit?: number;
618
+ /** Offset for pagination */
619
+ offset?: number;
620
+ }
621
+
622
+ /**
623
+ * Filter options for `getResults()`, `getResultsForCase()`, and `getResultsForRun()`.
624
+ * All date filters accept Unix timestamps (seconds).
625
+ */
626
+ export interface GetResultsOptions {
627
+ /** Only return results created after this Unix timestamp */
628
+ created_after?: number;
629
+ /** Only return results created before this Unix timestamp */
630
+ created_before?: number;
631
+ /** Only return results created by these user IDs */
632
+ created_by?: number[];
633
+ /** Only return results with these status IDs */
634
+ status_id?: number[];
635
+ /** Maximum number of results to return */
636
+ limit?: number;
637
+ /** Offset for pagination */
638
+ offset?: number;
639
+ }
640
+
641
+ /**
642
+ * Filter options for `getMilestones()`.
643
+ */
644
+ export interface GetMilestonesOptions {
645
+ /** Filter by completion status: 1 = completed, 0 = active */
646
+ is_completed?: 0 | 1;
647
+ /** Maximum number of milestones to return */
648
+ limit?: number;
649
+ /** Offset for pagination */
650
+ offset?: number;
651
+ }
652
+
653
+ // ── User Management (TASK-024, requires TestRail 7.3+) ────────────────────────
654
+
655
+ /** Payload for creating a new user via POST /add_user (TestRail 7.3+) */
656
+ export interface AddUserPayload {
657
+ /** User's email address */
658
+ email: string;
659
+ /** User's full name */
660
+ name: string;
661
+ /** Whether the user account is active (default: true) */
662
+ is_active?: boolean;
663
+ /** Role ID to assign to the user */
664
+ role_id?: number;
665
+ /** Password for the new user */
666
+ password?: string;
667
+ }
668
+
669
+ /** Payload for updating an existing user via POST /update_user/{user_id} (TestRail 7.3+) */
670
+ export interface UpdateUserPayload {
671
+ /** User's email address */
672
+ email?: string;
673
+ /** User's full name */
674
+ name?: string;
675
+ /** Whether the user account is active */
676
+ is_active?: boolean;
677
+ /** Role ID to assign to the user */
678
+ role_id?: number;
679
+ /** New password for the user */
680
+ password?: string;
681
+ }
682
+
683
+ // ── Roles (TASK-025, requires TestRail 7.3+) ──────────────────────────────────
684
+
685
+ /** A user role returned by GET /get_roles (TestRail 7.3+) */
686
+ export interface Role {
687
+ /** Unique role ID */
688
+ id: number;
689
+ /** Display name of the role */
690
+ name: string;
691
+ /** Whether this is the default role assigned to new users */
692
+ is_default: boolean;
693
+ }
694
+
695
+ // ── Groups (TASK-026, requires TestRail 7.5+) ─────────────────────────────────
696
+
697
+ /** A user group returned by GET /get_group and GET /get_groups (TestRail 7.5+) */
698
+ export interface Group {
699
+ /** Unique group ID */
700
+ id: number;
701
+ /** Display name of the group */
702
+ name: string;
703
+ /** IDs of users belonging to this group */
704
+ user_ids?: number[];
705
+ }
706
+
707
+ /** Payload for creating a new group via POST /add_group (TestRail 7.5+) */
708
+ export interface AddGroupPayload {
709
+ /** Name of the new group */
710
+ name: string;
711
+ /** IDs of users to add to the group */
712
+ user_ids?: number[];
713
+ }
714
+
715
+ /** Payload for updating an existing group via POST /update_group/{group_id} (TestRail 7.5+) */
716
+ export interface UpdateGroupPayload {
717
+ /** New name for the group */
718
+ name?: string;
719
+ /** IDs of users to set as the group members (replaces existing membership) */
720
+ user_ids?: number[];
721
+ }
722
+
723
+ // ── Attachments (TASK-027) ────────────────────────────────────────────────────
724
+
725
+ /** An attachment metadata record returned by attachment list and upload endpoints */
726
+ export interface Attachment {
727
+ /** Unique attachment ID */
728
+ attachment_id: number;
729
+ /** Original filename */
730
+ name: string;
731
+ /** Filename returned by the API (when available) */
732
+ filename?: string;
733
+ /** File size in bytes */
734
+ size?: number;
735
+ /** Unix timestamp when the attachment was created */
736
+ created_on?: number;
737
+ /** ID of the user who created the attachment */
738
+ created_by?: number;
739
+ /** Numeric ID of the entity this attachment belongs to */
740
+ entity_id?: number;
741
+ }
742
+
743
+ // ── Shared Steps (TASK-028, requires TestRail 7.0+) ───────────────────────────
744
+
745
+ /** A shared step set returned by GET /get_shared_step (TestRail 7.0+) */
746
+ export interface SharedStep {
747
+ /** Unique shared step ID */
748
+ id: number;
749
+ /** Display title of the shared step */
750
+ title: string;
751
+ /** ID of the project this shared step belongs to */
752
+ project_id?: number;
753
+ /** Number of cases that reference this shared step */
754
+ case_ids?: number[];
755
+ /** Unix timestamp when created */
756
+ created_on?: number;
757
+ /** ID of the user who created it */
758
+ created_by?: number;
759
+ /** Unix timestamp when last updated */
760
+ updated_on?: number;
761
+ /** ID of the user who last updated it */
762
+ updated_by?: number;
763
+ /** Custom step definitions (varies by template) */
764
+ custom_steps_separated?: Record<string, unknown>[];
765
+ }
766
+
767
+ /** Payload for creating a shared step via POST /add_shared_step/{project_id} (TestRail 7.0+) */
768
+ export interface AddSharedStepPayload {
769
+ /** Title of the shared step */
770
+ title: string;
771
+ /** Step definitions (varies by template configuration) */
772
+ custom_steps_separated?: Record<string, unknown>[];
773
+ }
774
+
775
+ /** Payload for updating a shared step via POST /update_shared_step/{shared_step_id} (TestRail 7.0+) */
776
+ export interface UpdateSharedStepPayload {
777
+ /** New title */
778
+ title?: string;
779
+ /** Updated step definitions */
780
+ custom_steps_separated?: Record<string, unknown>[];
781
+ }
782
+
783
+ // ── Variables (TASK-029) ──────────────────────────────────────────────────────
784
+
785
+ /** A variable used in data-driven testing */
786
+ export interface Variable {
787
+ /** Unique variable ID */
788
+ id: number;
789
+ /** Variable name */
790
+ name: string;
791
+ }
792
+
793
+ /** Payload for creating a variable via POST /add_variable/{project_id} */
794
+ export interface AddVariablePayload {
795
+ /** Variable name */
796
+ name: string;
797
+ }
798
+
799
+ /** Payload for updating a variable via POST /update_variable/{variable_id} */
800
+ export interface UpdateVariablePayload {
801
+ /** New variable name */
802
+ name?: string;
803
+ }
804
+
805
+ // ── Datasets (TASK-030) ───────────────────────────────────────────────────────
806
+
807
+ /** A dataset for data-driven testing */
808
+ export interface Dataset {
809
+ /** Unique dataset ID */
810
+ id: number;
811
+ /** Dataset name */
812
+ name: string;
813
+ /** ID of the project this dataset belongs to */
814
+ project_id?: number;
815
+ /** Unix timestamp when created */
816
+ created_on?: number;
817
+ /** ID of the user who created it */
818
+ created_by?: number;
819
+ }
820
+
821
+ /** Payload for creating a dataset via POST /add_dataset/{project_id} */
822
+ export interface AddDatasetPayload {
823
+ /** Dataset name */
824
+ name: string;
825
+ }
826
+
827
+ /** Payload for updating a dataset via POST /update_dataset/{dataset_id} */
828
+ export interface UpdateDatasetPayload {
829
+ /** New dataset name */
830
+ name?: string;
831
+ }
832
+
833
+ // ── Reports (TASK-031) ────────────────────────────────────────────────────────
834
+
835
+ /** A report template returned by GET /get_reports/{project_id} */
836
+ export interface Report {
837
+ /** Unique report template ID */
838
+ id: number;
839
+ /** Display name of the report */
840
+ name: string;
841
+ /** Description of the report */
842
+ description?: string;
843
+ /** Whether the report is shared with other users */
844
+ is_shared?: boolean;
845
+ }
846
+
847
+ /** Result returned by GET /run_report/{report_template_id} */
848
+ export interface ReportResult {
849
+ /** URL to the generated HTML report */
850
+ report_url: string;
851
+ /** URL to the generated report user interface */
852
+ user_report_url?: string;
853
+ }