@timesheet/sdk 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -1
- package/README.md +74 -1
- package/dist/index.d.mts +89 -3
- package/dist/index.d.ts +89 -3
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
## [1.0.4] - 2026-01-04
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- OAuth 2.1 Discovery support (RFC 8414):
|
|
13
|
+
- `OAuthDiscovery` class for endpoint discovery from `/.well-known/oauth-authorization-server`
|
|
14
|
+
- Support for Protected Resource Metadata (RFC 9728)
|
|
15
|
+
- Support for OpenID Connect Discovery (`/.well-known/openid-configuration`)
|
|
16
|
+
- Discovery result caching with configurable TTL
|
|
17
|
+
- `discoverOAuth()` convenience function for quick discovery
|
|
18
|
+
- Custom `authorizationEndpoint` and `tokenEndpoint` options in OAuth21Auth methods
|
|
19
|
+
|
|
9
20
|
## [1.0.3] - 2026-01-04
|
|
10
21
|
|
|
11
22
|
### Added
|
|
@@ -89,7 +100,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
89
100
|
- Removed complex mocking in favor of simple validation tests
|
|
90
101
|
- Updated GitHub Actions to use non-deprecated action versions
|
|
91
102
|
|
|
92
|
-
[Unreleased]: https://github.com/timesheetIO/timesheet-typescript/compare/v1.0.
|
|
103
|
+
[Unreleased]: https://github.com/timesheetIO/timesheet-typescript/compare/v1.0.4...HEAD
|
|
104
|
+
[1.0.4]: https://github.com/timesheetIO/timesheet-typescript/compare/v1.0.3...v1.0.4
|
|
93
105
|
[1.0.3]: https://github.com/timesheetIO/timesheet-typescript/compare/v1.0.2...v1.0.3
|
|
94
106
|
[1.0.2]: https://github.com/timesheetIO/timesheet-typescript/compare/v1.0.1...v1.0.2
|
|
95
107
|
[1.0.1]: https://github.com/timesheetIO/timesheet-typescript/compare/v1.0.0...v1.0.1
|
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ The official TypeScript SDK for the [Timesheet API](https://timesheet.io), provi
|
|
|
12
12
|
|
|
13
13
|
- ✅ **Type-Safe** - Full TypeScript support with comprehensive types
|
|
14
14
|
- ✅ **Modern Architecture** - Promise-based with async/await support
|
|
15
|
-
- ✅ **Authentication** - Built-in API Key, OAuth2, and OAuth 2.1 (PKCE)
|
|
15
|
+
- ✅ **Authentication** - Built-in API Key, OAuth2, and OAuth 2.1 (PKCE) with automatic discovery (RFC 8414)
|
|
16
16
|
- ✅ **Error Handling** - Typed exceptions for better error management
|
|
17
17
|
- ✅ **Pagination** - Automatic pagination with async iterators
|
|
18
18
|
- ✅ **Retry Logic** - Configurable retry with exponential backoff
|
|
@@ -127,6 +127,79 @@ const client = new TimesheetClient({
|
|
|
127
127
|
});
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
+
#### OAuth 2.1 with Endpoint Discovery (RFC 8414)
|
|
131
|
+
|
|
132
|
+
The SDK supports automatic endpoint discovery from `/.well-known/oauth-authorization-server`, allowing you to dynamically configure OAuth endpoints:
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import { OAuth21Auth, OAuthDiscovery, generatePkceCodePair } from '@timesheet/sdk';
|
|
136
|
+
|
|
137
|
+
// Step 1: Discover OAuth endpoints
|
|
138
|
+
const discovery = new OAuthDiscovery();
|
|
139
|
+
const metadata = await discovery.discover('https://api.timesheet.io');
|
|
140
|
+
|
|
141
|
+
console.log('Authorization endpoint:', metadata.authorizationServer.authorization_endpoint);
|
|
142
|
+
console.log('Token endpoint:', metadata.authorizationServer.token_endpoint);
|
|
143
|
+
console.log('Supported scopes:', metadata.authorizationServer.scopes_supported);
|
|
144
|
+
|
|
145
|
+
// Step 2: Generate PKCE and build authorization URL using discovered endpoints
|
|
146
|
+
const pkce = generatePkceCodePair();
|
|
147
|
+
|
|
148
|
+
const authUrl = OAuth21Auth.buildAuthorizationUrl({
|
|
149
|
+
clientId: 'your-client-id',
|
|
150
|
+
redirectUri: 'https://your-app.com/callback',
|
|
151
|
+
codeChallenge: pkce.codeChallenge,
|
|
152
|
+
codeChallengeMethod: pkce.codeChallengeMethod,
|
|
153
|
+
scope: 'read write',
|
|
154
|
+
state: 'random-csrf-state',
|
|
155
|
+
authorizationEndpoint: metadata.authorizationServer.authorization_endpoint,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Store pkce.codeVerifier and token endpoint securely, then redirect user
|
|
159
|
+
sessionStorage.setItem('pkce_verifier', pkce.codeVerifier);
|
|
160
|
+
sessionStorage.setItem('token_endpoint', metadata.authorizationServer.token_endpoint);
|
|
161
|
+
|
|
162
|
+
// Step 3: After callback, exchange code using discovered token endpoint
|
|
163
|
+
const auth = await OAuth21Auth.fromAuthorizationCode({
|
|
164
|
+
clientId: 'your-client-id',
|
|
165
|
+
authorizationCode: codeFromCallback,
|
|
166
|
+
redirectUri: 'https://your-app.com/callback',
|
|
167
|
+
codeVerifier: sessionStorage.getItem('pkce_verifier'),
|
|
168
|
+
tokenEndpoint: sessionStorage.getItem('token_endpoint'),
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
const client = new TimesheetClient({
|
|
172
|
+
authentication: auth
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
The `OAuthDiscovery` class provides caching and additional discovery options:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import { OAuthDiscovery, discoverOAuth } from '@timesheet/sdk';
|
|
180
|
+
|
|
181
|
+
// Using convenience function (uses shared cached instance)
|
|
182
|
+
const result = await discoverOAuth('https://api.timesheet.io');
|
|
183
|
+
|
|
184
|
+
// Using class with custom options
|
|
185
|
+
const discovery = new OAuthDiscovery({
|
|
186
|
+
cacheTtl: 3600000, // Cache for 1 hour (default)
|
|
187
|
+
timeout: 10000, // Request timeout in ms
|
|
188
|
+
fetchOpenIdConfig: true, // Also fetch OpenID Connect config
|
|
189
|
+
fetchProtectedResource: true, // Also fetch protected resource metadata (RFC 9728)
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
const metadata = await discovery.discover('https://api.timesheet.io');
|
|
193
|
+
|
|
194
|
+
// Check cache status
|
|
195
|
+
if (discovery.isCached('https://api.timesheet.io')) {
|
|
196
|
+
console.log('Using cached metadata');
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Clear cache when needed
|
|
200
|
+
discovery.clearCache();
|
|
201
|
+
```
|
|
202
|
+
|
|
130
203
|
#### Using OAuth 2.1 with existing tokens
|
|
131
204
|
|
|
132
205
|
```typescript
|
package/dist/index.d.mts
CHANGED
|
@@ -57,6 +57,7 @@ interface AuthorizationUrlOptions {
|
|
|
57
57
|
state?: string;
|
|
58
58
|
scope?: string;
|
|
59
59
|
resource?: string;
|
|
60
|
+
authorizationEndpoint?: string;
|
|
60
61
|
}
|
|
61
62
|
interface TokenExchangeOptions {
|
|
62
63
|
clientId: string;
|
|
@@ -65,21 +66,24 @@ interface TokenExchangeOptions {
|
|
|
65
66
|
redirectUri: string;
|
|
66
67
|
codeVerifier: string;
|
|
67
68
|
resource?: string;
|
|
69
|
+
tokenEndpoint?: string;
|
|
68
70
|
}
|
|
69
71
|
interface OAuth21RefreshOptions {
|
|
70
72
|
clientId: string;
|
|
71
73
|
clientSecret?: string;
|
|
72
74
|
refreshToken: string;
|
|
73
75
|
resource?: string;
|
|
76
|
+
tokenEndpoint?: string;
|
|
74
77
|
}
|
|
75
78
|
declare class OAuth21Auth implements Authentication {
|
|
76
|
-
private static readonly
|
|
77
|
-
private static readonly
|
|
79
|
+
private static readonly DEFAULT_TOKEN_ENDPOINT;
|
|
80
|
+
private static readonly DEFAULT_AUTH_ENDPOINT;
|
|
78
81
|
private accessToken;
|
|
79
82
|
private refreshToken?;
|
|
80
83
|
private readonly clientId?;
|
|
81
84
|
private readonly clientSecret?;
|
|
82
85
|
private readonly resource?;
|
|
86
|
+
private readonly tokenEndpoint;
|
|
83
87
|
private tokenExpiry?;
|
|
84
88
|
private refreshPromise?;
|
|
85
89
|
constructor(accessToken: string);
|
|
@@ -95,6 +99,88 @@ declare class OAuth21Auth implements Authentication {
|
|
|
95
99
|
private parseTokenExpiry;
|
|
96
100
|
}
|
|
97
101
|
|
|
102
|
+
interface AuthorizationServerMetadata {
|
|
103
|
+
issuer: string;
|
|
104
|
+
authorization_endpoint: string;
|
|
105
|
+
token_endpoint: string;
|
|
106
|
+
registration_endpoint?: string;
|
|
107
|
+
scopes_supported?: string[];
|
|
108
|
+
response_types_supported: string[];
|
|
109
|
+
grant_types_supported?: string[];
|
|
110
|
+
token_endpoint_auth_methods_supported?: string[];
|
|
111
|
+
code_challenge_methods_supported?: string[];
|
|
112
|
+
revocation_endpoint?: string;
|
|
113
|
+
revocation_endpoint_auth_methods_supported?: string[];
|
|
114
|
+
introspection_endpoint?: string;
|
|
115
|
+
introspection_endpoint_auth_methods_supported?: string[];
|
|
116
|
+
service_documentation?: string;
|
|
117
|
+
}
|
|
118
|
+
interface ProtectedResourceMetadata {
|
|
119
|
+
resource: string;
|
|
120
|
+
authorization_servers: string[];
|
|
121
|
+
scopes_supported?: string[];
|
|
122
|
+
bearer_methods_supported?: string[];
|
|
123
|
+
resource_documentation?: string;
|
|
124
|
+
resource_signing_alg_values_supported?: string[];
|
|
125
|
+
}
|
|
126
|
+
interface OpenIdConfiguration {
|
|
127
|
+
issuer: string;
|
|
128
|
+
authorization_endpoint: string;
|
|
129
|
+
token_endpoint: string;
|
|
130
|
+
userinfo_endpoint?: string;
|
|
131
|
+
jwks_uri: string;
|
|
132
|
+
registration_endpoint?: string;
|
|
133
|
+
scopes_supported?: string[];
|
|
134
|
+
response_types_supported: string[];
|
|
135
|
+
response_modes_supported?: string[];
|
|
136
|
+
grant_types_supported?: string[];
|
|
137
|
+
token_endpoint_auth_methods_supported?: string[];
|
|
138
|
+
token_endpoint_auth_signing_alg_values_supported?: string[];
|
|
139
|
+
service_documentation?: string;
|
|
140
|
+
ui_locales_supported?: string[];
|
|
141
|
+
op_policy_uri?: string;
|
|
142
|
+
op_tos_uri?: string;
|
|
143
|
+
revocation_endpoint?: string;
|
|
144
|
+
introspection_endpoint?: string;
|
|
145
|
+
code_challenge_methods_supported?: string[];
|
|
146
|
+
}
|
|
147
|
+
interface OAuthDiscoveryResult {
|
|
148
|
+
issuer: string;
|
|
149
|
+
authorizationServer: AuthorizationServerMetadata;
|
|
150
|
+
protectedResource?: ProtectedResourceMetadata;
|
|
151
|
+
openIdConfiguration?: OpenIdConfiguration;
|
|
152
|
+
fetchedAt: Date;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
interface OAuthDiscoveryOptions {
|
|
156
|
+
cacheTtl?: number;
|
|
157
|
+
timeout?: number;
|
|
158
|
+
fetchOpenIdConfig?: boolean;
|
|
159
|
+
fetchProtectedResource?: boolean;
|
|
160
|
+
}
|
|
161
|
+
declare class OAuthDiscovery {
|
|
162
|
+
private static readonly DEFAULT_CACHE_TTL;
|
|
163
|
+
private static readonly DEFAULT_TIMEOUT;
|
|
164
|
+
private readonly cache;
|
|
165
|
+
private readonly options;
|
|
166
|
+
constructor(options?: OAuthDiscoveryOptions);
|
|
167
|
+
discover(issuerUrl: string): Promise<OAuthDiscoveryResult>;
|
|
168
|
+
fetchAuthorizationServerMetadata(issuerUrl: string): Promise<AuthorizationServerMetadata>;
|
|
169
|
+
fetchOpenIdConfiguration(issuerUrl: string): Promise<OpenIdConfiguration>;
|
|
170
|
+
fetchProtectedResourceMetadata(resourceUrl: string): Promise<ProtectedResourceMetadata>;
|
|
171
|
+
clearCache(): void;
|
|
172
|
+
clearCacheForIssuer(issuerUrl: string): void;
|
|
173
|
+
isCached(issuerUrl: string): boolean;
|
|
174
|
+
private normalizeIssuerUrl;
|
|
175
|
+
private getCached;
|
|
176
|
+
private setCache;
|
|
177
|
+
private validateAuthorizationServerMetadata;
|
|
178
|
+
private validateOpenIdConfiguration;
|
|
179
|
+
private validateProtectedResourceMetadata;
|
|
180
|
+
}
|
|
181
|
+
declare function getDefaultDiscovery(): OAuthDiscovery;
|
|
182
|
+
declare function discoverOAuth(issuerUrl: string, options?: OAuthDiscoveryOptions): Promise<OAuthDiscoveryResult>;
|
|
183
|
+
|
|
98
184
|
declare class RetryConfig {
|
|
99
185
|
readonly maxRetries: number;
|
|
100
186
|
readonly initialDelay: number;
|
|
@@ -1847,4 +1933,4 @@ interface TimesheetClientOptions {
|
|
|
1847
1933
|
}
|
|
1848
1934
|
declare function createClient(options: TimesheetClientOptions): TimesheetClient;
|
|
1849
1935
|
|
|
1850
|
-
export { type Activity, ApiClient, ApiKeyAuth, type Authentication, type AuthorizationUrlOptions, type Automation, type AutomationCreateRequest, type AutomationList, type AutomationListParams, AutomationResource, type AutomationUpdateRequest, type ClientConfig, type CodeChallengeMethod, type CustomExportField, type CustomExportFieldCreateRequest, type CustomExportFieldUpdateRequest, type CustomExportFieldsResponse, type Document, type DocumentCreateRequest, type DocumentList, type DocumentListParams, type DocumentPrint, type DocumentReport, DocumentReportResource, DocumentResource, type DocumentUpdateRequest, type Expense, type ExpenseCreateRequest, type ExpenseList, type ExpenseListParams, type ExpenseReportItem, ExpenseReportResource, ExpenseResource, type ExpenseStatus, type ExpenseUpdateRequest, type ExportFieldDefinition, type ExportFieldsResponse, type ExportFormat, type ExportParams, type ExportReportType, type ExportReportsResponse, ExportResource, type ExportTemplate, type ExportTemplateCreateRequest, type ExportTemplateListParams, type ExportTemplateParams, type ExportTemplateUpdateRequest, type ExportedField, type FileResponse, type ListParams, type Member, NavigablePage, type Note, type NoteCreateRequest, type NoteList, type NoteListParams, type NoteReportItem, NoteReportResource, NoteResource, type NoteUpdateRequest, OAuth21Auth, type OAuth21RefreshOptions, OAuth2Auth, type Organization, type OrganizationCreateRequest, type OrganizationList, type OrganizationListParams, OrganizationResource, type OrganizationUpdateRequest, type Page, type PageParams, type Pause, type PauseCreateRequest, type PauseList, type PauseListParams, PauseResource, type PauseUpdateRequest, type PkceCodePair, type Profile, ProfileResource, type ProfileUpdateRequest, type Project, type ProjectCreateRequest, type ProjectList, type ProjectListParams, type ProjectMember, ProjectResource, type ProjectUpdateRequest, type Rate, type RateCreateRequest, type RateList, type RateListParams, RateResource, type RateUpdateRequest, ReportsClient, Resource, RetryConfig, type RetryConfigOptions, type Settings, SettingsResource, type SettingsUpdateRequest, type SortablePageParams, type Tag, type TagCreateRequest, type TagList, type TagListParams, TagResource, type TagUpdateRequest, type Task, type TaskCreateRequest, type TaskList, type TaskListParams, type TaskPerformance, type TaskReportItem, TaskReportResource, TaskResource, type TaskStatistic, type TaskStatusUpdateRequest, type TaskTimesUpdateRequest, type TaskUpdateRequest, type Team, type TeamCreateRequest, type TeamList, type TeamListParams, type TeamMember, type TeamMemberList, type TeamMemberListParams, TeamResource, type TeamUpdateRequest, type Timer, type TimerPauseRequest, TimerResource, type TimerResumeRequest, type TimerStartRequest, type TimerStopRequest, type TimerUpdateRequest, TimesheetApiError, TimesheetAuthError, TimesheetClient, type TimesheetClientOptions, TimesheetRateLimitError, type Todo, type TodoCreateRequest, type TodoList, type TodoListParams, TodoResource, type TodoUpdateRequest, type TokenExchangeOptions, type Webhook, type WebhookCreateRequest, type WebhookEventType, WebhookEvents, type WebhookList, type WebhookListParams, WebhookResource, type WebhookUpdateRequest, combineWebhookEvents, createClient, generateCodeChallenge, generateCodeVerifier, generatePkceCodePair, isValidCodeVerifier };
|
|
1936
|
+
export { type Activity, ApiClient, ApiKeyAuth, type Authentication, type AuthorizationServerMetadata, type AuthorizationUrlOptions, type Automation, type AutomationCreateRequest, type AutomationList, type AutomationListParams, AutomationResource, type AutomationUpdateRequest, type ClientConfig, type CodeChallengeMethod, type CustomExportField, type CustomExportFieldCreateRequest, type CustomExportFieldUpdateRequest, type CustomExportFieldsResponse, type Document, type DocumentCreateRequest, type DocumentList, type DocumentListParams, type DocumentPrint, type DocumentReport, DocumentReportResource, DocumentResource, type DocumentUpdateRequest, type Expense, type ExpenseCreateRequest, type ExpenseList, type ExpenseListParams, type ExpenseReportItem, ExpenseReportResource, ExpenseResource, type ExpenseStatus, type ExpenseUpdateRequest, type ExportFieldDefinition, type ExportFieldsResponse, type ExportFormat, type ExportParams, type ExportReportType, type ExportReportsResponse, ExportResource, type ExportTemplate, type ExportTemplateCreateRequest, type ExportTemplateListParams, type ExportTemplateParams, type ExportTemplateUpdateRequest, type ExportedField, type FileResponse, type ListParams, type Member, NavigablePage, type Note, type NoteCreateRequest, type NoteList, type NoteListParams, type NoteReportItem, NoteReportResource, NoteResource, type NoteUpdateRequest, OAuth21Auth, type OAuth21RefreshOptions, OAuth2Auth, OAuthDiscovery, type OAuthDiscoveryOptions, type OAuthDiscoveryResult, type OpenIdConfiguration, type Organization, type OrganizationCreateRequest, type OrganizationList, type OrganizationListParams, OrganizationResource, type OrganizationUpdateRequest, type Page, type PageParams, type Pause, type PauseCreateRequest, type PauseList, type PauseListParams, PauseResource, type PauseUpdateRequest, type PkceCodePair, type Profile, ProfileResource, type ProfileUpdateRequest, type Project, type ProjectCreateRequest, type ProjectList, type ProjectListParams, type ProjectMember, ProjectResource, type ProjectUpdateRequest, type ProtectedResourceMetadata, type Rate, type RateCreateRequest, type RateList, type RateListParams, RateResource, type RateUpdateRequest, ReportsClient, Resource, RetryConfig, type RetryConfigOptions, type Settings, SettingsResource, type SettingsUpdateRequest, type SortablePageParams, type Tag, type TagCreateRequest, type TagList, type TagListParams, TagResource, type TagUpdateRequest, type Task, type TaskCreateRequest, type TaskList, type TaskListParams, type TaskPerformance, type TaskReportItem, TaskReportResource, TaskResource, type TaskStatistic, type TaskStatusUpdateRequest, type TaskTimesUpdateRequest, type TaskUpdateRequest, type Team, type TeamCreateRequest, type TeamList, type TeamListParams, type TeamMember, type TeamMemberList, type TeamMemberListParams, TeamResource, type TeamUpdateRequest, type Timer, type TimerPauseRequest, TimerResource, type TimerResumeRequest, type TimerStartRequest, type TimerStopRequest, type TimerUpdateRequest, TimesheetApiError, TimesheetAuthError, TimesheetClient, type TimesheetClientOptions, TimesheetRateLimitError, type Todo, type TodoCreateRequest, type TodoList, type TodoListParams, TodoResource, type TodoUpdateRequest, type TokenExchangeOptions, type Webhook, type WebhookCreateRequest, type WebhookEventType, WebhookEvents, type WebhookList, type WebhookListParams, WebhookResource, type WebhookUpdateRequest, combineWebhookEvents, createClient, discoverOAuth, generateCodeChallenge, generateCodeVerifier, generatePkceCodePair, getDefaultDiscovery, isValidCodeVerifier };
|
package/dist/index.d.ts
CHANGED
|
@@ -57,6 +57,7 @@ interface AuthorizationUrlOptions {
|
|
|
57
57
|
state?: string;
|
|
58
58
|
scope?: string;
|
|
59
59
|
resource?: string;
|
|
60
|
+
authorizationEndpoint?: string;
|
|
60
61
|
}
|
|
61
62
|
interface TokenExchangeOptions {
|
|
62
63
|
clientId: string;
|
|
@@ -65,21 +66,24 @@ interface TokenExchangeOptions {
|
|
|
65
66
|
redirectUri: string;
|
|
66
67
|
codeVerifier: string;
|
|
67
68
|
resource?: string;
|
|
69
|
+
tokenEndpoint?: string;
|
|
68
70
|
}
|
|
69
71
|
interface OAuth21RefreshOptions {
|
|
70
72
|
clientId: string;
|
|
71
73
|
clientSecret?: string;
|
|
72
74
|
refreshToken: string;
|
|
73
75
|
resource?: string;
|
|
76
|
+
tokenEndpoint?: string;
|
|
74
77
|
}
|
|
75
78
|
declare class OAuth21Auth implements Authentication {
|
|
76
|
-
private static readonly
|
|
77
|
-
private static readonly
|
|
79
|
+
private static readonly DEFAULT_TOKEN_ENDPOINT;
|
|
80
|
+
private static readonly DEFAULT_AUTH_ENDPOINT;
|
|
78
81
|
private accessToken;
|
|
79
82
|
private refreshToken?;
|
|
80
83
|
private readonly clientId?;
|
|
81
84
|
private readonly clientSecret?;
|
|
82
85
|
private readonly resource?;
|
|
86
|
+
private readonly tokenEndpoint;
|
|
83
87
|
private tokenExpiry?;
|
|
84
88
|
private refreshPromise?;
|
|
85
89
|
constructor(accessToken: string);
|
|
@@ -95,6 +99,88 @@ declare class OAuth21Auth implements Authentication {
|
|
|
95
99
|
private parseTokenExpiry;
|
|
96
100
|
}
|
|
97
101
|
|
|
102
|
+
interface AuthorizationServerMetadata {
|
|
103
|
+
issuer: string;
|
|
104
|
+
authorization_endpoint: string;
|
|
105
|
+
token_endpoint: string;
|
|
106
|
+
registration_endpoint?: string;
|
|
107
|
+
scopes_supported?: string[];
|
|
108
|
+
response_types_supported: string[];
|
|
109
|
+
grant_types_supported?: string[];
|
|
110
|
+
token_endpoint_auth_methods_supported?: string[];
|
|
111
|
+
code_challenge_methods_supported?: string[];
|
|
112
|
+
revocation_endpoint?: string;
|
|
113
|
+
revocation_endpoint_auth_methods_supported?: string[];
|
|
114
|
+
introspection_endpoint?: string;
|
|
115
|
+
introspection_endpoint_auth_methods_supported?: string[];
|
|
116
|
+
service_documentation?: string;
|
|
117
|
+
}
|
|
118
|
+
interface ProtectedResourceMetadata {
|
|
119
|
+
resource: string;
|
|
120
|
+
authorization_servers: string[];
|
|
121
|
+
scopes_supported?: string[];
|
|
122
|
+
bearer_methods_supported?: string[];
|
|
123
|
+
resource_documentation?: string;
|
|
124
|
+
resource_signing_alg_values_supported?: string[];
|
|
125
|
+
}
|
|
126
|
+
interface OpenIdConfiguration {
|
|
127
|
+
issuer: string;
|
|
128
|
+
authorization_endpoint: string;
|
|
129
|
+
token_endpoint: string;
|
|
130
|
+
userinfo_endpoint?: string;
|
|
131
|
+
jwks_uri: string;
|
|
132
|
+
registration_endpoint?: string;
|
|
133
|
+
scopes_supported?: string[];
|
|
134
|
+
response_types_supported: string[];
|
|
135
|
+
response_modes_supported?: string[];
|
|
136
|
+
grant_types_supported?: string[];
|
|
137
|
+
token_endpoint_auth_methods_supported?: string[];
|
|
138
|
+
token_endpoint_auth_signing_alg_values_supported?: string[];
|
|
139
|
+
service_documentation?: string;
|
|
140
|
+
ui_locales_supported?: string[];
|
|
141
|
+
op_policy_uri?: string;
|
|
142
|
+
op_tos_uri?: string;
|
|
143
|
+
revocation_endpoint?: string;
|
|
144
|
+
introspection_endpoint?: string;
|
|
145
|
+
code_challenge_methods_supported?: string[];
|
|
146
|
+
}
|
|
147
|
+
interface OAuthDiscoveryResult {
|
|
148
|
+
issuer: string;
|
|
149
|
+
authorizationServer: AuthorizationServerMetadata;
|
|
150
|
+
protectedResource?: ProtectedResourceMetadata;
|
|
151
|
+
openIdConfiguration?: OpenIdConfiguration;
|
|
152
|
+
fetchedAt: Date;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
interface OAuthDiscoveryOptions {
|
|
156
|
+
cacheTtl?: number;
|
|
157
|
+
timeout?: number;
|
|
158
|
+
fetchOpenIdConfig?: boolean;
|
|
159
|
+
fetchProtectedResource?: boolean;
|
|
160
|
+
}
|
|
161
|
+
declare class OAuthDiscovery {
|
|
162
|
+
private static readonly DEFAULT_CACHE_TTL;
|
|
163
|
+
private static readonly DEFAULT_TIMEOUT;
|
|
164
|
+
private readonly cache;
|
|
165
|
+
private readonly options;
|
|
166
|
+
constructor(options?: OAuthDiscoveryOptions);
|
|
167
|
+
discover(issuerUrl: string): Promise<OAuthDiscoveryResult>;
|
|
168
|
+
fetchAuthorizationServerMetadata(issuerUrl: string): Promise<AuthorizationServerMetadata>;
|
|
169
|
+
fetchOpenIdConfiguration(issuerUrl: string): Promise<OpenIdConfiguration>;
|
|
170
|
+
fetchProtectedResourceMetadata(resourceUrl: string): Promise<ProtectedResourceMetadata>;
|
|
171
|
+
clearCache(): void;
|
|
172
|
+
clearCacheForIssuer(issuerUrl: string): void;
|
|
173
|
+
isCached(issuerUrl: string): boolean;
|
|
174
|
+
private normalizeIssuerUrl;
|
|
175
|
+
private getCached;
|
|
176
|
+
private setCache;
|
|
177
|
+
private validateAuthorizationServerMetadata;
|
|
178
|
+
private validateOpenIdConfiguration;
|
|
179
|
+
private validateProtectedResourceMetadata;
|
|
180
|
+
}
|
|
181
|
+
declare function getDefaultDiscovery(): OAuthDiscovery;
|
|
182
|
+
declare function discoverOAuth(issuerUrl: string, options?: OAuthDiscoveryOptions): Promise<OAuthDiscoveryResult>;
|
|
183
|
+
|
|
98
184
|
declare class RetryConfig {
|
|
99
185
|
readonly maxRetries: number;
|
|
100
186
|
readonly initialDelay: number;
|
|
@@ -1847,4 +1933,4 @@ interface TimesheetClientOptions {
|
|
|
1847
1933
|
}
|
|
1848
1934
|
declare function createClient(options: TimesheetClientOptions): TimesheetClient;
|
|
1849
1935
|
|
|
1850
|
-
export { type Activity, ApiClient, ApiKeyAuth, type Authentication, type AuthorizationUrlOptions, type Automation, type AutomationCreateRequest, type AutomationList, type AutomationListParams, AutomationResource, type AutomationUpdateRequest, type ClientConfig, type CodeChallengeMethod, type CustomExportField, type CustomExportFieldCreateRequest, type CustomExportFieldUpdateRequest, type CustomExportFieldsResponse, type Document, type DocumentCreateRequest, type DocumentList, type DocumentListParams, type DocumentPrint, type DocumentReport, DocumentReportResource, DocumentResource, type DocumentUpdateRequest, type Expense, type ExpenseCreateRequest, type ExpenseList, type ExpenseListParams, type ExpenseReportItem, ExpenseReportResource, ExpenseResource, type ExpenseStatus, type ExpenseUpdateRequest, type ExportFieldDefinition, type ExportFieldsResponse, type ExportFormat, type ExportParams, type ExportReportType, type ExportReportsResponse, ExportResource, type ExportTemplate, type ExportTemplateCreateRequest, type ExportTemplateListParams, type ExportTemplateParams, type ExportTemplateUpdateRequest, type ExportedField, type FileResponse, type ListParams, type Member, NavigablePage, type Note, type NoteCreateRequest, type NoteList, type NoteListParams, type NoteReportItem, NoteReportResource, NoteResource, type NoteUpdateRequest, OAuth21Auth, type OAuth21RefreshOptions, OAuth2Auth, type Organization, type OrganizationCreateRequest, type OrganizationList, type OrganizationListParams, OrganizationResource, type OrganizationUpdateRequest, type Page, type PageParams, type Pause, type PauseCreateRequest, type PauseList, type PauseListParams, PauseResource, type PauseUpdateRequest, type PkceCodePair, type Profile, ProfileResource, type ProfileUpdateRequest, type Project, type ProjectCreateRequest, type ProjectList, type ProjectListParams, type ProjectMember, ProjectResource, type ProjectUpdateRequest, type Rate, type RateCreateRequest, type RateList, type RateListParams, RateResource, type RateUpdateRequest, ReportsClient, Resource, RetryConfig, type RetryConfigOptions, type Settings, SettingsResource, type SettingsUpdateRequest, type SortablePageParams, type Tag, type TagCreateRequest, type TagList, type TagListParams, TagResource, type TagUpdateRequest, type Task, type TaskCreateRequest, type TaskList, type TaskListParams, type TaskPerformance, type TaskReportItem, TaskReportResource, TaskResource, type TaskStatistic, type TaskStatusUpdateRequest, type TaskTimesUpdateRequest, type TaskUpdateRequest, type Team, type TeamCreateRequest, type TeamList, type TeamListParams, type TeamMember, type TeamMemberList, type TeamMemberListParams, TeamResource, type TeamUpdateRequest, type Timer, type TimerPauseRequest, TimerResource, type TimerResumeRequest, type TimerStartRequest, type TimerStopRequest, type TimerUpdateRequest, TimesheetApiError, TimesheetAuthError, TimesheetClient, type TimesheetClientOptions, TimesheetRateLimitError, type Todo, type TodoCreateRequest, type TodoList, type TodoListParams, TodoResource, type TodoUpdateRequest, type TokenExchangeOptions, type Webhook, type WebhookCreateRequest, type WebhookEventType, WebhookEvents, type WebhookList, type WebhookListParams, WebhookResource, type WebhookUpdateRequest, combineWebhookEvents, createClient, generateCodeChallenge, generateCodeVerifier, generatePkceCodePair, isValidCodeVerifier };
|
|
1936
|
+
export { type Activity, ApiClient, ApiKeyAuth, type Authentication, type AuthorizationServerMetadata, type AuthorizationUrlOptions, type Automation, type AutomationCreateRequest, type AutomationList, type AutomationListParams, AutomationResource, type AutomationUpdateRequest, type ClientConfig, type CodeChallengeMethod, type CustomExportField, type CustomExportFieldCreateRequest, type CustomExportFieldUpdateRequest, type CustomExportFieldsResponse, type Document, type DocumentCreateRequest, type DocumentList, type DocumentListParams, type DocumentPrint, type DocumentReport, DocumentReportResource, DocumentResource, type DocumentUpdateRequest, type Expense, type ExpenseCreateRequest, type ExpenseList, type ExpenseListParams, type ExpenseReportItem, ExpenseReportResource, ExpenseResource, type ExpenseStatus, type ExpenseUpdateRequest, type ExportFieldDefinition, type ExportFieldsResponse, type ExportFormat, type ExportParams, type ExportReportType, type ExportReportsResponse, ExportResource, type ExportTemplate, type ExportTemplateCreateRequest, type ExportTemplateListParams, type ExportTemplateParams, type ExportTemplateUpdateRequest, type ExportedField, type FileResponse, type ListParams, type Member, NavigablePage, type Note, type NoteCreateRequest, type NoteList, type NoteListParams, type NoteReportItem, NoteReportResource, NoteResource, type NoteUpdateRequest, OAuth21Auth, type OAuth21RefreshOptions, OAuth2Auth, OAuthDiscovery, type OAuthDiscoveryOptions, type OAuthDiscoveryResult, type OpenIdConfiguration, type Organization, type OrganizationCreateRequest, type OrganizationList, type OrganizationListParams, OrganizationResource, type OrganizationUpdateRequest, type Page, type PageParams, type Pause, type PauseCreateRequest, type PauseList, type PauseListParams, PauseResource, type PauseUpdateRequest, type PkceCodePair, type Profile, ProfileResource, type ProfileUpdateRequest, type Project, type ProjectCreateRequest, type ProjectList, type ProjectListParams, type ProjectMember, ProjectResource, type ProjectUpdateRequest, type ProtectedResourceMetadata, type Rate, type RateCreateRequest, type RateList, type RateListParams, RateResource, type RateUpdateRequest, ReportsClient, Resource, RetryConfig, type RetryConfigOptions, type Settings, SettingsResource, type SettingsUpdateRequest, type SortablePageParams, type Tag, type TagCreateRequest, type TagList, type TagListParams, TagResource, type TagUpdateRequest, type Task, type TaskCreateRequest, type TaskList, type TaskListParams, type TaskPerformance, type TaskReportItem, TaskReportResource, TaskResource, type TaskStatistic, type TaskStatusUpdateRequest, type TaskTimesUpdateRequest, type TaskUpdateRequest, type Team, type TeamCreateRequest, type TeamList, type TeamListParams, type TeamMember, type TeamMemberList, type TeamMemberListParams, TeamResource, type TeamUpdateRequest, type Timer, type TimerPauseRequest, TimerResource, type TimerResumeRequest, type TimerStartRequest, type TimerStopRequest, type TimerUpdateRequest, TimesheetApiError, TimesheetAuthError, TimesheetClient, type TimesheetClientOptions, TimesheetRateLimitError, type Todo, type TodoCreateRequest, type TodoList, type TodoListParams, TodoResource, type TodoUpdateRequest, type TokenExchangeOptions, type Webhook, type WebhookCreateRequest, type WebhookEventType, WebhookEvents, type WebhookList, type WebhookListParams, WebhookResource, type WebhookUpdateRequest, combineWebhookEvents, createClient, discoverOAuth, generateCodeChallenge, generateCodeVerifier, generatePkceCodePair, getDefaultDiscovery, isValidCodeVerifier };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var ue=Object.create;var V=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var de=Object.getOwnPropertyNames;var ge=Object.getPrototypeOf,Pe=Object.prototype.hasOwnProperty;var fe=(s,e)=>{for(var t in e)V(s,t,{get:e[t],enumerable:!0})},re=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let p of de(e))!Pe.call(s,p)&&p!==t&&V(s,p,{get:()=>e[p],enumerable:!(r=le(e,p))||r.enumerable});return s};var d=(s,e,t)=>(t=s!=null?ue(ge(s)):{},re(e||!s||!s.__esModule?V(t,"default",{value:s,enumerable:!0}):t,s)),Te=s=>re(V({},"__esModule",{value:!0}),s);var ke={};fe(ke,{ApiClient:()=>y,ApiKeyAuth:()=>K,AutomationResource:()=>N,DocumentReportResource:()=>S,DocumentResource:()=>I,ExpenseReportResource:()=>M,ExpenseResource:()=>A,ExportResource:()=>F,NavigablePage:()=>n,NoteReportResource:()=>z,NoteResource:()=>v,OAuth21Auth:()=>ee,OAuth2Auth:()=>R,OrganizationResource:()=>b,PauseResource:()=>$,ProfileResource:()=>D,ProjectResource:()=>C,RateResource:()=>w,ReportsClient:()=>j,Resource:()=>o,RetryConfig:()=>H,SettingsResource:()=>U,TagResource:()=>E,TaskReportResource:()=>O,TaskResource:()=>k,TeamResource:()=>x,TimerResource:()=>q,TimesheetApiError:()=>c,TimesheetAuthError:()=>W,TimesheetClient:()=>J,TimesheetRateLimitError:()=>B,TodoResource:()=>L,WebhookEvents:()=>ye,WebhookResource:()=>_,combineWebhookEvents:()=>Re,createClient:()=>Ce,generateCodeChallenge:()=>ae,generateCodeVerifier:()=>oe,generatePkceCodePair:()=>Z,isValidCodeVerifier:()=>X});module.exports=Te(ke);var T=d(require("axios"));var c=class s extends Error{constructor(e,t,r,p){let i=t?p?`${e} (HTTP ${t}, Code: ${p})`:`${e} (HTTP ${t})`:e;super(i),this.name="TimesheetApiError",this.statusCode=t,this.responseBody=r,this.errorCode=p,typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,s)}};var W=class extends c{constructor(e,t=401,r){super(e,t,r,"authentication_error"),this.name="TimesheetAuthError"}};var B=class extends c{constructor(e,t){super(e,429,void 0,"rate_limit_exceeded"),this.name="TimesheetRateLimitError",this.retryAfter=t}getRetryAfterDate(){if(!this.retryAfter)return null;let e=Number(this.retryAfter);if(!isNaN(e))return new Date(e*1e3);let t=new Date(this.retryAfter);return isNaN(t.getTime())?null:t}};var y=class{constructor(e){this.config=e,this.httpClient=e.httpClient||T.default.create({baseURL:e.baseUrl,timeout:3e4,headers:{"User-Agent":"Timesheet-TypeScript-SDK/1.0.0","Content-Type":"application/json"}}),this.httpClient.interceptors.request.use(async t=>{if(t.url!=="/oauth/token"&&this.config.authentication){let r=await this.config.authentication.getAuthHeaders();if(r)for(let[p,i]of Object.entries(r))t.headers.set(p,i)}return t})}async request(e){let t=null,r=this.config.retryConfig;for(let p=0;p<=r.maxRetries;p++)try{return(await this.httpClient.request(e)).data}catch(i){if(t=i,T.default.isAxiosError(i)&&i.response?.status===401){let m=i.response.data;throw new W(m?.message||"Authentication failed",401,JSON.stringify(m))}if(T.default.isAxiosError(i)&&i.response?.status===429){let m=i.response.headers["retry-after"];throw new B("Rate limit exceeded",m)}let h=T.default.isAxiosError(i)?i.response?.status:void 0;if(p<r.maxRetries&&h&&r.retryableStatusCodes.includes(h)){let m=Math.min(r.initialDelay*Math.pow(r.backoffMultiplier,p),r.maxDelay);await this.sleep(m);continue}if(T.default.isAxiosError(i)){let m=i.response?.data;throw new c(m?.message||i.message,i.response?.status,JSON.stringify(m),m?.code)}else throw i instanceof Error?new c(i.message):new c("Unknown error occurred")}throw t||new Error("Unknown error")}async get(e,t){return this.request({method:"GET",url:e,params:t})}async post(e,t,r){return this.request({method:"POST",url:e,data:t,params:r})}async put(e,t,r){return this.request({method:"PUT",url:e,data:t,params:r})}async delete(e,t){return this.request({method:"DELETE",url:e,params:t})}sleep(e){return new Promise(t=>setTimeout(t,e))}};var K=class{constructor(e){this.apiKey=e;if(e===null)throw new Error("API key cannot be null");if(e===void 0)throw new Error("API key cannot be undefined");if(!e)throw new Error("API key cannot be empty");if(typeof e!="string")throw new Error("API key must be a string");if(e.trim().length===0)throw new Error("API key cannot be empty or whitespace");if(!this.isValidFormat(e))throw new Error("Invalid API key format")}isValidFormat(e){return/^ts_[a-zA-Z0-9]+\.[a-zA-Z0-9]+$/.test(e)}applyAuth(e){e.headers||(e.headers={}),e.headers.Authorization=`ApiKey ${this.apiKey}`}needsRefresh(){return!1}async refresh(){throw new Error("API keys cannot be refreshed")}async getAuthHeaders(){return{Authorization:`ApiKey ${this.apiKey}`}}isValid(){return typeof this.apiKey=="string"&&this.apiKey.trim().length>0&&this.isValidFormat(this.apiKey)}};var Y=d(require("axios")),se=d(require("jsonwebtoken")),P=class P{constructor(e,t,r){t&&r?(this.clientId=e,this.clientSecret=t,this.refreshToken=r,this.accessToken=""):(this.accessToken=e,this.parseTokenExpiry())}applyAuth(e){e.headers||(e.headers={}),e.headers.Authorization=`Bearer ${this.accessToken}`}needsRefresh(){return this.refreshToken&&!this.accessToken?!0:!this.refreshToken||!this.tokenExpiry?!1:new Date(Date.now()+5*60*1e3)>=this.tokenExpiry}async refresh(){if(!this.refreshToken)throw new Error("Cannot refresh without refresh token");if(this.refreshPromise)return this.refreshPromise;this.refreshPromise=this.performRefresh();try{await this.refreshPromise}finally{this.refreshPromise=void 0}}async performRefresh(){try{let e=await Y.default.post(P.TOKEN_ENDPOINT,new URLSearchParams({grant_type:"refresh_token",refresh_token:this.refreshToken,client_id:this.clientId,client_secret:this.clientSecret}),{headers:{"Content-Type":"application/x-www-form-urlencoded"}});this.accessToken=e.data.access_token,e.data.refresh_token&&(this.refreshToken=e.data.refresh_token),this.parseTokenExpiry()}catch(e){let t=e instanceof Error?e.message:"Unknown error";throw new Error(`Failed to refresh OAuth2 token: ${t}`)}}async getAuthHeaders(){return this.needsRefresh()&&await this.refresh(),{Authorization:`Bearer ${this.accessToken}`}}static async fromAuthorizationCode(e,t,r,p){try{let i=await Y.default.post(P.TOKEN_ENDPOINT,new URLSearchParams({grant_type:"authorization_code",code:r,redirect_uri:p,client_id:e,client_secret:t}),{headers:{"Content-Type":"application/x-www-form-urlencoded"}}),h=i.data.access_token,m=i.data.refresh_token;return m?new P(e,t,m):new P(h)}catch(i){let h=i instanceof Error?i.message:"Unknown error";throw new Error(`Failed to exchange authorization code: ${h}`)}}static buildAuthorizationUrl(e,t,r){let p=new URLSearchParams({client_id:e,redirect_uri:t,response_type:"code"});return r&&p.append("state",r),`https://api.timesheet.io/oauth2/auth?${p.toString()}`}parseTokenExpiry(){try{let e=se.default.decode(this.accessToken);e&&e.exp&&(this.tokenExpiry=new Date(e.exp*1e3))}catch{this.tokenExpiry=new Date(Date.now()+60*60*1e3)}}};P.TOKEN_ENDPOINT="https://api.timesheet.io/oauth2/token";var R=P;var Q=d(require("axios")),ne=d(require("jsonwebtoken"));var G=require("crypto");function oe(s=64){if(s<43||s>128)throw new Error("Code verifier length must be between 43 and 128 characters");let e=(0,G.randomBytes)(Math.ceil(s*3/4));return ie(e).slice(0,s)}function ae(s,e="S256"){if(e==="plain")return s;let t=(0,G.createHash)("sha256").update(s,"ascii").digest();return ie(t)}function Z(s="S256",e=64){let t=oe(e),r=ae(t,s);return{codeVerifier:t,codeChallenge:r,codeChallengeMethod:s}}function X(s){return s.length<43||s.length>128?!1:/^[A-Za-z0-9\-._~]+$/.test(s)}function ie(s){return s.toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var g=class g{constructor(e){if(typeof e=="string")this.accessToken=e,this.parseTokenExpiry();else{let t=e;this.clientId=t.clientId,this.clientSecret=t.clientSecret,this.refreshToken=t.refreshToken,this.resource=t.resource,this.accessToken=""}}applyAuth(e){e.headers||(e.headers={}),e.headers.Authorization=`Bearer ${this.accessToken}`}needsRefresh(){return this.refreshToken&&!this.accessToken?!0:!this.refreshToken||!this.tokenExpiry?!1:new Date(Date.now()+5*60*1e3)>=this.tokenExpiry}async refresh(){if(!this.refreshToken)throw new Error("Cannot refresh without refresh token");if(this.refreshPromise)return this.refreshPromise;this.refreshPromise=this.performRefresh();try{await this.refreshPromise}finally{this.refreshPromise=void 0}}async performRefresh(){try{let e=new URLSearchParams({grant_type:"refresh_token",refresh_token:this.refreshToken,client_id:this.clientId});this.clientSecret&&e.append("client_secret",this.clientSecret),this.resource&&e.append("resource",this.resource);let t=await Q.default.post(g.TOKEN_ENDPOINT,e,{headers:{"Content-Type":"application/x-www-form-urlencoded"}});this.accessToken=t.data.access_token,t.data.refresh_token&&(this.refreshToken=t.data.refresh_token),this.parseTokenExpiry()}catch(e){let t=e instanceof Error?e.message:"Unknown error";throw new Error(`Failed to refresh OAuth 2.1 token: ${t}`)}}async getAuthHeaders(){return this.needsRefresh()&&await this.refresh(),{Authorization:`Bearer ${this.accessToken}`}}static async fromAuthorizationCode(e){let{clientId:t,clientSecret:r,authorizationCode:p,redirectUri:i,codeVerifier:h,resource:m}=e;if(!X(h))throw new Error("Invalid code verifier: must be 43-128 characters using only A-Z, a-z, 0-9, -, ., _, ~");try{let u=new URLSearchParams({grant_type:"authorization_code",code:p,redirect_uri:i,client_id:t,code_verifier:h});r&&u.append("client_secret",r),m&&u.append("resource",m);let l=await Q.default.post(g.TOKEN_ENDPOINT,u,{headers:{"Content-Type":"application/x-www-form-urlencoded"}}),ce=l.data.access_token,te=l.data.refresh_token;return te?new g({clientId:t,clientSecret:r,refreshToken:te,resource:m}):new g(ce)}catch(u){let l=u instanceof Error?u.message:"Unknown error";throw new Error(`Failed to exchange authorization code: ${l}`)}}static buildAuthorizationUrl(e){let{clientId:t,redirectUri:r,codeChallenge:p,codeChallengeMethod:i="S256",state:h,scope:m,resource:u}=e,l=new URLSearchParams({response_type:"code",client_id:t,redirect_uri:r,code_challenge:p,code_challenge_method:i});return h&&l.append("state",h),m&&l.append("scope",m),u&&l.append("resource",u),`${g.AUTH_ENDPOINT}?${l.toString()}`}static generatePkce(e="S256"){return Z(e)}parseTokenExpiry(){try{let e=ne.default.decode(this.accessToken);e&&e.exp&&(this.tokenExpiry=new Date(e.exp*1e3))}catch{this.tokenExpiry=new Date(Date.now()+60*60*1e3)}}};g.TOKEN_ENDPOINT="https://api.timesheet.io/oauth2/token",g.AUTH_ENDPOINT="https://api.timesheet.io/oauth2/auth";var ee=g;var H=class s{constructor(e={}){this.maxRetries=e.maxRetries??3,this.initialDelay=e.initialDelay??100,this.maxDelay=e.maxDelay??1e4,this.backoffMultiplier=e.backoffMultiplier??2,this.retryableStatusCodes=e.retryableStatusCodes??[429,502,503,504]}static default(){return new s}};var n=class{constructor(e,t){this.items=e.items,this.params=e.params,this.nextPageLoader=t}get totalPages(){return Math.ceil((this.params?.count||0)/(this.params?.limit||25))}get hasNextPage(){return(this.params?.page||1)<this.totalPages}async nextPage(){if(!this.hasNextPage)throw new Error("No more pages available");if(!this.nextPageLoader)throw new Error("Next page loader not configured");return this.nextPageLoader((this.params.page||1)+1)}async*[Symbol.asyncIterator](){let e=this;for(;;){for(let t of e.items)yield t;if(!e.hasNextPage)break;e=await e.nextPage()}}async toArray(){let e=[];for await(let t of this)e.push(t);return e}};var ye={TEAM_CREATE:"team.create",TEAM_UPDATE:"team.update",PROJECT_CREATE:"project.create",PROJECT_UPDATE:"project.update",TODO_CREATE:"todo.create",TODO_UPDATE:"todo.update",TASK_CREATE:"task.create",TASK_UPDATE:"task.update",TAG_CREATE:"tag.create",TAG_UPDATE:"tag.update",RATE_CREATE:"rate.create",RATE_UPDATE:"rate.update",TIMER_START:"timer.start",TIMER_STOP:"timer.stop",TIMER_PAUSE:"timer.pause",TIMER_RESUME:"timer.resume"};function Re(...s){return s.join(",")}var o=class{constructor(e,t){this.http=e;typeof t=="string"?this.basePath=t:this.basePath=t.basePath}createNavigablePage(e,t){return new n(e,t)}};var b=class extends o{constructor(e){super(e,"/v1/organizations")}async list(e){let t=await this.http.get(this.basePath,e);return new n(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var x=class extends o{constructor(e){super(e,"/v1/teams")}async list(e){let t=await this.http.get(this.basePath,e);return new n(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async listMembers(e,t){let r=await this.http.post(`${this.basePath}/${e}/members/list`,t);return this.createNavigablePage(r,p=>this.listMembers(e,{...t,page:p}))}async getMember(e,t){return this.http.get(`${this.basePath}/${e}/members/${t}`)}async getColleagues(e){let t=await this.http.post(`${this.basePath}/getColleagues`,e);return this.createNavigablePage(t,r=>this.getColleagues({...e,page:r}))}};var C=class extends o{constructor(e){super(e,"/v1/projects")}async list(e){let t=await this.http.get(this.basePath,e);return new n(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var f=d(require("dayjs")),pe=d(require("dayjs/plugin/utc")),me=d(require("dayjs/plugin/timezone")),he=d(require("dayjs/plugin/customParseFormat"));f.default.extend(pe.default);f.default.extend(me.default);f.default.extend(he.default);var be="YYYY-MM-DDTHH:mm:ssZ",xe=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{2}:\d{2}$/,a={isValidTimestampFormat(s){return xe.test(s)},formatTimestamp(s){return typeof s=="string"&&this.isValidTimestampFormat(s)?s:(0,f.default)(s||new Date).format(be)},parseTimestamp(s){return(0,f.default)(s).toDate()},formatDate(s){return(0,f.default)(s||new Date).format("YYYY-MM-DD")},now(){return this.formatTimestamp()}};var k=class extends o{constructor(e){super(e,"/v1/tasks")}async create(e){let t={...e,startDateTime:a.formatTimestamp(e.startDateTime),endDateTime:e.endDateTime?a.formatTimestamp(e.endDateTime):void 0};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,startDateTime:t.startDateTime?a.formatTimestamp(t.startDateTime):void 0,endDateTime:t.endDateTime?a.formatTimestamp(t.endDateTime):void 0};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async updateStatus(e){return this.http.put(`${this.basePath}/updateStatus`,e)}async updateTimes(e){let t={...e,startDateTime:a.formatTimestamp(e.startDateTime),endDateTime:a.formatTimestamp(e.endDateTime)};return this.http.put(`${this.basePath}/updateTimes`,t)}};var w=class extends o{constructor(e){super(e,"/v1/rates")}async list(e){let t=await this.http.get(this.basePath,e);return new n(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var E=class extends o{constructor(e){super(e,"/v1/tags")}async list(e){let t=await this.http.get(this.basePath,e);return new n(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var A=class extends o{constructor(e){super(e,"/v1/expenses")}async list(e){let t=await this.http.get(this.basePath,e);return new n(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,dateTime:a.formatTimestamp(e.dateTime)};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,dateTime:t.dateTime?a.formatTimestamp(t.dateTime):void 0};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async updateStatus(e,t){return this.http.put(`${this.basePath}/${e}/status`,t)}};var v=class extends o{constructor(e){super(e,"/v1/notes")}async list(e){let t=await this.http.get(this.basePath,e);return new n(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,dateTime:a.formatTimestamp(e.dateTime)};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,dateTime:a.formatTimestamp(t.dateTime)};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var $=class extends o{constructor(e){super(e,"/v1/pauses")}async list(e){let t=await this.http.get(this.basePath,e);return new n(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,startDateTime:a.formatTimestamp(e.startDateTime),endDateTime:a.formatTimestamp(e.endDateTime)};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,startDateTime:a.formatTimestamp(t.startDateTime),endDateTime:a.formatTimestamp(t.endDateTime)};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var D=class{constructor(e){this.http=e}async getProfile(){return this.http.get("/v1/profiles/me")}async updateProfile(e){return this.http.put("/v1/profiles/me",e)}};var U=class{constructor(e){this.http=e}async get(){return this.http.get("/v1/settings")}async update(e){return this.http.put("/v1/settings",e)}};var N=class extends o{constructor(e){super(e,"/v1/automations")}async list(e){let t=await this.http.get(this.basePath,e);return new n(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var I=class extends o{constructor(e){super(e,"/v1/documents")}async list(e){let t=await this.http.get(this.basePath,e);return new n(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var q=class{constructor(e){this.http=e}async get(){return this.http.get("/v1/timer")}async start(e){let t={...e,startDateTime:e.startDateTime?a.formatTimestamp(e.startDateTime):a.formatTimestamp()};return this.http.post("/v1/timer/start",t)}async stop(e){let t=e?{...e,endDateTime:e.endDateTime?a.formatTimestamp(e.endDateTime):a.formatTimestamp()}:{endDateTime:a.formatTimestamp()};return this.http.post("/v1/timer/stop",t)}async pause(e){let t=e?{...e,startDateTime:e.startDateTime?a.formatTimestamp(e.startDateTime):a.formatTimestamp()}:{startDateTime:a.formatTimestamp()};return this.http.post("/v1/timer/pause",t)}async resume(e){let t=e?{...e,endDateTime:e.endDateTime?a.formatTimestamp(e.endDateTime):a.formatTimestamp()}:{endDateTime:a.formatTimestamp()};return this.http.post("/v1/timer/resume",t)}async update(e){let t={...e,startDateTime:e.startDateTime?a.formatTimestamp(e.startDateTime):void 0};return this.http.put("/v1/timer/update",t)}};var L=class extends o{constructor(e){super(e,"/v1/todos")}async list(e){let t=await this.http.get(this.basePath,e);return new n(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,dueDate:e.dueDate?a.formatTimestamp(e.dueDate):void 0};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,dueDate:t.dueDate?a.formatTimestamp(t.dueDate):void 0};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var _=class extends o{constructor(e){super(e,"/v1/webhooks")}async list(e){let t=await this.http.get(this.basePath,e);return new n(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var S=class extends o{constructor(e){super(e,"/v1/documents")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}async getXml(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/xml`,headers:{Accept:"application/xml"}})}};var O=class extends o{constructor(e){super(e,"/v1/tasks")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}};var M=class extends o{constructor(e){super(e,"/v1/expenses")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}};var z=class extends o{constructor(e){super(e,"/v1/notes")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}};var F=class extends o{constructor(e){super(e,"/v1/export")}async generate(e){return this.http.post(`${this.basePath}/data`,e)}async send(e){return this.http.post(`${this.basePath}/send`,e)}async generateFromTemplate(e){return this.http.request({method:"POST",url:`${this.basePath}/from-template`,data:e,responseType:"arraybuffer"})}async getFields(e){return this.http.get(`${this.basePath}/fields`,e?{scope:e}:void 0)}async getReportTypes(){return this.http.get(`${this.basePath}/report-types`)}async listTemplates(e){let t=await this.http.get(`${this.basePath}/templates`,e);return new n(t,r=>this.listTemplates({...e,page:r}))}async searchTemplates(e){let t=await this.http.post(`${this.basePath}/templates/search`,e);return this.createNavigablePage(t,r=>this.searchTemplates({...e,page:r}))}async createTemplate(e){return this.http.post(`${this.basePath}/templates`,e)}async getTemplate(e){return this.http.get(`${this.basePath}/templates/${encodeURIComponent(e)}`)}async updateTemplate(e,t){return this.http.put(`${this.basePath}/templates/${encodeURIComponent(e)}`,t)}async deleteTemplate(e){return this.http.delete(`${this.basePath}/templates/${encodeURIComponent(e)}`)}async listCustomFields(e){return this.http.get(`${this.basePath}/custom-fields`,e?{scope:e}:void 0)}async createCustomField(e){return this.http.post(`${this.basePath}/custom-fields`,e)}async getCustomField(e){return this.http.get(`${this.basePath}/custom-fields/${encodeURIComponent(e)}`)}async updateCustomField(e,t){return this.http.put(`${this.basePath}/custom-fields/${encodeURIComponent(e)}`,t)}async deleteCustomField(e){return this.http.delete(`${this.basePath}/custom-fields/${encodeURIComponent(e)}`)}};var j=class{constructor(e){this.documents=new S(e),this.tasks=new O(e),this.expenses=new M(e),this.notes=new z(e),this.export=new F(e)}};var J=class{constructor(e){let t=this.createAuthentication(e),r=e.retryConfig||H.default(),p={baseUrl:e.baseUrl||"https://api.timesheet.io",authentication:t,retryConfig:r,httpClient:e.httpClient};this.apiClient=new y(p);let i={baseUrl:e.reportsBaseUrl||"https://reports.timesheet.io",authentication:t,retryConfig:r,httpClient:e.reportsHttpClient};this.reportsApiClient=new y(i),this.organizations=new b(this.apiClient),this.teams=new x(this.apiClient),this.projects=new C(this.apiClient),this.tasks=new k(this.apiClient),this.rates=new w(this.apiClient),this.tags=new E(this.apiClient),this.expenses=new A(this.apiClient),this.notes=new v(this.apiClient),this.pauses=new $(this.apiClient),this.profile=new D(this.apiClient),this.settings=new U(this.apiClient),this.automations=new N(this.apiClient),this.documents=new I(this.apiClient),this.timer=new q(this.apiClient),this.todos=new L(this.apiClient),this.webhooks=new _(this.apiClient),this.reports=new j(this.reportsApiClient)}createAuthentication(e){if(e.apiKey)return new K(e.apiKey);if(e.oauth2Token)return new R(e.oauth2Token);if(e.oauth2)return new R(e.oauth2.clientId,e.oauth2.clientSecret,e.oauth2.refreshToken);if(e.authentication)return e.authentication;throw new Error("Authentication must be configured")}};function Ce(s){return new J(s)}0&&(module.exports={ApiClient,ApiKeyAuth,AutomationResource,DocumentReportResource,DocumentResource,ExpenseReportResource,ExpenseResource,ExportResource,NavigablePage,NoteReportResource,NoteResource,OAuth21Auth,OAuth2Auth,OrganizationResource,PauseResource,ProfileResource,ProjectResource,RateResource,ReportsClient,Resource,RetryConfig,SettingsResource,TagResource,TaskReportResource,TaskResource,TeamResource,TimerResource,TimesheetApiError,TimesheetAuthError,TimesheetClient,TimesheetRateLimitError,TodoResource,WebhookEvents,WebhookResource,combineWebhookEvents,createClient,generateCodeChallenge,generateCodeVerifier,generatePkceCodePair,isValidCodeVerifier});
|
|
1
|
+
"use strict";var ye=Object.create;var Z=Object.defineProperty;var Re=Object.getOwnPropertyDescriptor;var be=Object.getOwnPropertyNames;var xe=Object.getPrototypeOf,Ce=Object.prototype.hasOwnProperty;var we=(s,e)=>{for(var t in e)Z(s,t,{get:e[t],enumerable:!0})},pe=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of be(e))!Ce.call(s,i)&&i!==t&&Z(s,i,{get:()=>e[i],enumerable:!(r=Re(e,i))||r.enumerable});return s};var u=(s,e,t)=>(t=s!=null?ye(xe(s)):{},pe(e||!s||!s.__esModule?Z(t,"default",{value:s,enumerable:!0}):t,s)),Ee=s=>pe(Z({},"__esModule",{value:!0}),s);var Ie={};we(Ie,{ApiClient:()=>y,ApiKeyAuth:()=>H,AutomationResource:()=>N,DocumentReportResource:()=>S,DocumentResource:()=>q,ExpenseReportResource:()=>M,ExpenseResource:()=>A,ExportResource:()=>j,NavigablePage:()=>p,NoteReportResource:()=>F,NoteResource:()=>D,OAuth21Auth:()=>ie,OAuth2Auth:()=>R,OAuthDiscovery:()=>V,OrganizationResource:()=>x,PauseResource:()=>$,ProfileResource:()=>U,ProjectResource:()=>w,RateResource:()=>k,ReportsClient:()=>W,Resource:()=>o,RetryConfig:()=>G,SettingsResource:()=>I,TagResource:()=>v,TaskReportResource:()=>z,TaskResource:()=>E,TeamResource:()=>C,TimerResource:()=>_,TimesheetApiError:()=>c,TimesheetAuthError:()=>B,TimesheetClient:()=>ee,TimesheetRateLimitError:()=>K,TodoResource:()=>O,WebhookEvents:()=>ve,WebhookResource:()=>L,combineWebhookEvents:()=>Ae,createClient:()=>Ue,discoverOAuth:()=>ke,generateCodeChallenge:()=>ce,generateCodeVerifier:()=>he,generatePkceCodePair:()=>re,getDefaultDiscovery:()=>le,isValidCodeVerifier:()=>se});module.exports=Ee(Ie);var T=u(require("axios"));var c=class s extends Error{constructor(e,t,r,i){let a=t?i?`${e} (HTTP ${t}, Code: ${i})`:`${e} (HTTP ${t})`:e;super(a),this.name="TimesheetApiError",this.statusCode=t,this.responseBody=r,this.errorCode=i,typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,s)}};var B=class extends c{constructor(e,t=401,r){super(e,t,r,"authentication_error"),this.name="TimesheetAuthError"}};var K=class extends c{constructor(e,t){super(e,429,void 0,"rate_limit_exceeded"),this.name="TimesheetRateLimitError",this.retryAfter=t}getRetryAfterDate(){if(!this.retryAfter)return null;let e=Number(this.retryAfter);if(!isNaN(e))return new Date(e*1e3);let t=new Date(this.retryAfter);return isNaN(t.getTime())?null:t}};var y=class{constructor(e){this.config=e,this.httpClient=e.httpClient||T.default.create({baseURL:e.baseUrl,timeout:3e4,headers:{"User-Agent":"Timesheet-TypeScript-SDK/1.0.0","Content-Type":"application/json"}}),this.httpClient.interceptors.request.use(async t=>{if(t.url!=="/oauth/token"&&this.config.authentication){let r=await this.config.authentication.getAuthHeaders();if(r)for(let[i,a]of Object.entries(r))t.headers.set(i,a)}return t})}async request(e){let t=null,r=this.config.retryConfig;for(let i=0;i<=r.maxRetries;i++)try{return(await this.httpClient.request(e)).data}catch(a){if(t=a,T.default.isAxiosError(a)&&a.response?.status===401){let m=a.response.data;throw new B(m?.message||"Authentication failed",401,JSON.stringify(m))}if(T.default.isAxiosError(a)&&a.response?.status===429){let m=a.response.headers["retry-after"];throw new K("Rate limit exceeded",m)}let h=T.default.isAxiosError(a)?a.response?.status:void 0;if(i<r.maxRetries&&h&&r.retryableStatusCodes.includes(h)){let m=Math.min(r.initialDelay*Math.pow(r.backoffMultiplier,i),r.maxDelay);await this.sleep(m);continue}if(T.default.isAxiosError(a)){let m=a.response?.data;throw new c(m?.message||a.message,a.response?.status,JSON.stringify(m),m?.code)}else throw a instanceof Error?new c(a.message):new c("Unknown error occurred")}throw t||new Error("Unknown error")}async get(e,t){return this.request({method:"GET",url:e,params:t})}async post(e,t,r){return this.request({method:"POST",url:e,data:t,params:r})}async put(e,t,r){return this.request({method:"PUT",url:e,data:t,params:r})}async delete(e,t){return this.request({method:"DELETE",url:e,params:t})}sleep(e){return new Promise(t=>setTimeout(t,e))}};var H=class{constructor(e){this.apiKey=e;if(e===null)throw new Error("API key cannot be null");if(e===void 0)throw new Error("API key cannot be undefined");if(!e)throw new Error("API key cannot be empty");if(typeof e!="string")throw new Error("API key must be a string");if(e.trim().length===0)throw new Error("API key cannot be empty or whitespace");if(!this.isValidFormat(e))throw new Error("Invalid API key format")}isValidFormat(e){return/^ts_[a-zA-Z0-9]+\.[a-zA-Z0-9]+$/.test(e)}applyAuth(e){e.headers||(e.headers={}),e.headers.Authorization=`ApiKey ${this.apiKey}`}needsRefresh(){return!1}async refresh(){throw new Error("API keys cannot be refreshed")}async getAuthHeaders(){return{Authorization:`ApiKey ${this.apiKey}`}}isValid(){return typeof this.apiKey=="string"&&this.apiKey.trim().length>0&&this.isValidFormat(this.apiKey)}};var te=u(require("axios")),me=u(require("jsonwebtoken")),f=class f{constructor(e,t,r){t&&r?(this.clientId=e,this.clientSecret=t,this.refreshToken=r,this.accessToken=""):(this.accessToken=e,this.parseTokenExpiry())}applyAuth(e){e.headers||(e.headers={}),e.headers.Authorization=`Bearer ${this.accessToken}`}needsRefresh(){return this.refreshToken&&!this.accessToken?!0:!this.refreshToken||!this.tokenExpiry?!1:new Date(Date.now()+5*60*1e3)>=this.tokenExpiry}async refresh(){if(!this.refreshToken)throw new Error("Cannot refresh without refresh token");if(this.refreshPromise)return this.refreshPromise;this.refreshPromise=this.performRefresh();try{await this.refreshPromise}finally{this.refreshPromise=void 0}}async performRefresh(){try{let e=await te.default.post(f.TOKEN_ENDPOINT,new URLSearchParams({grant_type:"refresh_token",refresh_token:this.refreshToken,client_id:this.clientId,client_secret:this.clientSecret}),{headers:{"Content-Type":"application/x-www-form-urlencoded"}});this.accessToken=e.data.access_token,e.data.refresh_token&&(this.refreshToken=e.data.refresh_token),this.parseTokenExpiry()}catch(e){let t=e instanceof Error?e.message:"Unknown error";throw new Error(`Failed to refresh OAuth2 token: ${t}`)}}async getAuthHeaders(){return this.needsRefresh()&&await this.refresh(),{Authorization:`Bearer ${this.accessToken}`}}static async fromAuthorizationCode(e,t,r,i){try{let a=await te.default.post(f.TOKEN_ENDPOINT,new URLSearchParams({grant_type:"authorization_code",code:r,redirect_uri:i,client_id:e,client_secret:t}),{headers:{"Content-Type":"application/x-www-form-urlencoded"}}),h=a.data.access_token,m=a.data.refresh_token;return m?new f(e,t,m):new f(h)}catch(a){let h=a instanceof Error?a.message:"Unknown error";throw new Error(`Failed to exchange authorization code: ${h}`)}}static buildAuthorizationUrl(e,t,r){let i=new URLSearchParams({client_id:e,redirect_uri:t,response_type:"code"});return r&&i.append("state",r),`https://api.timesheet.io/oauth2/auth?${i.toString()}`}parseTokenExpiry(){try{let e=me.default.decode(this.accessToken);e&&e.exp&&(this.tokenExpiry=new Date(e.exp*1e3))}catch{this.tokenExpiry=new Date(Date.now()+60*60*1e3)}}};f.TOKEN_ENDPOINT="https://api.timesheet.io/oauth2/token";var R=f;var oe=u(require("axios")),de=u(require("jsonwebtoken"));var X=require("crypto");function he(s=64){if(s<43||s>128)throw new Error("Code verifier length must be between 43 and 128 characters");let e=(0,X.randomBytes)(Math.ceil(s*3/4));return ue(e).slice(0,s)}function ce(s,e="S256"){if(e==="plain")return s;let t=(0,X.createHash)("sha256").update(s,"ascii").digest();return ue(t)}function re(s="S256",e=64){let t=he(e),r=ce(t,s);return{codeVerifier:t,codeChallenge:r,codeChallengeMethod:s}}function se(s){return s.length<43||s.length>128?!1:/^[A-Za-z0-9\-._~]+$/.test(s)}function ue(s){return s.toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var d=class d{constructor(e){if(typeof e=="string")this.accessToken=e,this.tokenEndpoint=d.DEFAULT_TOKEN_ENDPOINT,this.parseTokenExpiry();else{let t=e;this.clientId=t.clientId,this.clientSecret=t.clientSecret,this.refreshToken=t.refreshToken,this.resource=t.resource,this.tokenEndpoint=t.tokenEndpoint??d.DEFAULT_TOKEN_ENDPOINT,this.accessToken=""}}applyAuth(e){e.headers||(e.headers={}),e.headers.Authorization=`Bearer ${this.accessToken}`}needsRefresh(){return this.refreshToken&&!this.accessToken?!0:!this.refreshToken||!this.tokenExpiry?!1:new Date(Date.now()+5*60*1e3)>=this.tokenExpiry}async refresh(){if(!this.refreshToken)throw new Error("Cannot refresh without refresh token");if(this.refreshPromise)return this.refreshPromise;this.refreshPromise=this.performRefresh();try{await this.refreshPromise}finally{this.refreshPromise=void 0}}async performRefresh(){try{let e=new URLSearchParams({grant_type:"refresh_token",refresh_token:this.refreshToken,client_id:this.clientId});this.clientSecret&&e.append("client_secret",this.clientSecret),this.resource&&e.append("resource",this.resource);let t=await oe.default.post(this.tokenEndpoint,e,{headers:{"Content-Type":"application/x-www-form-urlencoded"}});this.accessToken=t.data.access_token,t.data.refresh_token&&(this.refreshToken=t.data.refresh_token),this.parseTokenExpiry()}catch(e){let t=e instanceof Error?e.message:"Unknown error";throw new Error(`Failed to refresh OAuth 2.1 token: ${t}`)}}async getAuthHeaders(){return this.needsRefresh()&&await this.refresh(),{Authorization:`Bearer ${this.accessToken}`}}static async fromAuthorizationCode(e){let{clientId:t,clientSecret:r,authorizationCode:i,redirectUri:a,codeVerifier:h,resource:m,tokenEndpoint:J}=e,Y=J??d.DEFAULT_TOKEN_ENDPOINT;if(!se(h))throw new Error("Invalid code verifier: must be 43-128 characters using only A-Z, a-z, 0-9, -, ., _, ~");try{let g=new URLSearchParams({grant_type:"authorization_code",code:i,redirect_uri:a,client_id:t,code_verifier:h});r&&g.append("client_secret",r),m&&g.append("resource",m);let l=await oe.default.post(Y,g,{headers:{"Content-Type":"application/x-www-form-urlencoded"}}),Te=l.data.access_token,ne=l.data.refresh_token;return ne?new d({clientId:t,clientSecret:r,refreshToken:ne,resource:m,tokenEndpoint:Y}):new d(Te)}catch(g){let l=g instanceof Error?g.message:"Unknown error";throw new Error(`Failed to exchange authorization code: ${l}`)}}static buildAuthorizationUrl(e){let{clientId:t,redirectUri:r,codeChallenge:i,codeChallengeMethod:a="S256",state:h,scope:m,resource:J,authorizationEndpoint:Y}=e,g=Y??d.DEFAULT_AUTH_ENDPOINT,l=new URLSearchParams({response_type:"code",client_id:t,redirect_uri:r,code_challenge:i,code_challenge_method:a});return h&&l.append("state",h),m&&l.append("scope",m),J&&l.append("resource",J),`${g}?${l.toString()}`}static generatePkce(e="S256"){return re(e)}parseTokenExpiry(){try{let e=de.default.decode(this.accessToken);e&&e.exp&&(this.tokenExpiry=new Date(e.exp*1e3))}catch{this.tokenExpiry=new Date(Date.now()+60*60*1e3)}}};d.DEFAULT_TOKEN_ENDPOINT="https://api.timesheet.io/oauth2/token",d.DEFAULT_AUTH_ENDPOINT="https://api.timesheet.io/oauth2/auth";var ie=d;var Q=u(require("axios")),b=class b{constructor(e={}){this.cache=new Map;this.options={cacheTtl:e.cacheTtl??b.DEFAULT_CACHE_TTL,timeout:e.timeout??b.DEFAULT_TIMEOUT,fetchOpenIdConfig:e.fetchOpenIdConfig??!1,fetchProtectedResource:e.fetchProtectedResource??!1}}async discover(e){let t=this.normalizeIssuerUrl(e),r=this.getCached(t);if(r)return r;let i=await this.fetchAuthorizationServerMetadata(t),a={issuer:i.issuer,authorizationServer:i,fetchedAt:new Date};if(this.options.fetchOpenIdConfig)try{a.openIdConfiguration=await this.fetchOpenIdConfiguration(t)}catch{}if(this.options.fetchProtectedResource)try{a.protectedResource=await this.fetchProtectedResourceMetadata(t)}catch{}return this.setCache(t,a),a}async fetchAuthorizationServerMetadata(e){let t=`${this.normalizeIssuerUrl(e)}/.well-known/oauth-authorization-server`;try{let r=await Q.default.get(t,{timeout:this.options.timeout,headers:{Accept:"application/json"}});return this.validateAuthorizationServerMetadata(r.data),r.data}catch(r){let i=r instanceof Error?r.message:"Unknown error";throw new Error(`Failed to fetch authorization server metadata from ${t}: ${i}`)}}async fetchOpenIdConfiguration(e){let t=`${this.normalizeIssuerUrl(e)}/.well-known/openid-configuration`;try{let r=await Q.default.get(t,{timeout:this.options.timeout,headers:{Accept:"application/json"}});return this.validateOpenIdConfiguration(r.data),r.data}catch(r){let i=r instanceof Error?r.message:"Unknown error";throw new Error(`Failed to fetch OpenID configuration from ${t}: ${i}`)}}async fetchProtectedResourceMetadata(e){let t=`${this.normalizeIssuerUrl(e)}/.well-known/oauth-protected-resource`;try{let r=await Q.default.get(t,{timeout:this.options.timeout,headers:{Accept:"application/json"}});return this.validateProtectedResourceMetadata(r.data),r.data}catch(r){let i=r instanceof Error?r.message:"Unknown error";throw new Error(`Failed to fetch protected resource metadata from ${t}: ${i}`)}}clearCache(){this.cache.clear()}clearCacheForIssuer(e){this.cache.delete(this.normalizeIssuerUrl(e))}isCached(e){return this.getCached(this.normalizeIssuerUrl(e))!==null}normalizeIssuerUrl(e){return e.replace(/\/+$/,"")}getCached(e){let t=this.cache.get(e);return t?new Date>=t.expiresAt?(this.cache.delete(e),null):t.result:null}setCache(e,t){let r=new Date(Date.now()+this.options.cacheTtl);this.cache.set(e,{result:t,expiresAt:r})}validateAuthorizationServerMetadata(e){if(!e.issuer)throw new Error("Authorization server metadata missing required field: issuer");if(!e.authorization_endpoint)throw new Error("Authorization server metadata missing required field: authorization_endpoint");if(!e.token_endpoint)throw new Error("Authorization server metadata missing required field: token_endpoint");if(!e.response_types_supported||e.response_types_supported.length===0)throw new Error("Authorization server metadata missing required field: response_types_supported")}validateOpenIdConfiguration(e){if(!e.issuer)throw new Error("OpenID configuration missing required field: issuer");if(!e.authorization_endpoint)throw new Error("OpenID configuration missing required field: authorization_endpoint");if(!e.token_endpoint)throw new Error("OpenID configuration missing required field: token_endpoint");if(!e.jwks_uri)throw new Error("OpenID configuration missing required field: jwks_uri")}validateProtectedResourceMetadata(e){if(!e.resource)throw new Error("Protected resource metadata missing required field: resource");if(!e.authorization_servers||e.authorization_servers.length===0)throw new Error("Protected resource metadata missing required field: authorization_servers")}};b.DEFAULT_CACHE_TTL=60*60*1e3,b.DEFAULT_TIMEOUT=1e4;var V=b,ae=null;function le(){return ae||(ae=new V),ae}async function ke(s,e){return(e?new V(e):le()).discover(s)}var G=class s{constructor(e={}){this.maxRetries=e.maxRetries??3,this.initialDelay=e.initialDelay??100,this.maxDelay=e.maxDelay??1e4,this.backoffMultiplier=e.backoffMultiplier??2,this.retryableStatusCodes=e.retryableStatusCodes??[429,502,503,504]}static default(){return new s}};var p=class{constructor(e,t){this.items=e.items,this.params=e.params,this.nextPageLoader=t}get totalPages(){return Math.ceil((this.params?.count||0)/(this.params?.limit||25))}get hasNextPage(){return(this.params?.page||1)<this.totalPages}async nextPage(){if(!this.hasNextPage)throw new Error("No more pages available");if(!this.nextPageLoader)throw new Error("Next page loader not configured");return this.nextPageLoader((this.params.page||1)+1)}async*[Symbol.asyncIterator](){let e=this;for(;;){for(let t of e.items)yield t;if(!e.hasNextPage)break;e=await e.nextPage()}}async toArray(){let e=[];for await(let t of this)e.push(t);return e}};var ve={TEAM_CREATE:"team.create",TEAM_UPDATE:"team.update",PROJECT_CREATE:"project.create",PROJECT_UPDATE:"project.update",TODO_CREATE:"todo.create",TODO_UPDATE:"todo.update",TASK_CREATE:"task.create",TASK_UPDATE:"task.update",TAG_CREATE:"tag.create",TAG_UPDATE:"tag.update",RATE_CREATE:"rate.create",RATE_UPDATE:"rate.update",TIMER_START:"timer.start",TIMER_STOP:"timer.stop",TIMER_PAUSE:"timer.pause",TIMER_RESUME:"timer.resume"};function Ae(...s){return s.join(",")}var o=class{constructor(e,t){this.http=e;typeof t=="string"?this.basePath=t:this.basePath=t.basePath}createNavigablePage(e,t){return new p(e,t)}};var x=class extends o{constructor(e){super(e,"/v1/organizations")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var C=class extends o{constructor(e){super(e,"/v1/teams")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async listMembers(e,t){let r=await this.http.post(`${this.basePath}/${e}/members/list`,t);return this.createNavigablePage(r,i=>this.listMembers(e,{...t,page:i}))}async getMember(e,t){return this.http.get(`${this.basePath}/${e}/members/${t}`)}async getColleagues(e){let t=await this.http.post(`${this.basePath}/getColleagues`,e);return this.createNavigablePage(t,r=>this.getColleagues({...e,page:r}))}};var w=class extends o{constructor(e){super(e,"/v1/projects")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var P=u(require("dayjs")),ge=u(require("dayjs/plugin/utc")),fe=u(require("dayjs/plugin/timezone")),Pe=u(require("dayjs/plugin/customParseFormat"));P.default.extend(ge.default);P.default.extend(fe.default);P.default.extend(Pe.default);var De="YYYY-MM-DDTHH:mm:ssZ",$e=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{2}:\d{2}$/,n={isValidTimestampFormat(s){return $e.test(s)},formatTimestamp(s){return typeof s=="string"&&this.isValidTimestampFormat(s)?s:(0,P.default)(s||new Date).format(De)},parseTimestamp(s){return(0,P.default)(s).toDate()},formatDate(s){return(0,P.default)(s||new Date).format("YYYY-MM-DD")},now(){return this.formatTimestamp()}};var E=class extends o{constructor(e){super(e,"/v1/tasks")}async create(e){let t={...e,startDateTime:n.formatTimestamp(e.startDateTime),endDateTime:e.endDateTime?n.formatTimestamp(e.endDateTime):void 0};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,startDateTime:t.startDateTime?n.formatTimestamp(t.startDateTime):void 0,endDateTime:t.endDateTime?n.formatTimestamp(t.endDateTime):void 0};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async updateStatus(e){return this.http.put(`${this.basePath}/updateStatus`,e)}async updateTimes(e){let t={...e,startDateTime:n.formatTimestamp(e.startDateTime),endDateTime:n.formatTimestamp(e.endDateTime)};return this.http.put(`${this.basePath}/updateTimes`,t)}};var k=class extends o{constructor(e){super(e,"/v1/rates")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var v=class extends o{constructor(e){super(e,"/v1/tags")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var A=class extends o{constructor(e){super(e,"/v1/expenses")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,dateTime:n.formatTimestamp(e.dateTime)};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,dateTime:t.dateTime?n.formatTimestamp(t.dateTime):void 0};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}async updateStatus(e,t){return this.http.put(`${this.basePath}/${e}/status`,t)}};var D=class extends o{constructor(e){super(e,"/v1/notes")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,dateTime:n.formatTimestamp(e.dateTime)};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,dateTime:n.formatTimestamp(t.dateTime)};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var $=class extends o{constructor(e){super(e,"/v1/pauses")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,startDateTime:n.formatTimestamp(e.startDateTime),endDateTime:n.formatTimestamp(e.endDateTime)};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,startDateTime:n.formatTimestamp(t.startDateTime),endDateTime:n.formatTimestamp(t.endDateTime)};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var U=class{constructor(e){this.http=e}async getProfile(){return this.http.get("/v1/profiles/me")}async updateProfile(e){return this.http.put("/v1/profiles/me",e)}};var I=class{constructor(e){this.http=e}async get(){return this.http.get("/v1/settings")}async update(e){return this.http.put("/v1/settings",e)}};var N=class extends o{constructor(e){super(e,"/v1/automations")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var q=class extends o{constructor(e){super(e,"/v1/documents")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var _=class{constructor(e){this.http=e}async get(){return this.http.get("/v1/timer")}async start(e){let t={...e,startDateTime:e.startDateTime?n.formatTimestamp(e.startDateTime):n.formatTimestamp()};return this.http.post("/v1/timer/start",t)}async stop(e){let t=e?{...e,endDateTime:e.endDateTime?n.formatTimestamp(e.endDateTime):n.formatTimestamp()}:{endDateTime:n.formatTimestamp()};return this.http.post("/v1/timer/stop",t)}async pause(e){let t=e?{...e,startDateTime:e.startDateTime?n.formatTimestamp(e.startDateTime):n.formatTimestamp()}:{startDateTime:n.formatTimestamp()};return this.http.post("/v1/timer/pause",t)}async resume(e){let t=e?{...e,endDateTime:e.endDateTime?n.formatTimestamp(e.endDateTime):n.formatTimestamp()}:{endDateTime:n.formatTimestamp()};return this.http.post("/v1/timer/resume",t)}async update(e){let t={...e,startDateTime:e.startDateTime?n.formatTimestamp(e.startDateTime):void 0};return this.http.put("/v1/timer/update",t)}};var O=class extends o{constructor(e){super(e,"/v1/todos")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){let t={...e,dueDate:e.dueDate?n.formatTimestamp(e.dueDate):void 0};return this.http.post(this.basePath,t)}async update(e,t){let r={...t,dueDate:t.dueDate?n.formatTimestamp(t.dueDate):void 0};return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,r)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var L=class extends o{constructor(e){super(e,"/v1/webhooks")}async list(e){let t=await this.http.get(this.basePath,e);return new p(t,r=>this.list({...e,page:r}))}async create(e){return this.http.post(this.basePath,e)}async update(e,t){return this.http.put(`${this.basePath}/${encodeURIComponent(e)}`,t)}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async delete(e){return this.http.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async search(e){let t=await this.http.post(`${this.basePath}/search`,e);return this.createNavigablePage(t,r=>this.search({...e,page:r}))}};var S=class extends o{constructor(e){super(e,"/v1/documents")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}async getXml(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/xml`,headers:{Accept:"application/xml"}})}};var z=class extends o{constructor(e){super(e,"/v1/tasks")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}};var M=class extends o{constructor(e){super(e,"/v1/expenses")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}};var F=class extends o{constructor(e){super(e,"/v1/notes")}async get(e){return this.http.get(`${this.basePath}/${encodeURIComponent(e)}`)}async getPdf(e){return this.http.request({method:"GET",url:`${this.basePath}/${encodeURIComponent(e)}/pdf`,responseType:"arraybuffer"})}};var j=class extends o{constructor(e){super(e,"/v1/export")}async generate(e){return this.http.post(`${this.basePath}/data`,e)}async send(e){return this.http.post(`${this.basePath}/send`,e)}async generateFromTemplate(e){return this.http.request({method:"POST",url:`${this.basePath}/from-template`,data:e,responseType:"arraybuffer"})}async getFields(e){return this.http.get(`${this.basePath}/fields`,e?{scope:e}:void 0)}async getReportTypes(){return this.http.get(`${this.basePath}/report-types`)}async listTemplates(e){let t=await this.http.get(`${this.basePath}/templates`,e);return new p(t,r=>this.listTemplates({...e,page:r}))}async searchTemplates(e){let t=await this.http.post(`${this.basePath}/templates/search`,e);return this.createNavigablePage(t,r=>this.searchTemplates({...e,page:r}))}async createTemplate(e){return this.http.post(`${this.basePath}/templates`,e)}async getTemplate(e){return this.http.get(`${this.basePath}/templates/${encodeURIComponent(e)}`)}async updateTemplate(e,t){return this.http.put(`${this.basePath}/templates/${encodeURIComponent(e)}`,t)}async deleteTemplate(e){return this.http.delete(`${this.basePath}/templates/${encodeURIComponent(e)}`)}async listCustomFields(e){return this.http.get(`${this.basePath}/custom-fields`,e?{scope:e}:void 0)}async createCustomField(e){return this.http.post(`${this.basePath}/custom-fields`,e)}async getCustomField(e){return this.http.get(`${this.basePath}/custom-fields/${encodeURIComponent(e)}`)}async updateCustomField(e,t){return this.http.put(`${this.basePath}/custom-fields/${encodeURIComponent(e)}`,t)}async deleteCustomField(e){return this.http.delete(`${this.basePath}/custom-fields/${encodeURIComponent(e)}`)}};var W=class{constructor(e){this.documents=new S(e),this.tasks=new z(e),this.expenses=new M(e),this.notes=new F(e),this.export=new j(e)}};var ee=class{constructor(e){let t=this.createAuthentication(e),r=e.retryConfig||G.default(),i={baseUrl:e.baseUrl||"https://api.timesheet.io",authentication:t,retryConfig:r,httpClient:e.httpClient};this.apiClient=new y(i);let a={baseUrl:e.reportsBaseUrl||"https://reports.timesheet.io",authentication:t,retryConfig:r,httpClient:e.reportsHttpClient};this.reportsApiClient=new y(a),this.organizations=new x(this.apiClient),this.teams=new C(this.apiClient),this.projects=new w(this.apiClient),this.tasks=new E(this.apiClient),this.rates=new k(this.apiClient),this.tags=new v(this.apiClient),this.expenses=new A(this.apiClient),this.notes=new D(this.apiClient),this.pauses=new $(this.apiClient),this.profile=new U(this.apiClient),this.settings=new I(this.apiClient),this.automations=new N(this.apiClient),this.documents=new q(this.apiClient),this.timer=new _(this.apiClient),this.todos=new O(this.apiClient),this.webhooks=new L(this.apiClient),this.reports=new W(this.reportsApiClient)}createAuthentication(e){if(e.apiKey)return new H(e.apiKey);if(e.oauth2Token)return new R(e.oauth2Token);if(e.oauth2)return new R(e.oauth2.clientId,e.oauth2.clientSecret,e.oauth2.refreshToken);if(e.authentication)return e.authentication;throw new Error("Authentication must be configured")}};function Ue(s){return new ee(s)}0&&(module.exports={ApiClient,ApiKeyAuth,AutomationResource,DocumentReportResource,DocumentResource,ExpenseReportResource,ExpenseResource,ExportResource,NavigablePage,NoteReportResource,NoteResource,OAuth21Auth,OAuth2Auth,OAuthDiscovery,OrganizationResource,PauseResource,ProfileResource,ProjectResource,RateResource,ReportsClient,Resource,RetryConfig,SettingsResource,TagResource,TaskReportResource,TaskResource,TeamResource,TimerResource,TimesheetApiError,TimesheetAuthError,TimesheetClient,TimesheetRateLimitError,TodoResource,WebhookEvents,WebhookResource,combineWebhookEvents,createClient,discoverOAuth,generateCodeChallenge,generateCodeVerifier,generatePkceCodePair,getDefaultDiscovery,isValidCodeVerifier});
|
|
2
2
|
//# sourceMappingURL=index.js.map
|