New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@timesheet/sdk

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@timesheet/sdk

Official TypeScript SDK for the Timesheet API

latest
Source
npmnpm
Version
1.0.6
Version published
Maintainers
1
Created
Source

Timesheet TypeScript SDK

npm version npm downloads Build Status License TypeScript

The official TypeScript SDK for the Timesheet API, providing a comprehensive solution for time tracking, project management, and team collaboration.

Features

  • Type-Safe - Full TypeScript support with comprehensive types
  • Modern Architecture - Promise-based with async/await support
  • Authentication - Built-in API Key, OAuth2, and OAuth 2.1 (PKCE) with automatic discovery (RFC 8414)
  • Error Handling - Typed exceptions for better error management
  • Pagination - Automatic pagination with async iterators
  • Retry Logic - Configurable retry with exponential backoff
  • Lightweight - Minimal dependencies
  • Tree-Shakeable - Import only what you need
  • Well Documented - Extensive JSDoc and examples

Installation

npm install @timesheet/sdk
# or
yarn add @timesheet/sdk
# or
pnpm add @timesheet/sdk

Quick Start

import { TimesheetClient } from '@timesheet/sdk';

// Initialize with API key
const client = new TimesheetClient({
  apiKey: 'your-api-key'
});

// Create a project
const project = await client.projects.create({
  title: 'My Project',
  description: 'Created with TypeScript SDK'
});

// Start a timer
const timer = await client.timer.start({
  projectId: project.id,
  startDateTime: new Date().toISOString()
});

// List recent tasks
const tasks = await client.tasks.list({
  limit: 10,
  sort: 'created',
  order: 'desc'
});

console.log(`Found ${tasks.params.count} tasks`);

Authentication

API Key Authentication

const client = new TimesheetClient({
  apiKey: 'your-api-key'
});

OAuth2 Authentication

const client = new TimesheetClient({
  oauth2Token: 'your-access-token'
});

// With automatic token refresh
const client = new TimesheetClient({
  oauth2: {
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret',
    refreshToken: 'your-refresh-token'
  }
});

OAuth 2.1 Authentication (with PKCE)

OAuth 2.1 is the recommended authentication method for new applications. It requires PKCE (Proof Key for Code Exchange) for enhanced security.

import { OAuth21Auth, generatePkceCodePair } from '@timesheet/sdk';

// Step 1: Generate PKCE code pair
const pkce = generatePkceCodePair();
// Store pkce.codeVerifier securely (e.g., in session storage)

// Step 2: Build authorization URL and redirect user
const authUrl = OAuth21Auth.buildAuthorizationUrl({
  clientId: 'your-client-id',
  redirectUri: 'https://your-app.com/callback',
  codeChallenge: pkce.codeChallenge,
  codeChallengeMethod: pkce.codeChallengeMethod,
  state: 'random-csrf-state', // Optional but recommended
  scope: 'read write',        // Optional
});

// Redirect user to authUrl...

// Step 3: After user authorizes, exchange code for tokens
const auth = await OAuth21Auth.fromAuthorizationCode({
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret', // Optional for public clients
  authorizationCode: codeFromCallback,
  redirectUri: 'https://your-app.com/callback',
  codeVerifier: pkce.codeVerifier,
});

// Step 4: Use with TimesheetClient
const client = new TimesheetClient({
  authentication: auth
});

OAuth 2.1 with Endpoint Discovery (RFC 8414)

The SDK supports automatic endpoint discovery from /.well-known/oauth-authorization-server, allowing you to dynamically configure OAuth endpoints:

import { OAuth21Auth, OAuthDiscovery, generatePkceCodePair } from '@timesheet/sdk';

// Step 1: Discover OAuth endpoints
const discovery = new OAuthDiscovery();
const metadata = await discovery.discover('https://api.timesheet.io');

console.log('Authorization endpoint:', metadata.authorizationServer.authorization_endpoint);
console.log('Token endpoint:', metadata.authorizationServer.token_endpoint);
console.log('Supported scopes:', metadata.authorizationServer.scopes_supported);

// Step 2: Generate PKCE and build authorization URL using discovered endpoints
const pkce = generatePkceCodePair();

const authUrl = OAuth21Auth.buildAuthorizationUrl({
  clientId: 'your-client-id',
  redirectUri: 'https://your-app.com/callback',
  codeChallenge: pkce.codeChallenge,
  codeChallengeMethod: pkce.codeChallengeMethod,
  scope: 'read write',
  state: 'random-csrf-state',
  authorizationEndpoint: metadata.authorizationServer.authorization_endpoint,
});

// Store pkce.codeVerifier and token endpoint securely, then redirect user
sessionStorage.setItem('pkce_verifier', pkce.codeVerifier);
sessionStorage.setItem('token_endpoint', metadata.authorizationServer.token_endpoint);

// Step 3: After callback, exchange code using discovered token endpoint
const auth = await OAuth21Auth.fromAuthorizationCode({
  clientId: 'your-client-id',
  authorizationCode: codeFromCallback,
  redirectUri: 'https://your-app.com/callback',
  codeVerifier: sessionStorage.getItem('pkce_verifier'),
  tokenEndpoint: sessionStorage.getItem('token_endpoint'),
});

const client = new TimesheetClient({
  authentication: auth
});

The OAuthDiscovery class provides caching and additional discovery options:

import { OAuthDiscovery, discoverOAuth } from '@timesheet/sdk';

// Using convenience function (uses shared cached instance)
const result = await discoverOAuth('https://api.timesheet.io');

// Using class with custom options
const discovery = new OAuthDiscovery({
  cacheTtl: 3600000,           // Cache for 1 hour (default)
  timeout: 10000,              // Request timeout in ms
  fetchOpenIdConfig: true,      // Also fetch OpenID Connect config
  fetchProtectedResource: true, // Also fetch protected resource metadata (RFC 9728)
});

const metadata = await discovery.discover('https://api.timesheet.io');

// Check cache status
if (discovery.isCached('https://api.timesheet.io')) {
  console.log('Using cached metadata');
}

// Clear cache when needed
discovery.clearCache();

Using OAuth 2.1 with existing tokens

import { OAuth21Auth } from '@timesheet/sdk';

// With just an access token
const auth = new OAuth21Auth('your-access-token');

// With refresh token for automatic token refresh
const auth = new OAuth21Auth({
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret', // Optional for public clients
  refreshToken: 'your-refresh-token',
});

const client = new TimesheetClient({
  authentication: auth
});

Resources

All API resources are available through the client:

client.tasks         // Task management
client.projects      // Project management
client.tags          // Tag management
client.teams         // Team management
client.organizations // Organization settings
client.timer         // Real-time time tracking
client.rates         // Billing rates
client.expenses      // Expense tracking
client.notes         // Note attachments
client.pauses        // Break time tracking
client.documents     // Document generation
client.webhooks      // Event notifications
client.automations   // Time tracking automation
client.todos         // Task management
client.profile       // User profile
client.settings      // User settings

Examples

Task Management

// Create a task
const task = await client.tasks.create({
  projectId: 'project-id',
  description: 'Implement new feature',
  startDateTime: new Date(Date.now() - 3600000).toISOString(), // 1 hour ago
  endDateTime: new Date().toISOString(),
  tagIds: ['tag-1', 'tag-2'],
  billable: true
});

// Update task
await client.tasks.update(task.id, {
  description: 'Implement new feature - completed'
});

// Search tasks
const results = await client.tasks.searchAdvanced({
  projectIds: ['project-id'],
  search: 'feature',
  startDate: '2024-01-01',
  endDate: '2024-01-31'
});

Project Management

// Create a project
const project = await client.projects.create({
  title: 'New Website',
  teamId: 'team-id',
  color: 3,
  taskDefaultBillable: true
});

// List projects with filters
const projects = await client.projects.list({
  status: 'active',
  limit: 20
});

Timer Operations

// Start a timer
const timer = await client.timer.start({
  projectId: 'project-id',
  startDateTime: new Date().toISOString()
});

// Pause the timer
await client.timer.pause({
  startDateTime: new Date().toISOString()
});

// Resume the timer
await client.timer.resume({
  endDateTime: new Date().toISOString()
});

// Stop and create task
const stoppedTimer = await client.timer.stop({
  endDateTime: new Date().toISOString()
});

Pagination

// Manual pagination
const firstPage = await client.tasks.list({ limit: 50 });
console.log(`Page ${firstPage.params.page} of ${firstPage.totalPages}`);
console.log(`Total items: ${firstPage.params.count}`);

// Get next page
if (firstPage.hasNextPage) {
  const nextPage = await firstPage.nextPage();
}

// Auto-pagination with async iterator
const allTasks = await client.tasks.list({ projectId: 'project-id' });
for await (const task of allTasks) {
  console.log(task.description);
}

// Collect all results across all pages
const allTasksArray = await client.tasks.list({ 
  projectId: 'project-id' 
}).then(page => page.toArray());

Error Handling

import { 
  TimesheetApiError,
  TimesheetAuthError,
  TimesheetRateLimitError
} from '@timesheet/sdk';

try {
  const task = await client.tasks.get('task-id');
} catch (error) {
  if (error instanceof TimesheetAuthError) {
    console.error('Authentication failed');
  } else if (error instanceof TimesheetRateLimitError) {
    console.error(`Rate limited. Retry after: ${error.retryAfter}s`);
  } else if (error instanceof TimesheetApiError) {
    console.error(`API error: ${error.statusCode} - ${error.message}`);
  }
}

TypeScript Support

The SDK is written in TypeScript and provides comprehensive type definitions:

import type { 
  Task,
  Project,
  TaskCreateRequest,
  TaskListQueryParams,
  NavigablePage
} from '@timesheet/sdk';

// All methods are fully typed
const task: Task = await client.tasks.get('task-id');
const projects: NavigablePage<Project> = await client.projects.list();

// Type-safe parameters
const params: TaskCreateRequest = {
  projectId: 'project-id',
  description: 'Task description',
  billable: true,
  startDateTime: new Date().toISOString()
};

Documentation

Contributing

We welcome contributions! Please see our Contributing Guidelines for details.

Development

# Clone the repository
git clone https://github.com/timesheetIO/timesheet-typescript.git
cd timesheet-typescript

# Install dependencies
npm install

# Run tests
npm test

# Build the project
npm run build

# Generate documentation
npm run docs

Support

License

This SDK is distributed under the Apache License 2.0.

Changelog

See CHANGELOG.md for a list of changes.

Made with ❤️ by the timesheet.io team

Keywords

timesheet

FAQs

Package last updated on 26 Jan 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts