diff --git a/.gitignore b/.gitignore index 15201ac..869f6d5 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f1260c4..36c3ede 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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. + diff --git a/remove_default_exports/README.md b/remove_default_exports/README.md new file mode 100644 index 0000000..ab0d14c --- /dev/null +++ b/remove_default_exports/README.md @@ -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! \ No newline at end of file diff --git a/remove_default_exports/imput_repo/package.json b/remove_default_exports/imput_repo/package.json new file mode 100644 index 0000000..ce1ed32 --- /dev/null +++ b/remove_default_exports/imput_repo/package.json @@ -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" + } +} diff --git a/remove_default_exports/imput_repo/src/auth/services/authenticator.ts b/remove_default_exports/imput_repo/src/auth/services/authenticator.ts new file mode 100644 index 0000000..d2bb89b --- /dev/null +++ b/remove_default_exports/imput_repo/src/auth/services/authenticator.ts @@ -0,0 +1,6 @@ +// Original file keeps default export +export default class Authenticator { + authenticate(token: string): boolean { + return token.length > 0; + } +} diff --git a/remove_default_exports/imput_repo/src/auth/shared/authenticator.ts b/remove_default_exports/imput_repo/src/auth/shared/authenticator.ts new file mode 100644 index 0000000..97d51b5 --- /dev/null +++ b/remove_default_exports/imput_repo/src/auth/shared/authenticator.ts @@ -0,0 +1,2 @@ +// Should be converted to named export +export { default } from '../services/authenticator'; diff --git a/remove_default_exports/imput_repo/src/auth/shared/token.ts b/remove_default_exports/imput_repo/src/auth/shared/token.ts new file mode 100644 index 0000000..d85974c --- /dev/null +++ b/remove_default_exports/imput_repo/src/auth/shared/token.ts @@ -0,0 +1,2 @@ +// Should be converted to named export +export { default as generateToken } from '../utils/token-generator'; diff --git a/remove_default_exports/imput_repo/src/auth/utils/token-generator.ts b/remove_default_exports/imput_repo/src/auth/utils/token-generator.ts new file mode 100644 index 0000000..deca991 --- /dev/null +++ b/remove_default_exports/imput_repo/src/auth/utils/token-generator.ts @@ -0,0 +1,4 @@ +// Original file keeps default export +export default function generateToken(): string { + return Math.random().toString(36); +} diff --git a/remove_default_exports/imput_repo/src/comments/models/comment.ts b/remove_default_exports/imput_repo/src/comments/models/comment.ts new file mode 100644 index 0000000..b458ff0 --- /dev/null +++ b/remove_default_exports/imput_repo/src/comments/models/comment.ts @@ -0,0 +1,6 @@ +// Original file keeps default export +export default interface Comment { + id: string; + postId: string; + text: string; +} diff --git a/remove_default_exports/imput_repo/src/comments/services/comment-service.ts b/remove_default_exports/imput_repo/src/comments/services/comment-service.ts new file mode 100644 index 0000000..3e795dc --- /dev/null +++ b/remove_default_exports/imput_repo/src/comments/services/comment-service.ts @@ -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!' }; + } +} diff --git a/remove_default_exports/imput_repo/src/comments/shared/service.ts b/remove_default_exports/imput_repo/src/comments/shared/service.ts new file mode 100644 index 0000000..4a3efbc --- /dev/null +++ b/remove_default_exports/imput_repo/src/comments/shared/service.ts @@ -0,0 +1,2 @@ +// Should be converted to named export +export { default as CommentService } from '../services/comment-service'; diff --git a/remove_default_exports/imput_repo/src/comments/shared/types.ts b/remove_default_exports/imput_repo/src/comments/shared/types.ts new file mode 100644 index 0000000..a6847de --- /dev/null +++ b/remove_default_exports/imput_repo/src/comments/shared/types.ts @@ -0,0 +1,2 @@ +// Should be converted to named export +export { default as Comment } from '../models/comment'; diff --git a/remove_default_exports/imput_repo/src/posts/models/post.ts b/remove_default_exports/imput_repo/src/posts/models/post.ts new file mode 100644 index 0000000..7884480 --- /dev/null +++ b/remove_default_exports/imput_repo/src/posts/models/post.ts @@ -0,0 +1,6 @@ +// Original file keeps default export +export default interface Post { + id: string; + title: string; + content: string; +} diff --git a/remove_default_exports/imput_repo/src/posts/services/post-service.ts b/remove_default_exports/imput_repo/src/posts/services/post-service.ts new file mode 100644 index 0000000..71aba25 --- /dev/null +++ b/remove_default_exports/imput_repo/src/posts/services/post-service.ts @@ -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' }; + } +} diff --git a/remove_default_exports/imput_repo/src/posts/shared/service.ts b/remove_default_exports/imput_repo/src/posts/shared/service.ts new file mode 100644 index 0000000..c7c343f --- /dev/null +++ b/remove_default_exports/imput_repo/src/posts/shared/service.ts @@ -0,0 +1,2 @@ +// Should be converted to named export +export { default as PostService } from '../services/post-service'; diff --git a/remove_default_exports/imput_repo/src/posts/shared/types.ts b/remove_default_exports/imput_repo/src/posts/shared/types.ts new file mode 100644 index 0000000..12c432f --- /dev/null +++ b/remove_default_exports/imput_repo/src/posts/shared/types.ts @@ -0,0 +1,2 @@ +// Should be converted to named export +export { default as Post } from '../models/post'; diff --git a/remove_default_exports/imput_repo/src/shared/index.ts b/remove_default_exports/imput_repo/src/shared/index.ts new file mode 100644 index 0000000..99d7dff --- /dev/null +++ b/remove_default_exports/imput_repo/src/shared/index.ts @@ -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'; diff --git a/remove_default_exports/imput_repo/src/users/models/user.ts b/remove_default_exports/imput_repo/src/users/models/user.ts new file mode 100644 index 0000000..c734e40 --- /dev/null +++ b/remove_default_exports/imput_repo/src/users/models/user.ts @@ -0,0 +1,6 @@ +// Original file keeps default export +export default interface User { + id: string; + name: string; + email: string; +} diff --git a/remove_default_exports/imput_repo/src/users/services/user-service.ts b/remove_default_exports/imput_repo/src/users/services/user-service.ts new file mode 100644 index 0000000..d12fb9e --- /dev/null +++ b/remove_default_exports/imput_repo/src/users/services/user-service.ts @@ -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' }; + } +} diff --git a/remove_default_exports/imput_repo/src/users/shared/service.ts b/remove_default_exports/imput_repo/src/users/shared/service.ts new file mode 100644 index 0000000..a55e5f9 --- /dev/null +++ b/remove_default_exports/imput_repo/src/users/shared/service.ts @@ -0,0 +1,2 @@ +// Should be converted to named export +export { default as UserService } from '../services/user-service'; diff --git a/remove_default_exports/imput_repo/src/users/shared/types.ts b/remove_default_exports/imput_repo/src/users/shared/types.ts new file mode 100644 index 0000000..7892940 --- /dev/null +++ b/remove_default_exports/imput_repo/src/users/shared/types.ts @@ -0,0 +1,2 @@ +// Should be converted to named export +export { default as User } from '../models/user'; diff --git a/remove_default_exports/imput_repo/tsconfig.json b/remove_default_exports/imput_repo/tsconfig.json new file mode 100644 index 0000000..df8dd38 --- /dev/null +++ b/remove_default_exports/imput_repo/tsconfig.json @@ -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"] +} diff --git a/remove_default_exports/run.py b/remove_default_exports/run.py new file mode 100644 index 0000000..0744e35 --- /dev/null +++ b/remove_default_exports/run.py @@ -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)