@procyon-creative/harvest-sdk 0.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.
@@ -0,0 +1,903 @@
1
+ interface HarvestConfig {
2
+ accountId: string;
3
+ accessToken: string;
4
+ baseUrl?: string;
5
+ userAgent?: string;
6
+ }
7
+ interface PaginationParams {
8
+ page?: number;
9
+ per_page?: number;
10
+ }
11
+ interface PaginationMeta {
12
+ per_page: number;
13
+ total_pages: number;
14
+ total_entries: number;
15
+ next_page: number | null;
16
+ previous_page: number | null;
17
+ page: number;
18
+ }
19
+ interface PaginatedResponse<T> {
20
+ [key: string]: T[] | PaginationMeta | unknown;
21
+ }
22
+ interface Links {
23
+ first: string;
24
+ next: string | null;
25
+ previous: string | null;
26
+ last: string;
27
+ }
28
+
29
+ declare class HarvestClient {
30
+ private readonly baseUrl;
31
+ private readonly headers;
32
+ constructor(config: HarvestConfig);
33
+ get<T>(path: string, params?: Record<string, unknown>): Promise<T>;
34
+ post<T>(path: string, body?: Record<string, unknown>): Promise<T>;
35
+ patch<T>(path: string, body?: Record<string, unknown>): Promise<T>;
36
+ delete(path: string): Promise<void>;
37
+ private request;
38
+ }
39
+
40
+ /**
41
+ * Auto-paginating async iterable.
42
+ *
43
+ * Usage:
44
+ * for await (const entry of harvest.timeEntries.listAll()) { ... }
45
+ * const all = await harvest.timeEntries.listAll().toArray();
46
+ */
47
+ declare class Paginator<T> implements AsyncIterable<T> {
48
+ private readonly client;
49
+ private readonly path;
50
+ private readonly dataKey;
51
+ private readonly params;
52
+ constructor(client: HarvestClient, path: string, dataKey: string, params?: Record<string, unknown>);
53
+ [Symbol.asyncIterator](): AsyncIterableIterator<T>;
54
+ toArray(): Promise<T[]>;
55
+ }
56
+
57
+ declare abstract class BaseResource {
58
+ protected readonly client: HarvestClient;
59
+ constructor(client: HarvestClient);
60
+ }
61
+ /**
62
+ * Generic CRUD resource providing list/get/create/update/delete.
63
+ * Subclasses specify the path and data key used in paginated responses.
64
+ */
65
+ declare abstract class CrudResource<T> extends BaseResource {
66
+ protected abstract readonly path: string;
67
+ protected abstract readonly dataKey: string;
68
+ list(params?: PaginationParams & Record<string, unknown>): Promise<T[]>;
69
+ listAll(params?: Omit<PaginationParams, "page"> & Record<string, unknown>): Paginator<T>;
70
+ get(id: number): Promise<T>;
71
+ create(data: Record<string, unknown>): Promise<T>;
72
+ update(id: number, data: Record<string, unknown>): Promise<T>;
73
+ delete(id: number): Promise<void>;
74
+ }
75
+
76
+ interface Client {
77
+ id: number;
78
+ name: string;
79
+ is_active: boolean;
80
+ address: string | null;
81
+ statement_key: string;
82
+ currency: string;
83
+ created_at: string;
84
+ updated_at: string;
85
+ }
86
+ declare class ClientsResource extends CrudResource<Client> {
87
+ protected readonly path = "/clients";
88
+ protected readonly dataKey = "clients";
89
+ }
90
+
91
+ interface Company {
92
+ base_uri: string;
93
+ full_domain: string;
94
+ name: string;
95
+ is_active: boolean;
96
+ week_start_day: string;
97
+ wants_timestamp_timers: boolean;
98
+ time_format: string;
99
+ date_format: string;
100
+ plan_type: string;
101
+ clock: string;
102
+ decimal_symbol: string;
103
+ thousands_separator: string;
104
+ color_scheme: string;
105
+ weekly_capacity: number;
106
+ expense_feature: boolean;
107
+ invoice_feature: boolean;
108
+ estimate_feature: boolean;
109
+ approval_feature: boolean;
110
+ }
111
+ declare class CompanyResource extends BaseResource {
112
+ get(): Promise<Company>;
113
+ }
114
+
115
+ interface Contact {
116
+ id: number;
117
+ client: {
118
+ id: number;
119
+ name: string;
120
+ };
121
+ title: string | null;
122
+ first_name: string;
123
+ last_name: string | null;
124
+ email: string | null;
125
+ phone_office: string | null;
126
+ phone_mobile: string | null;
127
+ fax: string | null;
128
+ created_at: string;
129
+ updated_at: string;
130
+ }
131
+ declare class ContactsResource extends CrudResource<Contact> {
132
+ protected readonly path = "/contacts";
133
+ protected readonly dataKey = "contacts";
134
+ }
135
+
136
+ interface EstimateItemCategory {
137
+ id: number;
138
+ name: string;
139
+ created_at: string;
140
+ updated_at: string;
141
+ }
142
+ declare class EstimateItemCategoriesResource extends CrudResource<EstimateItemCategory> {
143
+ protected readonly path = "/estimate_item_categories";
144
+ protected readonly dataKey = "estimate_item_categories";
145
+ }
146
+
147
+ interface EstimateLineItem {
148
+ id?: number;
149
+ kind: string;
150
+ description?: string;
151
+ quantity?: number;
152
+ unit_price?: number;
153
+ amount?: number;
154
+ taxed?: boolean;
155
+ taxed2?: boolean;
156
+ }
157
+ interface Estimate {
158
+ id: number;
159
+ client_key: string;
160
+ number: string;
161
+ purchase_order: string | null;
162
+ amount: number;
163
+ tax: number | null;
164
+ tax_amount: number;
165
+ tax2: number | null;
166
+ tax2_amount: number;
167
+ discount: number | null;
168
+ discount_amount: number;
169
+ subject: string | null;
170
+ notes: string | null;
171
+ currency: string;
172
+ state: string;
173
+ issue_date: string | null;
174
+ sent_at: string | null;
175
+ accepted_at: string | null;
176
+ declined_at: string | null;
177
+ created_at: string;
178
+ updated_at: string;
179
+ client: {
180
+ id: number;
181
+ name: string;
182
+ };
183
+ creator: {
184
+ id: number;
185
+ name: string;
186
+ };
187
+ line_items: EstimateLineItem[];
188
+ }
189
+ interface EstimateMessage {
190
+ id: number;
191
+ sent_by: string;
192
+ sent_by_email: string;
193
+ sent_from: string;
194
+ sent_from_email: string;
195
+ recipients: {
196
+ name: string;
197
+ email: string;
198
+ }[];
199
+ subject: string;
200
+ body: string;
201
+ send_me_a_copy: boolean;
202
+ event_type: string | null;
203
+ created_at: string;
204
+ updated_at: string;
205
+ }
206
+ declare class EstimatesResource extends CrudResource<Estimate> {
207
+ protected readonly path = "/estimates";
208
+ protected readonly dataKey = "estimates";
209
+ /** Access messages for an estimate. */
210
+ messages(estimateId: number): EstimateMessagesResource;
211
+ }
212
+ declare class EstimateMessagesResource {
213
+ private readonly client;
214
+ private readonly estimateId;
215
+ constructor(client: HarvestClient, estimateId: number);
216
+ private get path();
217
+ list(params?: PaginationParams & Record<string, unknown>): Promise<EstimateMessage[]>;
218
+ listAll(params?: Record<string, unknown>): Paginator<EstimateMessage>;
219
+ create(data: Record<string, unknown>): Promise<EstimateMessage>;
220
+ delete(id: number): Promise<void>;
221
+ }
222
+
223
+ interface ExpenseCategory {
224
+ id: number;
225
+ name: string;
226
+ unit_name: string | null;
227
+ unit_price: number | null;
228
+ is_active: boolean;
229
+ deactivate_date: string | null;
230
+ created_at: string;
231
+ updated_at: string;
232
+ }
233
+ declare class ExpenseCategoriesResource extends CrudResource<ExpenseCategory> {
234
+ protected readonly path = "/expense_categories";
235
+ protected readonly dataKey = "expense_categories";
236
+ }
237
+
238
+ interface Expense {
239
+ id: number;
240
+ notes: string | null;
241
+ total_cost: number;
242
+ units: number | null;
243
+ is_closed: boolean;
244
+ is_locked: boolean;
245
+ is_billed: boolean;
246
+ locked_reason: string | null;
247
+ spent_date: string;
248
+ billable: boolean;
249
+ receipt: {
250
+ url: string;
251
+ file_name: string;
252
+ file_size: number;
253
+ content_type: string;
254
+ } | null;
255
+ created_at: string;
256
+ updated_at: string;
257
+ user: {
258
+ id: number;
259
+ name: string;
260
+ };
261
+ user_assignment: {
262
+ id: number;
263
+ is_project_manager: boolean;
264
+ is_active: boolean;
265
+ budget: number | null;
266
+ created_at: string;
267
+ updated_at: string;
268
+ hourly_rate: number | null;
269
+ };
270
+ project: {
271
+ id: number;
272
+ name: string;
273
+ code: string;
274
+ };
275
+ expense_category: {
276
+ id: number;
277
+ name: string;
278
+ unit_price: number | null;
279
+ unit_name: string | null;
280
+ };
281
+ client: {
282
+ id: number;
283
+ name: string;
284
+ currency: string;
285
+ };
286
+ invoice: {
287
+ id: number;
288
+ number: string;
289
+ } | null;
290
+ }
291
+ declare class ExpensesResource extends CrudResource<Expense> {
292
+ protected readonly path = "/expenses";
293
+ protected readonly dataKey = "expenses";
294
+ }
295
+
296
+ interface InvoiceItemCategory {
297
+ id: number;
298
+ name: string;
299
+ use_as_service: boolean;
300
+ use_as_expense: boolean;
301
+ created_at: string;
302
+ updated_at: string;
303
+ }
304
+ declare class InvoiceItemCategoriesResource extends CrudResource<InvoiceItemCategory> {
305
+ protected readonly path = "/invoice_item_categories";
306
+ protected readonly dataKey = "invoice_item_categories";
307
+ }
308
+
309
+ interface InvoiceLineItem {
310
+ id?: number;
311
+ kind: string;
312
+ description?: string;
313
+ quantity?: number;
314
+ unit_price?: number;
315
+ amount?: number;
316
+ taxed?: boolean;
317
+ taxed2?: boolean;
318
+ project?: {
319
+ id: number;
320
+ name: string;
321
+ code: string;
322
+ };
323
+ }
324
+ interface Invoice {
325
+ id: number;
326
+ client_key: string;
327
+ number: string;
328
+ purchase_order: string | null;
329
+ amount: number;
330
+ due_amount: number;
331
+ tax: number | null;
332
+ tax_amount: number;
333
+ tax2: number | null;
334
+ tax2_amount: number;
335
+ discount: number | null;
336
+ discount_amount: number;
337
+ subject: string | null;
338
+ notes: string | null;
339
+ currency: string;
340
+ state: string;
341
+ period_start: string | null;
342
+ period_end: string | null;
343
+ issue_date: string;
344
+ due_date: string;
345
+ payment_term: string;
346
+ sent_at: string | null;
347
+ paid_at: string | null;
348
+ paid_date: string | null;
349
+ closed_at: string | null;
350
+ recurring_invoice_id: number | null;
351
+ created_at: string;
352
+ updated_at: string;
353
+ client: {
354
+ id: number;
355
+ name: string;
356
+ };
357
+ estimate: {
358
+ id: number;
359
+ } | null;
360
+ retainer: {
361
+ id: number;
362
+ } | null;
363
+ creator: {
364
+ id: number;
365
+ name: string;
366
+ };
367
+ line_items: InvoiceLineItem[];
368
+ }
369
+ interface InvoiceMessage {
370
+ id: number;
371
+ sent_by: string;
372
+ sent_by_email: string;
373
+ sent_from: string;
374
+ sent_from_email: string;
375
+ recipients: {
376
+ name: string;
377
+ email: string;
378
+ }[];
379
+ subject: string;
380
+ body: string;
381
+ include_link_to_client_invoice: boolean;
382
+ attach_pdf: boolean;
383
+ send_me_a_copy: boolean;
384
+ thank_you: boolean;
385
+ event_type: string | null;
386
+ reminder: boolean;
387
+ send_reminder_on: string | null;
388
+ created_at: string;
389
+ updated_at: string;
390
+ }
391
+ declare class InvoicesResource extends CrudResource<Invoice> {
392
+ protected readonly path = "/invoices";
393
+ protected readonly dataKey = "invoices";
394
+ /** Access messages (send, list, delete) for an invoice. */
395
+ messages(invoiceId: number): InvoiceMessagesResource;
396
+ }
397
+ declare class InvoiceMessagesResource {
398
+ private readonly client;
399
+ private readonly invoiceId;
400
+ constructor(client: HarvestClient, invoiceId: number);
401
+ private get path();
402
+ list(params?: PaginationParams & Record<string, unknown>): Promise<InvoiceMessage[]>;
403
+ listAll(params?: Record<string, unknown>): Paginator<InvoiceMessage>;
404
+ create(data: Record<string, unknown>): Promise<InvoiceMessage>;
405
+ delete(id: number): Promise<void>;
406
+ }
407
+
408
+ interface UserAssignment {
409
+ id: number;
410
+ is_project_manager: boolean;
411
+ is_active: boolean;
412
+ use_default_rates: boolean;
413
+ budget: number | null;
414
+ created_at: string;
415
+ updated_at: string;
416
+ hourly_rate: number | null;
417
+ project: {
418
+ id: number;
419
+ name: string;
420
+ code: string;
421
+ };
422
+ user: {
423
+ id: number;
424
+ name: string;
425
+ };
426
+ }
427
+ /** Top-level user assignments list (across all projects). */
428
+ declare class UserAssignmentsResource extends BaseResource {
429
+ list(params?: PaginationParams & Record<string, unknown>): Promise<UserAssignment[]>;
430
+ listAll(params?: Record<string, unknown>): Paginator<UserAssignment>;
431
+ }
432
+ /** Nested user assignments for a specific project. */
433
+ declare class ProjectUserAssignmentsResource {
434
+ private readonly client;
435
+ private readonly projectId;
436
+ constructor(client: HarvestClient, projectId: number);
437
+ private get path();
438
+ list(params?: PaginationParams & Record<string, unknown>): Promise<UserAssignment[]>;
439
+ listAll(params?: Record<string, unknown>): Paginator<UserAssignment>;
440
+ get(id: number): Promise<UserAssignment>;
441
+ create(data: Record<string, unknown>): Promise<UserAssignment>;
442
+ update(id: number, data: Record<string, unknown>): Promise<UserAssignment>;
443
+ delete(id: number): Promise<void>;
444
+ }
445
+
446
+ interface TaskAssignment {
447
+ id: number;
448
+ billable: boolean;
449
+ is_active: boolean;
450
+ created_at: string;
451
+ updated_at: string;
452
+ hourly_rate: number | null;
453
+ budget: number | null;
454
+ project: {
455
+ id: number;
456
+ name: string;
457
+ code: string;
458
+ };
459
+ task: {
460
+ id: number;
461
+ name: string;
462
+ };
463
+ }
464
+ /** Top-level task assignments list (across all projects). */
465
+ declare class TaskAssignmentsResource extends BaseResource {
466
+ list(params?: PaginationParams & Record<string, unknown>): Promise<TaskAssignment[]>;
467
+ listAll(params?: Record<string, unknown>): Paginator<TaskAssignment>;
468
+ }
469
+ /** Nested task assignments for a specific project. */
470
+ declare class ProjectTaskAssignmentsResource {
471
+ private readonly client;
472
+ private readonly projectId;
473
+ constructor(client: HarvestClient, projectId: number);
474
+ private get path();
475
+ list(params?: PaginationParams & Record<string, unknown>): Promise<TaskAssignment[]>;
476
+ listAll(params?: Record<string, unknown>): Paginator<TaskAssignment>;
477
+ get(id: number): Promise<TaskAssignment>;
478
+ create(data: Record<string, unknown>): Promise<TaskAssignment>;
479
+ update(id: number, data: Record<string, unknown>): Promise<TaskAssignment>;
480
+ delete(id: number): Promise<void>;
481
+ }
482
+
483
+ interface Project {
484
+ id: number;
485
+ name: string;
486
+ code: string;
487
+ is_active: boolean;
488
+ is_billable: boolean;
489
+ is_fixed_fee: boolean;
490
+ bill_by: string;
491
+ budget: number | null;
492
+ budget_by: string;
493
+ budget_is_monthly: boolean;
494
+ notify_when_over_budget: boolean;
495
+ over_budget_notification_percentage: number;
496
+ over_budget_notification_date: string | null;
497
+ show_budget_to_all: boolean;
498
+ cost_budget: number | null;
499
+ cost_budget_include_expenses: boolean;
500
+ hourly_rate: number | null;
501
+ fee: number | null;
502
+ notes: string | null;
503
+ starts_on: string | null;
504
+ ends_on: string | null;
505
+ created_at: string;
506
+ updated_at: string;
507
+ client: {
508
+ id: number;
509
+ name: string;
510
+ currency: string;
511
+ };
512
+ }
513
+ declare class ProjectsResource extends CrudResource<Project> {
514
+ protected readonly path = "/projects";
515
+ protected readonly dataKey = "projects";
516
+ /** Access user assignments nested under a project. */
517
+ userAssignments(projectId: number): ProjectUserAssignmentsResource;
518
+ /** Access task assignments nested under a project. */
519
+ taskAssignments(projectId: number): ProjectTaskAssignmentsResource;
520
+ }
521
+
522
+ interface TimeReportResult {
523
+ client_id: number;
524
+ client_name: string;
525
+ project_id: number;
526
+ project_name: string;
527
+ task_id?: number;
528
+ task_name?: string;
529
+ user_id?: number;
530
+ user_name?: string;
531
+ total_hours: number;
532
+ billable_hours: number;
533
+ currency: string;
534
+ billable_amount: number;
535
+ }
536
+ interface TimeReport {
537
+ results: TimeReportResult[];
538
+ per_page: number;
539
+ total_pages: number;
540
+ total_entries: number;
541
+ next_page: number | null;
542
+ previous_page: number | null;
543
+ page: number;
544
+ }
545
+ interface ExpenseReportResult {
546
+ client_id: number;
547
+ client_name: string;
548
+ project_id?: number;
549
+ project_name?: string;
550
+ expense_category_id?: number;
551
+ expense_category_name?: string;
552
+ user_id?: number;
553
+ user_name?: string;
554
+ total_amount: number;
555
+ billable_amount: number;
556
+ currency: string;
557
+ }
558
+ interface ExpenseReport {
559
+ results: ExpenseReportResult[];
560
+ per_page: number;
561
+ total_pages: number;
562
+ total_entries: number;
563
+ next_page: number | null;
564
+ previous_page: number | null;
565
+ page: number;
566
+ }
567
+ interface UninvoicedReport {
568
+ results: {
569
+ client_id: number;
570
+ client_name: string;
571
+ project_id: number;
572
+ project_name: string;
573
+ currency: string;
574
+ total_hours: number;
575
+ uninvoiced_hours: number;
576
+ uninvoiced_expenses: number;
577
+ uninvoiced_amount: number;
578
+ }[];
579
+ per_page: number;
580
+ total_pages: number;
581
+ total_entries: number;
582
+ next_page: number | null;
583
+ previous_page: number | null;
584
+ page: number;
585
+ }
586
+ interface ProjectBudgetReport {
587
+ results: {
588
+ client_id: number;
589
+ client_name: string;
590
+ project_id: number;
591
+ project_name: string;
592
+ budget_is_monthly: boolean;
593
+ budget_by: string;
594
+ is_active: boolean;
595
+ budget: number;
596
+ budget_spent: number;
597
+ budget_remaining: number;
598
+ }[];
599
+ per_page: number;
600
+ total_pages: number;
601
+ total_entries: number;
602
+ next_page: number | null;
603
+ previous_page: number | null;
604
+ page: number;
605
+ }
606
+ interface ReportParams {
607
+ from: string;
608
+ to: string;
609
+ page?: number;
610
+ per_page?: number;
611
+ [key: string]: unknown;
612
+ }
613
+ declare class TimeReports {
614
+ private readonly client;
615
+ constructor(client: HarvestClient);
616
+ byClients(params: ReportParams): Promise<TimeReport>;
617
+ byProjects(params: ReportParams): Promise<TimeReport>;
618
+ byTasks(params: ReportParams): Promise<TimeReport>;
619
+ byTeam(params: ReportParams): Promise<TimeReport>;
620
+ }
621
+ declare class ExpenseReports {
622
+ private readonly client;
623
+ constructor(client: HarvestClient);
624
+ byClients(params: ReportParams): Promise<ExpenseReport>;
625
+ byProjects(params: ReportParams): Promise<ExpenseReport>;
626
+ byCategories(params: ReportParams): Promise<ExpenseReport>;
627
+ byTeam(params: ReportParams): Promise<ExpenseReport>;
628
+ }
629
+ declare class ReportsResource {
630
+ private readonly client;
631
+ readonly time: TimeReports;
632
+ readonly expenses: ExpenseReports;
633
+ constructor(client: HarvestClient);
634
+ uninvoiced(params: ReportParams): Promise<UninvoicedReport>;
635
+ projectBudget(params?: Record<string, unknown>): Promise<ProjectBudgetReport>;
636
+ }
637
+
638
+ interface Role {
639
+ id: number;
640
+ name: string;
641
+ user_ids: number[];
642
+ created_at: string;
643
+ updated_at: string;
644
+ }
645
+ declare class RolesResource extends CrudResource<Role> {
646
+ protected readonly path = "/roles";
647
+ protected readonly dataKey = "roles";
648
+ }
649
+
650
+ interface Task {
651
+ id: number;
652
+ name: string;
653
+ billable_by_default: boolean;
654
+ default_hourly_rate: number | null;
655
+ is_default: boolean;
656
+ is_active: boolean;
657
+ created_at: string;
658
+ updated_at: string;
659
+ }
660
+ declare class TasksResource extends CrudResource<Task> {
661
+ protected readonly path = "/tasks";
662
+ protected readonly dataKey = "tasks";
663
+ }
664
+
665
+ interface TimeEntry {
666
+ id: number;
667
+ spent_date: string;
668
+ hours: number;
669
+ hours_without_timer: number;
670
+ rounded_hours: number;
671
+ notes: string | null;
672
+ is_locked: boolean;
673
+ locked_reason: string | null;
674
+ is_closed: boolean;
675
+ is_billed: boolean;
676
+ timer_started_at: string | null;
677
+ started_time: string | null;
678
+ ended_time: string | null;
679
+ is_running: boolean;
680
+ billable: boolean;
681
+ budgeted: boolean;
682
+ billable_rate: number | null;
683
+ cost_rate: number | null;
684
+ created_at: string;
685
+ updated_at: string;
686
+ user: {
687
+ id: number;
688
+ name: string;
689
+ };
690
+ client: {
691
+ id: number;
692
+ name: string;
693
+ currency: string;
694
+ };
695
+ project: {
696
+ id: number;
697
+ name: string;
698
+ code: string;
699
+ };
700
+ task: {
701
+ id: number;
702
+ name: string;
703
+ };
704
+ user_assignment: {
705
+ id: number;
706
+ is_project_manager: boolean;
707
+ is_active: boolean;
708
+ budget: number | null;
709
+ created_at: string;
710
+ updated_at: string;
711
+ hourly_rate: number | null;
712
+ };
713
+ task_assignment: {
714
+ id: number;
715
+ billable: boolean;
716
+ is_active: boolean;
717
+ created_at: string;
718
+ updated_at: string;
719
+ hourly_rate: number | null;
720
+ budget: number | null;
721
+ };
722
+ invoice: {
723
+ id: number;
724
+ number: string;
725
+ } | null;
726
+ external_reference: {
727
+ id: string;
728
+ group_id: string;
729
+ account_id: string;
730
+ permalink: string;
731
+ } | null;
732
+ }
733
+ declare class TimeEntriesResource extends CrudResource<TimeEntry> {
734
+ protected readonly path = "/time_entries";
735
+ protected readonly dataKey = "time_entries";
736
+ /** Stop a running time entry timer. */
737
+ stop(id: number): Promise<TimeEntry>;
738
+ /** Restart a stopped time entry timer. */
739
+ restart(id: number): Promise<TimeEntry>;
740
+ /** Delete external reference for a time entry. */
741
+ deleteExternalReference(id: number): Promise<void>;
742
+ }
743
+
744
+ interface User {
745
+ id: number;
746
+ first_name: string;
747
+ last_name: string;
748
+ email: string;
749
+ telephone: string;
750
+ timezone: string;
751
+ has_access_to_all_future_projects: boolean;
752
+ is_contractor: boolean;
753
+ is_active: boolean;
754
+ weekly_capacity: number;
755
+ default_hourly_rate: number | null;
756
+ cost_rate: number | null;
757
+ roles: string[];
758
+ access_roles: string[];
759
+ avatar_url: string;
760
+ created_at: string;
761
+ updated_at: string;
762
+ }
763
+ interface BillableRate {
764
+ id: number;
765
+ amount: number;
766
+ start_date: string | null;
767
+ end_date: string | null;
768
+ created_at: string;
769
+ updated_at: string;
770
+ }
771
+ interface CostRate {
772
+ id: number;
773
+ amount: number;
774
+ start_date: string | null;
775
+ end_date: string | null;
776
+ created_at: string;
777
+ updated_at: string;
778
+ }
779
+ interface ProjectAssignment {
780
+ id: number;
781
+ is_project_manager: boolean;
782
+ is_active: boolean;
783
+ use_default_rates: boolean;
784
+ budget: number | null;
785
+ created_at: string;
786
+ updated_at: string;
787
+ hourly_rate: number | null;
788
+ project: {
789
+ id: number;
790
+ name: string;
791
+ code: string;
792
+ };
793
+ client: {
794
+ id: number;
795
+ name: string;
796
+ };
797
+ task_assignments: {
798
+ id: number;
799
+ billable: boolean;
800
+ is_active: boolean;
801
+ created_at: string;
802
+ updated_at: string;
803
+ hourly_rate: number | null;
804
+ budget: number | null;
805
+ task: {
806
+ id: number;
807
+ name: string;
808
+ };
809
+ }[];
810
+ }
811
+ declare class UsersResource extends CrudResource<User> {
812
+ protected readonly path = "/users";
813
+ protected readonly dataKey = "users";
814
+ /** Retrieve the currently authenticated user. */
815
+ me(): Promise<User>;
816
+ /** List project assignments for the current user. */
817
+ myProjectAssignments(params?: PaginationParams & Record<string, unknown>): Promise<ProjectAssignment[]>;
818
+ /** Access billable rates for a user. */
819
+ billableRates(userId: number): UserBillableRatesResource;
820
+ /** Access cost rates for a user. */
821
+ costRates(userId: number): UserCostRatesResource;
822
+ /** Access teammates for a user. */
823
+ teammates(userId: number): UserTeammatesResource;
824
+ /** List project assignments for a specific user. */
825
+ projectAssignments(userId: number): UserProjectAssignmentsResource;
826
+ }
827
+ declare class UserBillableRatesResource {
828
+ private readonly client;
829
+ private readonly userId;
830
+ constructor(client: HarvestClient, userId: number);
831
+ private get path();
832
+ list(params?: PaginationParams & Record<string, unknown>): Promise<BillableRate[]>;
833
+ listAll(params?: Record<string, unknown>): Paginator<BillableRate>;
834
+ get(id: number): Promise<BillableRate>;
835
+ create(data: Record<string, unknown>): Promise<BillableRate>;
836
+ }
837
+ declare class UserCostRatesResource {
838
+ private readonly client;
839
+ private readonly userId;
840
+ constructor(client: HarvestClient, userId: number);
841
+ private get path();
842
+ list(params?: PaginationParams & Record<string, unknown>): Promise<CostRate[]>;
843
+ listAll(params?: Record<string, unknown>): Paginator<CostRate>;
844
+ get(id: number): Promise<CostRate>;
845
+ create(data: Record<string, unknown>): Promise<CostRate>;
846
+ }
847
+ declare class UserTeammatesResource {
848
+ private readonly client;
849
+ private readonly userId;
850
+ constructor(client: HarvestClient, userId: number);
851
+ private get path();
852
+ list(params?: PaginationParams & Record<string, unknown>): Promise<User[]>;
853
+ /** Update (replace) teammates for a user. */
854
+ update(data: Record<string, unknown>): Promise<User[]>;
855
+ }
856
+ declare class UserProjectAssignmentsResource {
857
+ private readonly client;
858
+ private readonly userId;
859
+ constructor(client: HarvestClient, userId: number);
860
+ private get path();
861
+ list(params?: PaginationParams & Record<string, unknown>): Promise<ProjectAssignment[]>;
862
+ listAll(params?: Record<string, unknown>): Paginator<ProjectAssignment>;
863
+ }
864
+
865
+ declare class HarvestApiError extends Error {
866
+ readonly status: number;
867
+ readonly statusText: string;
868
+ readonly body: unknown;
869
+ constructor(status: number, statusText: string, body: unknown);
870
+ }
871
+ declare class HarvestRateLimitError extends HarvestApiError {
872
+ readonly retryAfter: number;
873
+ constructor(retryAfter: number, body: unknown);
874
+ }
875
+ declare class HarvestNotFoundError extends HarvestApiError {
876
+ constructor(body: unknown);
877
+ }
878
+ declare class HarvestUnprocessableError extends HarvestApiError {
879
+ constructor(body: unknown);
880
+ }
881
+
882
+ declare class Harvest {
883
+ readonly clients: ClientsResource;
884
+ readonly company: CompanyResource;
885
+ readonly contacts: ContactsResource;
886
+ readonly estimateItemCategories: EstimateItemCategoriesResource;
887
+ readonly estimates: EstimatesResource;
888
+ readonly expenseCategories: ExpenseCategoriesResource;
889
+ readonly expenses: ExpensesResource;
890
+ readonly invoiceItemCategories: InvoiceItemCategoriesResource;
891
+ readonly invoices: InvoicesResource;
892
+ readonly projects: ProjectsResource;
893
+ readonly reports: ReportsResource;
894
+ readonly roles: RolesResource;
895
+ readonly taskAssignments: TaskAssignmentsResource;
896
+ readonly tasks: TasksResource;
897
+ readonly timeEntries: TimeEntriesResource;
898
+ readonly userAssignments: UserAssignmentsResource;
899
+ readonly users: UsersResource;
900
+ constructor(config: HarvestConfig);
901
+ }
902
+
903
+ export { type BillableRate, type Client, ClientsResource, type Company, CompanyResource, type Contact, ContactsResource, type CostRate, type Estimate, EstimateItemCategoriesResource, type EstimateItemCategory, type EstimateLineItem, type EstimateMessage, EstimateMessagesResource, EstimatesResource, type Expense, ExpenseCategoriesResource, type ExpenseCategory, type ExpenseReport, type ExpenseReportResult, ExpenseReports, ExpensesResource, Harvest, HarvestApiError, HarvestClient, type HarvestConfig, HarvestNotFoundError, HarvestRateLimitError, HarvestUnprocessableError, type Invoice, InvoiceItemCategoriesResource, type InvoiceItemCategory, type InvoiceLineItem, type InvoiceMessage, InvoiceMessagesResource, InvoicesResource, type Links, type PaginatedResponse, type PaginationMeta, type PaginationParams, Paginator, type Project, type ProjectAssignment, type ProjectBudgetReport, ProjectTaskAssignmentsResource, ProjectUserAssignmentsResource, ProjectsResource, type ReportParams, ReportsResource, type Role, RolesResource, type Task, type TaskAssignment, TaskAssignmentsResource, TasksResource, TimeEntriesResource, type TimeEntry, type TimeReport, type TimeReportResult, TimeReports, type UninvoicedReport, type User, type UserAssignment, UserAssignmentsResource, UserBillableRatesResource, UserCostRatesResource, UserProjectAssignmentsResource, UserTeammatesResource, UsersResource };