Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,9 @@ cython_debug/

# PyPI configuration file
.pypirc
/.idea/vcs.xml
/.idea/codegen-examples.iml
/.idea/misc.xml
/.idea/modules.xml
/.idea/inspectionProfiles/profiles_settings.xml
/.idea/inspectionProfiles/Project_Default.xml
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ By contributing to Codegen Examples, you agree that:
4. Submit a pull request to the `main` branch.
5. Include a clear description of your changes in the PR.


66 changes: 66 additions & 0 deletions remove_default_exports/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Remove Default Exports in TypeScript

This codemod demonstrates how to automatically convert default exports to named exports in your TypeScript codebase. The migration script makes this process simple by handling all the tedious manual updates automatically.

## How the Migration Script Works

The script automates the entire migration process in a few key steps:

1. **File Detection and Analysis**
```python
codebase = Codebase("./")
for file in codebase.files:
if "/shared/" not in file.filepath:
continue
```
- Automatically identifies shared TypeScript files
- Analyzes export structures
- Determines necessary export modifications

2. **Export Conversion**
```python
for export in file.exports:
if export.is_default_export():
export.make_non_default()
```
- Converts default exports to named exports
- Ensures corresponding non-shared files are updated
- Preserves existing export configurations

## Common Migration Patterns

### Default Export Conversion
```typescript
// Before
export default function myFunction() {}

// After
export function myFunction() {}
```

### Re-export Conversion
```typescript
// Before
export { default } from './module';

// After
export { myFunction } from './module';
```

## Running the Migration

```bash
# Install Codegen
pip install codegen
# Run the migration
python run.py
```

## Learn More

- [TypeScript Documentation](https://www.typescriptlang.org/docs/)
- [Codegen Documentation](https://docs.codegen.com)

## Contributing

Feel free to submit issues and enhancement requests!
15 changes: 15 additions & 0 deletions remove_default_exports/imput_repo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "default-exports-test",
"version": "1.0.0",
"description": "Test codebase for converting default exports",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"typescript": "^5.0.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Original file keeps default export
export default class Authenticator {
authenticate(token: string): boolean {
return token.length > 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Should be converted to named export
export { default } from '../services/authenticator';
2 changes: 2 additions & 0 deletions remove_default_exports/imput_repo/src/auth/shared/token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Should be converted to named export
export { default as generateToken } from '../utils/token-generator';
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Original file keeps default export
export default function generateToken(): string {
return Math.random().toString(36);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Original file keeps default export
export default interface Comment {
id: string;
postId: string;
text: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Original file keeps default export
import Comment from '../models/comment';

export default class CommentService {
getComment(id: string): Comment {
return { id, postId: '123', text: 'Great post!' };
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Should be converted to named export
export { default as CommentService } from '../services/comment-service';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Should be converted to named export
export { default as Comment } from '../models/comment';
6 changes: 6 additions & 0 deletions remove_default_exports/imput_repo/src/posts/models/post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Original file keeps default export
export default interface Post {
id: string;
title: string;
content: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Original file keeps default export
import Post from '../models/post';

export default class PostService {
getPost(id: string): Post {
return { id, title: 'Hello', content: 'World' };
}
}
2 changes: 2 additions & 0 deletions remove_default_exports/imput_repo/src/posts/shared/service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Should be converted to named export
export { default as PostService } from '../services/post-service';
2 changes: 2 additions & 0 deletions remove_default_exports/imput_repo/src/posts/shared/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Should be converted to named export
export { default as Post } from '../models/post';
6 changes: 6 additions & 0 deletions remove_default_exports/imput_repo/src/shared/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// All of these should be converted to named exports
export { default as Auth } from '../auth/services/authenticator';
export { default as Token } from '../auth/utils/token-generator';
export { default as UserModel } from '../users/models/user';
export { default as PostModel } from '../posts/models/post';
export { default as CommentModel } from '../comments/models/comment';
6 changes: 6 additions & 0 deletions remove_default_exports/imput_repo/src/users/models/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Original file keeps default export
export default interface User {
id: string;
name: string;
email: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Original file keeps default export
import User from '../models/user';

export default class UserService {
getUser(id: string): User {
return { id, name: 'John', email: 'john@example.com' };
}
}
2 changes: 2 additions & 0 deletions remove_default_exports/imput_repo/src/users/shared/service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Should be converted to named export
export { default as UserService } from '../services/user-service';
2 changes: 2 additions & 0 deletions remove_default_exports/imput_repo/src/users/shared/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Should be converted to named export
export { default as User } from '../models/user';
18 changes: 18 additions & 0 deletions remove_default_exports/imput_repo/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
},
"include": [
"../../src/**/*"
],
"exclude": ["node_modules"]
}
45 changes: 45 additions & 0 deletions remove_default_exports/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import codegen
from codegen import Codebase
from codegen.sdk.typescript.file import TSFile


@codegen.function("remove-default-exports")
def run(codebase: Codebase):
"""Convert default exports to named exports in TypeScript files.

This script:
1. Identifies shared TypeScript files with default exports.
2. Converts default exports to named exports.
3. Ensures corresponding non-shared files are updated.
"""
for file in codebase.files:
target_file = file.filepath
if not target_file:
print(f"⚠️ Target file not found: {target_file} in codebase")
continue

# Get corresponding non-shared file
non_shared_path = file.filepath.replace("/shared/", "/")
if not codebase.has_file(non_shared_path):
print(f"⚠️ No matching non-shared file for: {non_shared_path}")
continue

non_shared_file = codebase.get_file(non_shared_path)
print(f"📄 Processing {file.filepath}")

# Process individual exports
if isinstance(file, TSFile):
for export in file.exports:
# Handle default exports
if export.is_reexport() and export.is_default_export():
print(f" 🔄 Converting default export '{export.name}'")
default_export = next((e for e in non_shared_file.default_exports), None)
if default_export:
default_export.make_non_default()

print(f"✨ Fixed exports in {file.filepath}")


if __name__ == "__main__":
codebase = Codebase("./")
run(codebase)