Skip to content

Commit 6113c42

Browse files
committed
feat: standardize TypeScript imports to use .ts extensions
## Summary - Convert all relative imports from .js to .ts extensions (564 imports across 169 files) - Update ESLint rules to enforce .ts import pattern and prevent regression - Fix remaining barrel imports to use focused facade pattern - Add comprehensive documentation for TypeScript import standards ## Background/Details The project used mixed import extensions (.js and .ts) which created inconsistency and prevented compatibility with native TypeScript runtimes like Bun and Deno. The .js imports were a legacy pattern from older TypeScript compilation setups. ## Solution 1. **Automated Conversion**: Created script to convert all relative .js imports to .ts 2. **ESLint Enforcement**: Updated rules to catch both .js imports and barrel imports 3. **External Package Handling**: Preserved .js extensions for external packages (required) 4. **Focused Facades**: Completed migration from barrel imports to focused facade pattern ## Testing - All 1046 tests pass - Build compiles successfully - ESLint passes with no violations - Verified compatibility with current build system ## Benefits - Future-proof for native TypeScript runtimes (Bun, Deno, Node.js --loader) - Better IDE experience with direct source file navigation - Consistent import pattern matching actual source files - Automated enforcement prevents regression
1 parent 79cacba commit 6113c42

186 files changed

Lines changed: 603 additions & 565 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AGENTS.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,34 @@ This approach ensures that tests are robust, easy to maintain, and verify the ac
165165

166166
For complete guidelines, refer to @docs/TESTING.md.
167167

168+
## TypeScript Import Standards
169+
170+
This project uses **TypeScript file extensions** (`.ts`) for all relative imports to ensure compatibility with native TypeScript runtimes.
171+
172+
### Import Rules
173+
174+
-**Use `.ts` extensions**: `import { tool } from './tool.ts'`
175+
-**Use `.ts` for re-exports**: `export { default } from '../shared/tool.ts'`
176+
-**External packages use `.js`**: `import { McpServer } from '@camsoft/mcp-sdk/server/mcp.js'`
177+
-**Never use `.js` for internal files**: `import { tool } from './tool.js'` ← ESLint error
178+
179+
### Benefits
180+
181+
1. **Future-proof**: Compatible with native TypeScript runtimes (Bun, Deno, Node.js --loader)
182+
2. **IDE Experience**: Direct navigation to source TypeScript files
183+
3. **Consistency**: Import path matches the actual file you're editing
184+
4. **Modern Standard**: Aligns with TypeScript 4.7+ `allowImportingTsExtensions`
185+
186+
### ESLint Enforcement
187+
188+
The project automatically enforces this standard:
189+
190+
```bash
191+
npm run lint # Will catch .js imports for internal files
192+
```
193+
194+
This ensures all new code follows the `.ts` import pattern and maintains compatibility with both current and future TypeScript execution environments.
195+
168196
## Release Process
169197

170198
Follow standardized development workflow with feature branches, structured pull requests, and linear commit history. **Never push to main directly or force push without permission.**

eslint.config.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,16 @@ export default [
5959

6060
// Prevent barrel imports to maintain architectural improvements
6161
'no-restricted-imports': ['error', {
62-
patterns: [{
63-
group: ['**/utils/index.js', '../utils/index.js', '../../utils/index.js', '../../../utils/index.js'],
64-
message: 'Barrel imports from utils/index.js are prohibited. Use focused facade imports instead (e.g., utils/logging/index.js, utils/execution/index.js).'
65-
}]
62+
patterns: [
63+
{
64+
group: ['**/utils/index.js', '../utils/index.js', '../../utils/index.js', '../../../utils/index.js', '**/utils/index.ts', '../utils/index.ts', '../../utils/index.ts', '../../../utils/index.ts'],
65+
message: 'Barrel imports from utils/index are prohibited. Use focused facade imports instead (e.g., utils/logging/index.ts, utils/execution/index.ts).'
66+
},
67+
{
68+
group: ['./**/*.js', '../**/*.js'],
69+
message: 'Import TypeScript files with .ts extension, not .js. This ensures compatibility with native TypeScript runtimes like Bun and Deno. Change .js to .ts in your import path.'
70+
}
71+
]
6672
}],
6773
},
6874
},

src/core/__tests__/resources.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { describe, it, expect, beforeEach } from 'vitest';
22
import { McpServer } from '@camsoft/mcp-sdk/server/mcp.js';
33

4-
import { registerResources, getAvailableResources, loadResources } from '../resources.js';
4+
import { registerResources, getAvailableResources, loadResources } from '../resources.ts';
55

66
describe('resources', () => {
77
let mockServer: McpServer;

src/core/dynamic-tools.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import { log } from '../utils/logger.js';
2-
import { getDefaultCommandExecutor, CommandExecutor } from '../utils/command.js';
3-
import { WORKFLOW_LOADERS, WorkflowName, WORKFLOW_METADATA } from './generated-plugins.js';
4-
import { ToolResponse } from '../types/common.js';
5-
import { PluginMeta } from './plugin-types.js';
1+
import { log } from '../utils/logger.ts';
2+
import { getDefaultCommandExecutor, CommandExecutor } from '../utils/command.ts';
3+
import { WORKFLOW_LOADERS, WorkflowName, WORKFLOW_METADATA } from './generated-plugins.ts';
4+
import { ToolResponse } from '../types/common.ts';
5+
import { PluginMeta } from './plugin-types.ts';
66
import { McpServer } from '@camsoft/mcp-sdk/server/mcp.js';
77
import {
88
registerAndTrackTools,
99
removeTrackedTools,
1010
isToolRegistered,
11-
} from '../utils/tool-registry.js';
11+
} from '../utils/tool-registry.ts';
1212
import { ZodRawShape } from 'zod';
1313

1414
// Track enabled workflows and their tools for replacement functionality

src/core/plugin-registry.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import type { PluginMeta, WorkflowGroup, WorkflowMeta } from './plugin-types.js';
2-
import { WORKFLOW_LOADERS, WorkflowName, WORKFLOW_METADATA } from './generated-plugins.js';
1+
import type { PluginMeta, WorkflowGroup, WorkflowMeta } from './plugin-types.ts';
2+
import { WORKFLOW_LOADERS, WorkflowName, WORKFLOW_METADATA } from './generated-plugins.ts';
33

44
export async function loadPlugins(): Promise<Map<string, PluginMeta>> {
55
const plugins = new Map<string, PluginMeta>();

src/core/plugin-types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { z } from 'zod';
2-
import { ToolResponse } from '../types/common.js';
2+
import { ToolResponse } from '../types/common.ts';
33

44
export interface PluginMeta {
55
readonly name: string; // Verb used by MCP

src/core/resources.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313

1414
import { McpServer } from '@camsoft/mcp-sdk/server/mcp.js';
1515
import { ReadResourceResult } from '@camsoft/mcp-sdk/types.js';
16-
import { log } from '../utils/logging/index.js';
17-
import type { CommandExecutor } from '../utils/execution/index.js';
18-
import { RESOURCE_LOADERS } from './generated-resources.js';
16+
import { log } from '../utils/logging/index.ts';
17+
import type { CommandExecutor } from '../utils/execution/index.ts';
18+
import { RESOURCE_LOADERS } from './generated-resources.ts';
1919

2020
/**
2121
* Resource metadata interface

src/doctor-cli.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
* to the console. It's designed to be run directly via npx or mise.
88
*/
99

10-
import { version } from './version.js';
11-
import { doctorLogic } from './mcp/tools/doctor/doctor.js';
12-
import { getDefaultCommandExecutor } from './utils/execution/index.js';
10+
import { version } from './version.ts';
11+
import { doctorLogic } from './mcp/tools/doctor/doctor.ts';
12+
import { getDefaultCommandExecutor } from './utils/execution/index.ts';
1313

1414
async function runDoctor(): Promise<void> {
1515
try {

src/index.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,31 @@
1414
*/
1515

1616
// Import Sentry instrumentation
17-
import './utils/sentry.js';
17+
import './utils/sentry.ts';
1818

1919
// Import server components
20-
import { createServer, startServer } from './server/server.js';
20+
import { createServer, startServer } from './server/server.ts';
2121
import { McpServer } from '@camsoft/mcp-sdk/server/mcp.js';
2222

2323
// Import utilities
24-
import { log } from './utils/logger.js';
24+
import { log } from './utils/logger.ts';
2525

2626
// Import version
27-
import { version } from './version.js';
27+
import { version } from './version.ts';
2828

2929
// Import xcodemake utilities
30-
import { isXcodemakeEnabled, isXcodemakeAvailable } from './utils/xcodemake.js';
30+
import { isXcodemakeEnabled, isXcodemakeAvailable } from './utils/xcodemake.ts';
3131

3232
// Import process for stdout configuration
3333
import process from 'node:process';
3434

3535
// Import resource management
36-
import { registerResources } from './core/resources.js';
36+
import { registerResources } from './core/resources.ts';
3737
import {
3838
registerDiscoveryTools,
3939
registerAllToolsStatic,
4040
registerSelectedWorkflows,
41-
} from './utils/tool-registry.js';
41+
} from './utils/tool-registry.ts';
4242

4343
/**
4444
* Main function to start the server

src/mcp/resources/__tests__/devices.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { describe, it, expect } from 'vitest';
22

3-
import devicesResource, { devicesResourceLogic } from '../devices.js';
4-
import { createMockExecutor } from '../../../test-utils/mock-executors.js';
3+
import devicesResource, { devicesResourceLogic } from '../devices.ts';
4+
import { createMockExecutor } from '../../../test-utils/mock-executors.ts';
55

66
describe('devices resource', () => {
77
describe('Export Field Validation', () => {

0 commit comments

Comments
 (0)