diff --git a/docs/building-with-codegen/exports.mdx b/docs/building-with-codegen/exports.mdx
index ee989fea0..3d2286f01 100644
--- a/docs/building-with-codegen/exports.mdx
+++ b/docs/building-with-codegen/exports.mdx
@@ -7,6 +7,8 @@ iconType: "solid"
The [Export](/api-reference/core/Export) API provides tools for managing exports and module boundaries in TypeScript codebases.
+Exports are a TS-only language feature
+
## Export Statements vs Exports
Similar to imports, Codegen provides two levels of abstraction for working with exports:
@@ -30,19 +32,76 @@ export function process() {}
You can access these through your file's collections:
```python
+# Access all exports in the codebase
+for export in codebase.exports:
+ ...
+
# Access all export statements
for stmt in file.export_statements:
- print(f"Statement: {stmt.source}")
-
- # Access individual exports in the statement
for exp in stmt.exports:
- print(f" Export: {exp.name}")
+ ...
```
ExportStatement inherits from [Statement](/building-with-codegen/statements-and-code-blocks), providing operations like `remove()` and `insert_before()`. This is particularly useful when you want to manipulate the entire export declaration.
+## Common Operations
+
+Here are common operations for working with exports:
+
+```python
+# Add exports from source code
+file.add_export_from_source("export { MyComponent };")
+file.add_export_from_source("export type { MyType } from './types';")
+
+# Export existing symbols
+component = file.get_function("MyComponent")
+file.add_export(component) # export { MyComponent }
+file.add_export(component, alias="default") # export { MyComponent as default }
+
+# Convert to type export
+export = file.get_export("MyType")
+export.make_type_export()
+
+# Remove exports
+export = file.get_export("MyComponent")
+export.remove() # Removes export but keeps the symbol
+
+# Remove multiple exports
+for export in file.exports:
+ if not export.is_type_export():
+ export.remove()
+
+# Update export properties
+export.update(
+ name="NewName",
+ is_type=True,
+ is_default=False
+)
+
+# Export from another file
+other_file = codebase.get_file("./components.ts")
+component = other_file.get_class("Button")
+file.add_export(component, from_file=other_file) # export { Button } from './components';
+
+# Analyze symbols being exported
+for export in file.exports:
+ if isinstance(export.exported_symbol, ExternalModule):
+ print('Exporting ExternalModule')
+ else:
+ ...
+```
+
+
+When adding exports, you can:
+- Add from source code with `add_export_from_source()`
+- Export existing symbols with `add_export()`
+- Re-export from other files by specifying `from_file`
+
+The export will automatically handle adding any required imports.
+
+
## Export Types
Codegen supports several types of exports:
@@ -68,9 +127,13 @@ export { foo as default }; // Default export alias
export { bar as baz } from './other-file'; // Re-export with alias
```
-## Working with Exports
+## Identifying Export Types
The Export API provides methods to identify and filter exports:
+- [.is_type_export()](/api-reference/typescript/TSExport#is-type-export)
+- [.is_default_export()](/api-reference/typescript/TSExport#is-default-export)
+- [.is_wildcard_export()](/api-reference/typescript/TSExport#is-wildcard-export)
+
```python
# Check export types
@@ -81,14 +144,6 @@ for exp in file.exports:
print(f"Default export: {exp.name}")
elif exp.is_wildcard_export():
print(f"Wildcard export from: {exp.from_file.filepath}")
-
-# Work with re-exports
-for exp in file.exports:
- if exp.is_reexport():
- if exp.is_external_export:
- print(f"External re-export: {exp.name} from {exp.from_file.filepath}")
- else:
- print(f"Internal re-export: {exp.name}")
```
## Export Resolution
@@ -106,35 +161,9 @@ for exp in file.exports:
print(f"Through: {' -> '.join(e.file.filepath for e in exp.export_chain)}")
```
-## Common Operations
-
-Here are common operations for working with exports:
-
-```python
-# Add new export
-file.add_export("MyComponent")
-
-# Add export with alias
-file.add_export("MyComponent", alias="default")
-
-# Convert to type export
-export = file.get_export("MyType")
-export.make_type_export()
-
-# Remove export
-export.remove() # Removes export but keeps symbol
-
-# Update export properties
-export.update(
- name="NewName",
- is_type=True,
- is_default=False
-)
-```
-
## Managing Re-exports
-Common patterns for working with re-exports:
+You can manage re-exports with the [TSExport.is_reexport()](/api-reference/typescript/TSExport#is-reexport) API:
```python
# Create public API
diff --git a/docs/building-with-codegen/imports-and-exports.mdx b/docs/building-with-codegen/imports-and-exports.mdx
deleted file mode 100644
index 184812221..000000000
--- a/docs/building-with-codegen/imports-and-exports.mdx
+++ /dev/null
@@ -1,384 +0,0 @@
----
-title: "Imports and Exports"
-sidebarTitle: "Imports and Exports"
-icon: "arrow-right-to-bracket"
-iconType: "solid"
----
-
-Codegen provides a rich API for working with imports and exports.
-
-```python
-for imp in file.imports:
- if imp.symbol.name == "UserService":
- imp.remove() # Removes the import
- elif imp.symbol.alias == "math":
- imp.alias.edit("math_lib") # Updates an alias
- elif imp.is_wildcard:
- imp.remove() # Removes a wildcard import
-```
-
-## ImportStatement and ExportStatement
-
-The [ImportStatement](/api-reference/core/ImportStatement) and [ExportStatement](/api-reference/core/ExportStatement) classes represent the actual import and export declarations in your code. As subclasses of the [Statement API](/building-with-codegen/statements-and-code-blocks#statement-types), they handle the full statement-level operations like removal and formatting.
-
-A single statement often contains multiple individual imports or exports - for example, a Python import statement might bring in several functions from a module, or a TypeScript export statement might export multiple symbols at once.
-
-```python
-# ImportStatement example (python)
-import numpy as np # One statement, one import
-from math import sin, cos as cosine # One statement, multiple imports
-
-# ExportStatement example (TypeScript)
-export { foo, bar } # One statement, multiple exports
-export default class {} # One statement, one export
-```
-
-You can access these statements through your file's `import_statements` and `export_statements` collections, then work with the individual imports/exports they contain:
-
-```python
-# Access all imports in a statement
-import_stmt = file.import_statements[0]
-for import_symbol in import_stmt.imports:
- print(f"Found import: {import_symbol.name}")
-
-# Remove an entire import statement
-import_stmt.remove() # Removes all imports in this statement
-
-# Access exports in a statement (TypeScript)
-export_stmt = file.export_statements[0]
-print(f"Statement exports {len(export_stmt.exports)} symbols")
-```
-
-
- ImportStatement and ExportStatement are
- [Statement](/building-with-codegen/statements-and-code-blocks) subclasses, so
- they support all standard statement operations like `remove()`,
- `insert_before()`, etc.
-
-
-## Symbol-level representation
-
-While statements handle the overall structure of imports and exports, the [Import](/api-reference/core/Import) and [Export](/api-reference/core/Export) classes represent the individual symbols being imported or exported.
-
-Each Import or Export instance corresponds to a single symbol, even when multiple symbols are declared in the same statement. These classes handle symbol-specific operations like renaming, type information, and tracking dependencies.
-
-```python
-# One statement containing multiple Import symbols
-from math import sin, cos as cosine
-# Creates:
-# - Import for 'sin'
-# - Import for 'cos' with alias 'cosine'
-
-# TypeScript: One statement with multiple Export symbols
-export { foo as default, bar, type User }
-# Creates:
-# - Export for 'foo' as a default export
-# - Export for 'bar' as a named export
-# - Export for 'User' as a type export
-```
-
-Codegen programs typically interact directly with the [Import](/api-reference/core/Import) and [Export](/api-reference/core/Export) classes, which provide more intuitive APIs.
-
-```python
-# Access individual imports
-for imp in file.imports: # Iterates over all Import symbols
- if imp.is_type_import:
- print(f"Type import: {imp.name}")
- if imp.is_aliased():
- print(f"Original: {imp.symbol_name}, Alias: {imp.name}")
-
-# Work with individual exports (TypeScript)
-for exp in file.exports: # Iterates over all Export symbols
- if exp.is_default_export():
- print(f"Default export: {exp.name}")
- elif exp.is_type_export():
- print(f"Type export: {exp.name}")
-```
-
-
- Import and Export symbols maintain references to their parent statements, but
- can be manipulated independently. When you remove an Import/Export symbol,
- Codegen automatically handles cleaning up the parent statement if it becomes
- empty.
-
-
-## Working with Imports
-
-### Working with External Modules
-
-When working with imports, you often need to distinguish between imports from your project and external packages (like `react` or `lodash`). The [ExternalModule](/api-reference/core/ExternalModule) class helps with this:
-
-```python
-# Check if an import is from an external module
-for imp in file.imports:
- if isinstance(imp.resolved_symbol, ExternalModule):
- print(f"External import: {imp.name} from {imp.module}")
- else:
- print(f"Local import: {imp.name}")
-
-# Skip processing external imports
-for function in codebase.functions:
- for call in function.call_sites:
- if isinstance(call.function_definition, ExternalModule):
- # Skip external function calls (like React.useState)
- continue
- # Process local function calls...
-```
-
-### Common Import Operations
-
-Here are common operations you can perform on imports:
-
-```python
-# Change the module an import comes from
-import_stmt = file.get_import("MyComponent")
-import_stmt.set_module("./new/path") # Updates import path
-
-# Add/update import alias
-import_stmt.set_alias("MyAlias") # import X as MyAlias
-
-# Convert between import styles (TypeScript)
-import_stmt.make_type_import() # Converts to 'import type'
-import_stmt.make_value_import() # Removes 'type' modifier
-
-# Update multiple properties
-import_stmt.update(
- module="./new/path",
- alias="NewAlias",
- is_type=True
-)
-```
-
-### Bulk Import Management
-
-Here's how to perform operations on multiple imports:
-
-```python
-# Update all imports from a specific module
-old_path = "./old/path"
-new_path = "./new/path"
-
-for imp in file.imports:
- if imp.module == old_path:
- imp.set_module(new_path)
-
-# Remove all unused imports
-for imp in file.imports:
- if not imp.usages and not isinstance(imp.resolved_symbol, ExternalModule):
- print(f"Removing unused import: {imp.name}")
- imp.remove()
-
-# Consolidate imports from the same module
-from collections import defaultdict
-
-# Group imports by module
-module_imports = defaultdict(list)
-for imp in file.imports:
- module_imports[imp.module].append(imp)
-
-# Consolidate each group
-for module, imports in module_imports.items():
- if len(imports) > 1:
- # Create new combined import
- symbols = [imp.name for imp in imports]
- file.add_import_from_import_string(
- f"import {{ {', '.join(symbols)} }} from '{module}'"
- )
- # Remove old imports
- for imp in imports:
- imp.remove()
-```
-
-### Import Resolution
-
-You can trace import chains and resolve symbols:
-
-```python
-# Follow import chain to original symbol
-import_stmt = file.get_import("MyComponent")
-original_symbol = import_stmt.resolved_symbol
-
-if original_symbol:
- print(f"Imported from: {original_symbol.file.filepath}")
- print(f"Original name: {original_symbol.name}")
-
-# Check if import is re-exported
-for imp in file.imports:
- if imp.is_reexported:
- print(f"Re-exported symbol: {imp.name}")
- print(f"Through files: {' -> '.join(exp.file.filepath for exp in imp.export_chain)}")
-```
-
-
-When working with imports, always check if they resolve to external modules before modification. This prevents accidentally modifying imports from third-party packages.
-
-
-## Identifying Export Types
-
-Codegen provides several methods to identify and filter different types of exports in your TypeScript code. Here's how to work with various export patterns:
-
-```typescript
-// Direct exports - not re-exports, not aliased, not wildcard
-export const value = 42; // Value export
-export function myFunction() {} // Function export
-export class MyClass {} // Class export
-export type MyType = string; // Type export
-export interface MyInterface {} // Interface export
-export enum MyEnum {} // Enum export
-
-// Type exports (is_type_export() returns True)
-export type MyType = string; // Direct type export
-export interface MyInterface {} // Interface export
-export type { SomeType } from './other'; // Type re-export
-export { type User } from './models'; // Inline type export
-
-// Re-exports (is_reexport() returns True)
-export { foo, bar } from './other-file'; // Named re-exports
-export type { Type } from './other-file'; // Type re-exports
-
-// Aliased exports (is_aliased() returns True)
-export { foo as foop }; // Basic alias
-export { foo as default }; // Default export alias
-export { bar as baz } from './other-file'; // Re-export with alias
-
-// Wildcard exports (is_wildcard_export() returns True)
-export * from './other-file'; // Re-export all
-export * as utils from './other-file'; // Namespace re-export
-
-// External exports (is_external_export returns True)
-export { default as React } from 'react'; // External package re-export
-export { useState, useEffect } from 'react'; // Multiple external re-exports
-export type { ReactNode } from 'react'; // External type re-export
-export * from 'lodash'; // External wildcard re-export
-```
-
-You can combine these methods to precisely filter the exports you want to work with:
-
-```python
-# Find all type exports (including interfaces)
-for exp in file.exports:
- if exp.is_type_export():
- if exp.is_reexport():
- print(f"Re-exported type: {exp.name} from {exp.from_file.filepath}")
- else:
- print(f"Local type: {exp.name}")
-
-# Distinguish between type and value exports
-for exp in file.exports:
- if exp.is_type_export():
- print(f"Type export: {exp.name}")
- else:
- print(f"Value export: {exp.name}")
-
-# Find type re-exports
-for exp in file.exports:
- if exp.is_type_export() and exp.is_reexport():
- print(f"Type re-export: {exp.name}")
- if exp.is_aliased():
- print(f" Aliased as: {exp.resolved_symbol.name} -> {exp.name}")
-
-# Find all non-aliased re-exports
-for exp in file.exports:
- if exp.is_reexport() and not exp.is_aliased():
- print(f"Found non-aliased re-export: {exp.name}")
-
-# Distinguish between internal and external re-exports
-for exp in file.exports:
- if exp.is_reexport():
- if exp.is_external_export:
- print(f"External re-export from package: {exp.from_file.filepath}")
- else:
- print(f"Internal re-export from: {exp.from_file.filepath}")
-
-# Work with different types of re-exports
-for exp in file.exports:
- if exp.is_reexport():
- if exp.is_wildcard_export():
- source = "external package" if exp.is_external_export else "local module"
- print(f"Wildcard re-export from {source}: {exp.from_file.filepath}")
- elif exp.is_aliased():
- print(f"Aliased re-export: {exp.resolved_symbol.name} as {exp.name}")
- else:
- print(f"Named re-export: {exp.name}")
-
-# Track symbol resolution through re-exports
-for exp in file.exports:
- if exp.is_reexport():
- # The symbol in the current file
- current_symbol = exp.exported_symbol
- # The original symbol being re-exported
- original_symbol = exp.resolved_symbol
- print(f"Re-exporting {original_symbol.name} from {exp.from_file.filepath}")
-```
-
-
-These methods can be combined with other export features:
-- Type exports (`is_type_export()`)
-- Default exports (`is_default_export()`)
-- Symbol resolution (`resolved_symbol`, `exported_symbol`)
-- File paths (`from_file`, `to_file`)
-
-
-Common use cases include:
-- Creating clean public APIs by re-exporting internal modules
-- Renaming symbols to provide better public interfaces
-- Aggregating exports from multiple files into index files
-- Building layered exports (e.g., through multiple index files)
-- Converting between different export styles (e.g., default to named exports)
-
-
-## Operating on Imports and Exports
-
-### `from_file` and `to_file`
-
-The [from_file](/api-reference/core/Import#from-file) and [to_file](/api-reference/core/Import#to-file) properties on Import and Export symbols enable analysis and manipulation of the import graph.
-
-```python
-# Access the file that contains the symbol
-imp = file.imports[0]
-if imp.from_file.filepath.startswith('tests/'):
- print('File is importing from tests')
-
-# Find imports between A and B directories
-for imp in codebase.imports:
- if imp.from_file.filepath.startswith('A/') and imp.to_file.filepath.startswith('B/'):
- print(f'Importing {imp.name} from {imp.from_file.filepath} to {imp.to_file.filepath}')
-```
-
-### Adding Imports/Exports
-
-There are several ways to add imports to a file:
-
-```python
-# Add import for a specific symbol
-symbol = file.get_function("foo")
-file.add_symbol_import(
- symbol, # The symbol to import
- alias="bar", # Optional alias for the import
-)
-
-# Add import from a string representation
-file.add_import_from_import_string(
- "from module import symbol" # Python
- # or "import { symbol } from 'module'" # TypeScript
-)
-
-# Add symbol with its imports
-file.add_symbol(
- symbol, # The symbol to add
- should_export=True # Whether to export the added symbol
-)
-```
-
-### Removing Imports and Exports
-
-Removing individual imports and exports is straightforward:
-
-```python
-# Remove an import
-file.get_import("UserService").remove()
-
-# Remove an export
-file.get_export("UserService").remove()
-```
-