chore: fix typescript config issues

This commit is contained in:
Ralph Khreish
2025-09-07 16:12:51 -07:00
parent 022280024c
commit 94bff8391c
16 changed files with 62 additions and 55 deletions

View File

@@ -4,7 +4,7 @@
import os from 'os'; import os from 'os';
import path from 'path'; import path from 'path';
import { AuthConfig } from './types'; import { AuthConfig } from './types.js';
// Single base domain for all URLs // Single base domain for all URLs
// Build-time: process.env.TM_PUBLIC_BASE_DOMAIN gets replaced by tsup's env option // Build-time: process.env.TM_PUBLIC_BASE_DOMAIN gets replaced by tsup's env option

View File

@@ -427,7 +427,7 @@ describe('CredentialStore', () => {
// Should not throw // Should not throw
expect(() => store.clearCredentials()).not.toThrow(); expect(() => store.clearCredentials()).not.toThrow();
// Should not try to unlink non-existent file // Should not try to unlink non-existent file
expect(fs.unlinkSync).not.toHaveBeenCalled(); expect(fs.unlinkSync).not.toHaveBeenCalled();
}); });
@@ -511,18 +511,20 @@ describe('CredentialStore', () => {
// Credentials without expiry are considered invalid // Credentials without expiry are considered invalid
expect(store.hasValidCredentials()).toBe(false); expect(store.hasValidCredentials()).toBe(false);
// Should log warning about missing expiration // Should log warning about missing expiration
expect(mockLogger.warn).toHaveBeenCalledWith('No valid expiration time provided for token'); expect(mockLogger.warn).toHaveBeenCalledWith(
'No valid expiration time provided for token'
);
}); });
it('should use allowExpired=false by default', () => { it('should use allowExpired=false by default', () => {
// Spy on getCredentials to verify it's called with correct params // Spy on getCredentials to verify it's called with correct params
const getCredentialsSpy = vi.spyOn(store, 'getCredentials'); const getCredentialsSpy = vi.spyOn(store, 'getCredentials');
vi.mocked(fs.existsSync).mockReturnValue(false); vi.mocked(fs.existsSync).mockReturnValue(false);
store.hasValidCredentials(); store.hasValidCredentials();
expect(getCredentialsSpy).toHaveBeenCalledWith({ allowExpired: false }); expect(getCredentialsSpy).toHaveBeenCalledWith({ allowExpired: false });
}); });
}); });

View File

@@ -10,11 +10,11 @@ import { getLogger } from '../logger/index.js';
/** /**
* CredentialStore manages the persistence and retrieval of authentication credentials. * CredentialStore manages the persistence and retrieval of authentication credentials.
* *
* Runtime vs Persisted Shape: * Runtime vs Persisted Shape:
* - When retrieved (getCredentials): expiresAt is normalized to number (milliseconds since epoch) * - When retrieved (getCredentials): expiresAt is normalized to number (milliseconds since epoch)
* - When persisted (saveCredentials): expiresAt is stored as ISO string for readability * - When persisted (saveCredentials): expiresAt is stored as ISO string for readability
* *
* This normalization ensures consistent runtime behavior while maintaining * This normalization ensures consistent runtime behavior while maintaining
* human-readable persisted format in the auth.json file. * human-readable persisted format in the auth.json file.
*/ */
@@ -67,12 +67,15 @@ export class CredentialStore {
// Check if the token has expired (with clock skew tolerance) // Check if the token has expired (with clock skew tolerance)
const now = Date.now(); const now = Date.now();
const allowExpired = options?.allowExpired ?? false; const allowExpired = options?.allowExpired ?? false;
if (now >= (expiresAtMs - this.CLOCK_SKEW_MS) && !allowExpired) { if (now >= expiresAtMs - this.CLOCK_SKEW_MS && !allowExpired) {
this.logger.warn('Authentication token has expired or is about to expire', { this.logger.warn(
expiresAt: authData.expiresAt, 'Authentication token has expired or is about to expire',
currentTime: new Date(now).toISOString(), {
skewWindow: `${this.CLOCK_SKEW_MS / 1000}s` expiresAt: authData.expiresAt,
}); currentTime: new Date(now).toISOString(),
skewWindow: `${this.CLOCK_SKEW_MS / 1000}s`
}
);
return null; return null;
} }
@@ -206,12 +209,12 @@ export class CredentialStore {
for (const entry of entries) { for (const entry of entries) {
if (!entry.isFile()) continue; if (!entry.isFile()) continue;
const file = entry.name; const file = entry.name;
// Check if file matches pattern: baseName.corrupt-{timestamp} // Check if file matches pattern: baseName.corrupt-{timestamp}
if (!file.startsWith(prefix)) continue; if (!file.startsWith(prefix)) continue;
const suffix = file.slice(prefix.length); const suffix = file.slice(prefix.length);
if (!/^\d+$/.test(suffix)) continue; // Fixed regex, not from variable input if (!/^\d+$/.test(suffix)) continue; // Fixed regex, not from variable input
const filePath = path.join(dir, file); const filePath = path.join(dir, file);
try { try {
const stats = fs.statSync(filePath); const stats = fs.statSync(filePath);

View File

@@ -2,20 +2,20 @@
* Authentication module exports * Authentication module exports
*/ */
export { AuthManager } from './auth-manager'; export { AuthManager } from './auth-manager.js';
export { CredentialStore } from './credential-store'; export { CredentialStore } from './credential-store.js';
export { OAuthService } from './oauth-service'; export { OAuthService } from './oauth-service.js';
export type { export type {
AuthCredentials, AuthCredentials,
OAuthFlowOptions, OAuthFlowOptions,
AuthConfig, AuthConfig,
CliData CliData
} from './types'; } from './types.js';
export { AuthenticationError } from './types'; export { AuthenticationError } from './types.js';
export { export {
DEFAULT_AUTH_CONFIG, DEFAULT_AUTH_CONFIG,
getAuthConfig getAuthConfig
} from './config'; } from './config.js';

View File

@@ -12,11 +12,11 @@ import {
OAuthFlowOptions, OAuthFlowOptions,
AuthConfig, AuthConfig,
CliData CliData
} from './types'; } from './types.js';
import { CredentialStore } from './credential-store'; import { CredentialStore } from './credential-store.js';
import { SupabaseAuthClient } from '../clients/supabase-client'; import { SupabaseAuthClient } from '../clients/supabase-client.js';
import { getAuthConfig } from './config'; import { getAuthConfig } from './config.js';
import { getLogger } from '../logger'; import { getLogger } from '../logger/index.js';
import packageJson from '../../../../package.json' with { type: 'json' }; import packageJson from '../../../../package.json' with { type: 'json' };
export class OAuthService { export class OAuthService {

View File

@@ -2,4 +2,4 @@
* Client exports * Client exports
*/ */
export { SupabaseAuthClient } from './supabase-client'; export { SupabaseAuthClient } from './supabase-client.js';

View File

@@ -3,8 +3,8 @@
*/ */
import { createClient, SupabaseClient, User } from '@supabase/supabase-js'; import { createClient, SupabaseClient, User } from '@supabase/supabase-js';
import { AuthenticationError } from '../auth/types'; import { AuthenticationError } from '../auth/types.js';
import { getLogger } from '../logger'; import { getLogger } from '../logger/index.js';
export class SupabaseAuthClient { export class SupabaseAuthClient {
private client: SupabaseClient | null = null; private client: SupabaseClient | null = null;

View File

@@ -9,19 +9,19 @@ export {
createTaskMasterCore, createTaskMasterCore,
type TaskMasterCoreOptions, type TaskMasterCoreOptions,
type ListTasksResult type ListTasksResult
} from './task-master-core'; } from './task-master-core.js';
// Re-export types // Re-export types
export type * from './types'; export type * from './types/index.js';
// Re-export interfaces (types only to avoid conflicts) // Re-export interfaces (types only to avoid conflicts)
export type * from './interfaces'; export type * from './interfaces/index.js';
// Re-export constants // Re-export constants
export * from './constants'; export * from './constants/index.js';
// Re-export providers // Re-export providers
export * from './providers'; export * from './providers/index.js';
// Re-export storage (selectively to avoid conflicts) // Re-export storage (selectively to avoid conflicts)
export { export {
@@ -29,20 +29,20 @@ export {
ApiStorage, ApiStorage,
StorageFactory, StorageFactory,
type ApiStorageConfig type ApiStorageConfig
} from './storage'; } from './storage/index.js';
export { PlaceholderStorage, type StorageAdapter } from './storage'; export { PlaceholderStorage, type StorageAdapter } from './storage/index.js';
// Re-export parser // Re-export parser
export * from './parser'; export * from './parser/index.js';
// Re-export utilities // Re-export utilities
export * from './utils'; export * from './utils/index.js';
// Re-export errors // Re-export errors
export * from './errors'; export * from './errors/index.js';
// Re-export entities // Re-export entities
export { TaskEntity } from './entities/task.entity'; export { TaskEntity } from './entities/task.entity.js';
// Re-export authentication // Re-export authentication
export { export {
@@ -51,7 +51,7 @@ export {
type AuthCredentials, type AuthCredentials,
type OAuthFlowOptions, type OAuthFlowOptions,
type AuthConfig type AuthConfig
} from './auth'; } from './auth/index.js';
// Re-export logger // Re-export logger
export { getLogger, createLogger, setGlobalLogger } from './logger'; export { getLogger, createLogger, setGlobalLogger } from './logger/index.js';

View File

@@ -3,7 +3,7 @@
* This file defines the contract for configuration management * This file defines the contract for configuration management
*/ */
import type { TaskComplexity, TaskPriority } from '../types/index'; import type { TaskComplexity, TaskPriority } from '../types/index.js';
/** /**
* Model configuration for different AI roles * Model configuration for different AI roles

View File

@@ -4,13 +4,13 @@
*/ */
// Storage interfaces // Storage interfaces
export type * from './storage.interface'; export type * from './storage.interface.js';
export * from './storage.interface'; export * from './storage.interface.js';
// AI Provider interfaces // AI Provider interfaces
export type * from './ai-provider.interface'; export type * from './ai-provider.interface.js';
export * from './ai-provider.interface'; export * from './ai-provider.interface.js';
// Configuration interfaces // Configuration interfaces
export type * from './configuration.interface'; export type * from './configuration.interface.js';
export * from './configuration.interface'; export * from './configuration.interface.js';

View File

@@ -3,7 +3,7 @@
* This file defines the contract for all storage implementations * This file defines the contract for all storage implementations
*/ */
import type { Task, TaskMetadata } from '../types/index'; import type { Task, TaskMetadata } from '../types/index.js';
/** /**
* Interface for storage operations on tasks * Interface for storage operations on tasks

View File

@@ -2,7 +2,7 @@
* @fileoverview Logger factory and singleton management * @fileoverview Logger factory and singleton management
*/ */
import { Logger, LoggerConfig } from './logger.js'; import { Logger, type LoggerConfig } from './logger.js';
// Global logger instance // Global logger instance
let globalLogger: Logger | null = null; let globalLogger: Logger | null = null;

View File

@@ -3,7 +3,7 @@
* This file exports all parsing-related classes and functions * This file exports all parsing-related classes and functions
*/ */
import type { PlaceholderTask } from '../types/index'; import type { PlaceholderTask } from '../types/index.js';
// Parser implementations will be defined here // Parser implementations will be defined here
// export * from './prd-parser.js'; // export * from './prd-parser.js';

View File

@@ -3,4 +3,4 @@
* Provides business logic and service layer functionality * Provides business logic and service layer functionality
*/ */
export { TaskService } from './task-service'; export { TaskService } from './task-service.js';

View File

@@ -11,7 +11,7 @@ export {
isValidTaskId, isValidTaskId,
isValidSubtaskId, isValidSubtaskId,
getParentTaskId getParentTaskId
} from './id-generator'; } from './id-generator.js';
// Additional utility exports // Additional utility exports

View File

@@ -24,6 +24,8 @@
"skipLibCheck": true, "skipLibCheck": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"moduleResolution": "bundler", "moduleResolution": "bundler",
"moduleDetection": "force",
"types": ["node"],
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": true,
"paths": { "paths": {