Skip to content

Commit 667d017

Browse files
committed
Initialize Tidal API TypeScript client with authentication, error handling, and logging features. Added configuration management, example usage, and comprehensive tests. Included .env example and .gitignore for environment setup.
0 parents  commit 667d017

20 files changed

+7327
-0
lines changed

.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
TIDAL_WORKSPACE=your_workspace_name
2+
TIDAL_USERNAME=your_username
3+
TIDAL_PASSWORD=your_password
4+
LOG_LEVEL=info

.gitignore

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
plans/
2+
3+
# Dependencies
4+
node_modules/
5+
npm-debug.log*
6+
yarn-debug.log*
7+
yarn-error.log*
8+
9+
# Build outputs
10+
dist/
11+
build/
12+
*.tsbuildinfo
13+
14+
# Environment variables
15+
.env
16+
.env.local
17+
.env.development.local
18+
.env.test.local
19+
.env.production.local
20+
21+
# IDE
22+
.vscode/
23+
.idea/
24+
*.swp
25+
*.swo
26+
27+
# OS
28+
.DS_Store
29+
Thumbs.db
30+
31+
# Testing
32+
coverage/
33+
*.lcov
34+
35+
# Logs
36+
logs/
37+
*.log
38+
39+
# Runtime data
40+
pids/
41+
*.pid
42+
*.seed
43+
*.pid.lock

README.md

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
# Tidal API TypeScript Bulk Operations Client
2+
3+
A TypeScript client library for performing bulk operations on Tidal API resources with authentication, error handling, and comprehensive logging.
4+
5+
## ✅ Features
6+
7+
-**Authentication Service**: Complete authentication flow with token refresh using `/authenticate` endpoint
8+
-**API Client**: HTTP client with automatic token management
9+
-**Error Handling**: Comprehensive error types and handling
10+
-**Logging**: Configurable logging with multiple levels
11+
-**Configuration**: Environment-based configuration management
12+
-**TypeScript**: Full type safety and IntelliSense support
13+
-**Testing**: Comprehensive unit tests with >80% coverage
14+
15+
## 📦 Installation
16+
17+
```bash
18+
npm install
19+
```
20+
21+
## 🔧 Configuration
22+
23+
Create a `.env` file based on `.env.example`:
24+
25+
```bash
26+
cp .env.example .env
27+
```
28+
29+
Configure your environment variables:
30+
31+
```env
32+
TIDAL_WORKSPACE=your_workspace_name
33+
TIDAL_USERNAME=your_username
34+
TIDAL_PASSWORD=your_password
35+
LOG_LEVEL=info
36+
```
37+
38+
**Note**: The base URL is automatically generated as `https://{workspace}.tidal.cloud/api/v1` based on your workspace name. You can override this by setting `TIDAL_BASE_URL` if needed.
39+
40+
## 🚀 Quick Start
41+
42+
### Basic Usage
43+
44+
```typescript
45+
import { TidalApiClient } from './src/api/client';
46+
47+
// Create client
48+
const client = new TidalApiClient({
49+
workspace: 'your-workspace'
50+
// baseUrl is auto-generated as https://your-workspace.tidal.cloud/api/v1
51+
});
52+
53+
// Authenticate
54+
await client.authenticate('username', 'password');
55+
56+
// Make API calls
57+
const response = await client.get('/servers');
58+
console.log(response.data);
59+
```
60+
61+
### Using Environment Configuration
62+
63+
```typescript
64+
import { createAuthenticatedClient } from './src/index';
65+
66+
// Automatically loads from environment variables
67+
const client = await createAuthenticatedClient();
68+
69+
// Client is ready to use
70+
const servers = await client.get('/servers');
71+
```
72+
73+
### Manual Authentication Service
74+
75+
```typescript
76+
import { AuthService } from './src/api/auth';
77+
78+
const auth = new AuthService('https://your-workspace.tidal.cloud/api/v1');
79+
80+
// Authenticate
81+
const tokens = await auth.authenticate({
82+
username: 'your-username',
83+
password: 'your-password'
84+
});
85+
86+
// Check token validity
87+
if (auth.isTokenValid()) {
88+
const token = auth.getAccessToken();
89+
// Use token for API calls
90+
}
91+
92+
// Refresh token when needed
93+
if (!auth.isTokenValid()) {
94+
await auth.refreshAccessToken();
95+
}
96+
```
97+
98+
## 🔍 API Reference
99+
100+
### TidalApiClient
101+
102+
```typescript
103+
class TidalApiClient {
104+
constructor(config: ClientConfig)
105+
106+
// Authentication
107+
authenticate(username: string, password: string): Promise<AuthResponse>
108+
isAuthenticated(): boolean
109+
110+
// HTTP Methods
111+
get<T>(endpoint: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>>
112+
post<T>(endpoint: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>>
113+
put<T>(endpoint: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>>
114+
patch<T>(endpoint: string, data?: any, config?: AxiosRequestConfig): Promise<ApiResponse<T>>
115+
delete<T>(endpoint: string, config?: AxiosRequestConfig): Promise<ApiResponse<T>>
116+
117+
// Utility
118+
getWorkspace(): string
119+
getBaseUrl(): string
120+
}
121+
```
122+
123+
### AuthService
124+
125+
```typescript
126+
class AuthService {
127+
constructor(baseUrl: string)
128+
129+
authenticate(credentials: AuthCredentials): Promise<AuthResponse>
130+
isTokenValid(): boolean
131+
getAccessToken(): string | null
132+
refreshAccessToken(): Promise<AuthResponse>
133+
clearTokens(): void
134+
ensureValidToken(credentials?: AuthCredentials): Promise<string>
135+
}
136+
```
137+
138+
## 🧪 Testing
139+
140+
Run the test suite:
141+
142+
```bash
143+
# Run all tests
144+
npm test
145+
146+
# Run tests in watch mode
147+
npm run test:watch
148+
149+
# Run tests with coverage
150+
npm test -- --coverage
151+
```
152+
153+
## 📝 Development
154+
155+
### Build
156+
157+
```bash
158+
npm run build
159+
```
160+
161+
### Linting
162+
163+
```bash
164+
npm run lint
165+
```
166+
167+
### Development Mode
168+
169+
```bash
170+
npm run dev
171+
```
172+
173+
## 🔧 Error Handling
174+
175+
The client provides comprehensive error handling:
176+
177+
```typescript
178+
import { TidalApiError, AuthenticationError, ConfigurationError } from './src/utils/errors';
179+
180+
try {
181+
await client.authenticate('invalid', 'credentials');
182+
} catch (error) {
183+
if (error instanceof AuthenticationError) {
184+
console.error('Authentication failed:', error.message);
185+
} else if (error instanceof TidalApiError) {
186+
console.error('API error:', error.status, error.message);
187+
}
188+
}
189+
```
190+
191+
## 📊 Logging
192+
193+
Configure logging levels:
194+
195+
```typescript
196+
import { logger, LogLevel } from './src/utils/logger';
197+
198+
// Set log level
199+
logger.setLevel(LogLevel.DEBUG);
200+
201+
// Log messages
202+
logger.info('Client initialized');
203+
logger.debug('Making API request', { endpoint: '/servers' });
204+
logger.error('Request failed', { error: 'Network timeout' });
205+
```
206+
207+
## 🤝 Contributing
208+
209+
1. Fork the repository
210+
2. Create a feature branch
211+
3. Make your changes
212+
4. Add tests
213+
5. Run the test suite
214+
6. Submit a pull request

examples/basic-authentication.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#!/usr/bin/env ts-node
2+
3+
/**
4+
* Basic Authentication Example
5+
*
6+
* This example demonstrates how to:
7+
* 1. Load configuration from .env file
8+
* 2. Create a Tidal API client with environment config
9+
* 3. Authenticate with credentials from .env
10+
* 4. Make basic API calls
11+
* 5. Handle errors gracefully
12+
*
13+
* Prerequisites:
14+
* - Create a .env file based on .env.example
15+
* - Set TIDAL_WORKSPACE, TIDAL_USERNAME, TIDAL_PASSWORD
16+
*/
17+
18+
import { TidalApiClient, createAuthenticatedClient } from '../src/index';
19+
import { AuthenticationError, TidalApiError } from '../src/utils/errors';
20+
import { logger } from '../src/utils/logger';
21+
import { loadConfig, getAuthCredentials } from '../src/config/environment';
22+
23+
async function basicAuthenticationExample() {
24+
console.log('🚀 Tidal API Basic Authentication Example\n');
25+
26+
try {
27+
// Method 1: Manual client creation and authentication
28+
console.log('📝 Method 1: Manual Authentication');
29+
30+
// Load configuration from environment
31+
const config = loadConfig();
32+
const credentials = getAuthCredentials();
33+
34+
const client = new TidalApiClient({
35+
workspace: config.workspace,
36+
baseUrl: config.baseUrl
37+
});
38+
39+
// Authenticate with credentials from .env
40+
await client.authenticate(credentials.username, credentials.password);
41+
console.log('✅ Authentication successful!');
42+
console.log(`📍 Workspace: ${client.getWorkspace()}`);
43+
console.log(`🌐 Base URL: ${client.getBaseUrl()}`);
44+
console.log(`🔐 Authenticated: ${client.isAuthenticated()}\n`);
45+
46+
// Make a test API call
47+
try {
48+
console.log('📡 Making test API call to /servers...');
49+
const response = await client.get('/servers');
50+
console.log(`✅ API call successful! Status: ${response.status}`);
51+
console.log(`📊 Received ${response.data?.length || 0} servers\n`);
52+
} catch (apiError) {
53+
console.log('⚠️ API call failed (this is expected if endpoint doesn\'t exist)');
54+
console.log(` Error: ${apiError instanceof Error ? apiError.message : String(apiError)}\n`);
55+
}
56+
57+
} catch (error) {
58+
if (error instanceof AuthenticationError) {
59+
console.error('❌ Authentication failed:', error.message);
60+
console.error(' Please check your credentials in .env file\n');
61+
} else if (error instanceof TidalApiError) {
62+
console.error('❌ API Error:', error.message);
63+
console.error(` Status: ${error.status}, Code: ${error.code}\n`);
64+
} else {
65+
console.error('❌ Unexpected error:', error instanceof Error ? error.message : String(error));
66+
console.error(' Make sure your .env file is configured with TIDAL_WORKSPACE, TIDAL_USERNAME, TIDAL_PASSWORD\n');
67+
}
68+
}
69+
70+
try {
71+
// Method 2: Using environment variables (recommended)
72+
console.log('📝 Method 2: Environment-based Authentication');
73+
console.log(' (Make sure to set TIDAL_WORKSPACE, TIDAL_USERNAME, TIDAL_PASSWORD in .env)');
74+
75+
// This will automatically load from environment variables
76+
const envClient = await createAuthenticatedClient();
77+
console.log('✅ Environment-based authentication successful!');
78+
console.log(`📍 Workspace: ${envClient.getWorkspace()}`);
79+
console.log(`🔐 Authenticated: ${envClient.isAuthenticated()}\n`);
80+
81+
} catch (error) {
82+
console.log('⚠️ Environment-based authentication failed');
83+
console.log(' This is expected if .env file is not configured');
84+
console.log(` Error: ${error instanceof Error ? error.message : String(error)}\n`);
85+
}
86+
87+
console.log('🎉 Example completed!');
88+
console.log('\n📚 Next steps:');
89+
console.log(' 1. Ensure your .env file has valid Tidal credentials');
90+
console.log(' 2. Try making API calls to your Tidal workspace');
91+
console.log(' 3. Explore bulk operations in Phase 2');
92+
console.log('\n💡 Note: Both methods above use the same .env configuration');
93+
}
94+
95+
// Run the example
96+
if (require.main === module) {
97+
basicAuthenticationExample().catch(console.error);
98+
}
99+
100+
export { basicAuthenticationExample };

jest.config.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module.exports = {
2+
preset: "ts-jest",
3+
testEnvironment: "node",
4+
roots: ["<rootDir>/src", "<rootDir>/tests"],
5+
testMatch: ["**/__tests__/**/*.ts", "**/?(*.)+(spec|test).ts"],
6+
transform: {
7+
"^.+\\.ts$": "ts-jest",
8+
},
9+
collectCoverageFrom: ["src/**/*.ts", "!src/**/*.d.ts", "!src/index.ts"],
10+
coverageDirectory: "coverage",
11+
coverageReporters: ["text", "lcov", "html"],
12+
setupFilesAfterEnv: ["<rootDir>/tests/setup.ts"],
13+
testTimeout: 10000,
14+
};

0 commit comments

Comments
 (0)