-
Notifications
You must be signed in to change notification settings - Fork 171
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(typescript): Fix ESM output (#5554)
Fix ESM output
- Loading branch information
1 parent
65113d2
commit a4d83bf
Showing
10,070 changed files
with
40,050 additions
and
49,773 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
0.46.0 | ||
0.46.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
generators/typescript/utils/commons/src/scripts/RenameToEsmFilesFile.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import fs from "fs/promises"; | ||
import path from "path"; | ||
|
||
import { ScriptFile } from "./ScriptFile"; | ||
|
||
const fileName = "rename-to-esm-files.js"; | ||
const filePathOnDockerContainer = `/assets/scripts/${fileName}`; | ||
export const renameToEsmFilesFile: ScriptFile = { | ||
copyToFolder: async (destinationFolder: string): Promise<void> => { | ||
await fs.copyFile(filePathOnDockerContainer, path.join(destinationFolder, fileName)); | ||
} | ||
} as const; |
3 changes: 3 additions & 0 deletions
3
generators/typescript/utils/commons/src/scripts/ScriptFile.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export type ScriptFile = { | ||
copyToFolder: (destinationFolder: string) => Promise<void>; | ||
}; |
15 changes: 15 additions & 0 deletions
15
generators/typescript/utils/commons/src/scripts/ScriptsManager.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import fs from "fs/promises"; | ||
import path from "path"; | ||
|
||
import { AbsoluteFilePath } from "@fern-api/fs-utils"; | ||
|
||
import { renameToEsmFilesFile } from "./RenameToEsmFilesFile"; | ||
|
||
export class ScriptsManager { | ||
public async copyScripts({ pathToRoot }: { pathToRoot: AbsoluteFilePath }): Promise<void> { | ||
// make sure the scripts directory exists | ||
const scriptsDir = path.join(pathToRoot, "scripts"); | ||
await fs.mkdir(scriptsDir, { recursive: true }); | ||
await renameToEsmFilesFile.copyToFolder(scriptsDir); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./ScriptsManager"; |
1 change: 1 addition & 0 deletions
1
generators/typescript/utils/commons/src/typescript-project/PersistedTypescriptProject.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
generators/typescript/utils/commons/src/typescript-project/fixImportsForEsm.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { Project } from "ts-morph"; | ||
|
||
import { AbsoluteFilePath, RelativeFilePath, join } from "@fern-api/fs-utils"; | ||
|
||
export async function fixImportsForEsm(pathToProject: AbsoluteFilePath): Promise<void> { | ||
const project = new Project({ | ||
tsConfigFilePath: join(pathToProject, RelativeFilePath.of("tsconfig.json")) | ||
}); | ||
const typeChecker = project.getTypeChecker(); | ||
project.getSourceFiles().forEach((sourceFile) => { | ||
// Get all imports in the file | ||
const imports = sourceFile.getImportDeclarations(); | ||
const exports = sourceFile.getExportDeclarations(); | ||
|
||
[...imports, ...exports].forEach((importDecl) => { | ||
const moduleSpecifier = importDecl.getModuleSpecifierValue(); | ||
|
||
if (!moduleSpecifier) { | ||
return; | ||
} | ||
|
||
// Skip if it's not a relative import or already has .js extension | ||
if (!moduleSpecifier.startsWith(".") || moduleSpecifier.endsWith(".js")) { | ||
return; | ||
} | ||
|
||
// Get the referenced file path by using the TypeChecker | ||
const importModuleSpecifier = importDecl.getModuleSpecifier(); | ||
if (importModuleSpecifier == null) { | ||
return; | ||
} | ||
const symbol = typeChecker.getSymbolAtLocation(importModuleSpecifier); | ||
|
||
const symbolSourceFile = symbol?.getValueDeclaration()?.getSourceFile(); | ||
if (symbolSourceFile) { | ||
const filePath = symbolSourceFile.getFilePath(); | ||
let newSpecifier = moduleSpecifier; | ||
|
||
// Case 1: Directory import resolving to an index file | ||
if ( | ||
(filePath.endsWith("index.ts") || filePath.endsWith("index.js")) && | ||
!moduleSpecifier.endsWith("index") && | ||
!moduleSpecifier.endsWith(".ts") && | ||
!moduleSpecifier.endsWith(".js") | ||
) { | ||
newSpecifier = `${moduleSpecifier}/index.js`; | ||
} | ||
// Case 2: Regular .ts file import | ||
else if (filePath.endsWith(".ts") && !moduleSpecifier.endsWith(".ts")) { | ||
newSpecifier = `${moduleSpecifier}.js`; | ||
} | ||
// Case 3: Import with explicit .ts extension | ||
else if (moduleSpecifier.endsWith(".ts")) { | ||
newSpecifier = moduleSpecifier.replace(/\.ts$/, ".js"); | ||
} | ||
|
||
if (newSpecifier !== moduleSpecifier) { | ||
importDecl.setModuleSpecifier(newSpecifier); | ||
} | ||
} | ||
}); | ||
}); | ||
await project.save(); | ||
} |
119 changes: 119 additions & 0 deletions
119
generators/typescript/utils/scripts/rename-to-esm-files.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
#!/usr/bin/env node | ||
|
||
const fs = require('fs').promises; | ||
const path = require('path'); | ||
|
||
const extensionMap = { | ||
'.js': '.mjs', | ||
'.d.ts': '.d.mts' | ||
}; | ||
const oldExtensions = Object.keys(extensionMap); | ||
|
||
async function findFiles(rootPath) { | ||
const files = []; | ||
|
||
async function scan(directory) { | ||
const entries = await fs.readdir(directory, { withFileTypes: true }); | ||
|
||
for (const entry of entries) { | ||
const fullPath = path.join(directory, entry.name); | ||
|
||
if (entry.isDirectory()) { | ||
if (entry.name !== 'node_modules' && !entry.name.startsWith('.')) { | ||
await scan(fullPath); | ||
} | ||
} else if (entry.isFile()) { | ||
if (oldExtensions.some(ext => entry.name.endsWith(ext))) { | ||
files.push(fullPath); | ||
} | ||
} | ||
} | ||
} | ||
|
||
await scan(rootPath); | ||
return files; | ||
} | ||
|
||
async function updateFiles(files) { | ||
const updatedFiles = []; | ||
for (const file of files) { | ||
const updated = await updateFileContents(file); | ||
updatedFiles.push(updated); | ||
} | ||
|
||
console.log(`Updated imports in ${updatedFiles.length} files.`); | ||
} | ||
|
||
async function updateFileContents(file) { | ||
const content = await fs.readFile(file, 'utf8'); | ||
|
||
let newContent = content; | ||
// Update each extension type defined in the map | ||
for (const [oldExt, newExt] of Object.entries(extensionMap)) { | ||
const regex = new RegExp( | ||
`(import|export)(.+from\\s+['"])(\\.\\.?\\/[^'"]+)(\\${oldExt})(['"])`, | ||
'g' | ||
); | ||
newContent = newContent.replace(regex, `$1$2$3${newExt}$5`); | ||
} | ||
|
||
if (content !== newContent) { | ||
await fs.writeFile(file, newContent, 'utf8'); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
async function renameFiles(files) { | ||
let counter = 0; | ||
for (const file of files) { | ||
const ext = oldExtensions.find(ext => file.endsWith(ext)); | ||
const newExt = extensionMap[ext]; | ||
|
||
if (newExt) { | ||
const newPath = file.slice(0, -ext.length) + newExt; | ||
await fs.rename(file, newPath); | ||
counter++; | ||
} | ||
} | ||
|
||
console.log(`Renamed ${counter} files.`); | ||
} | ||
|
||
async function main() { | ||
try { | ||
const targetDir = process.argv[2]; | ||
if (!targetDir) { | ||
console.error('Please provide a target directory'); | ||
process.exit(1); | ||
} | ||
|
||
const targetPath = path.resolve(targetDir); | ||
const targetStats = await fs.stat(targetPath); | ||
|
||
if (!targetStats.isDirectory()) { | ||
console.error('The provided path is not a directory'); | ||
process.exit(1); | ||
} | ||
|
||
console.log(`Scanning directory: ${targetDir}`); | ||
|
||
const files = await findFiles(targetDir); | ||
|
||
if (files.length === 0) { | ||
console.log('No matching files found.'); | ||
process.exit(0); | ||
} | ||
|
||
console.log(`Found ${files.length} files.`); | ||
await updateFiles(files); | ||
await renameFiles(files); | ||
console.log('\nDone!'); | ||
|
||
} catch (error) { | ||
console.error('An error occurred:', error.message); | ||
process.exit(1); | ||
} | ||
} | ||
|
||
main(); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.