Skip to content

Commit

Permalink
feat (packages/codemod): Add script to scaffold new codemod. (#3648)
Browse files Browse the repository at this point in the history
  • Loading branch information
shaper authored Nov 13, 2024
1 parent cb91fe3 commit 29556ed
Show file tree
Hide file tree
Showing 4 changed files with 284 additions and 152 deletions.
5 changes: 5 additions & 0 deletions .changeset/proud-yaks-taste.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ai-sdk/codemod': patch
---

feat (packages/codemod): Add script to scaffold new codemod.
4 changes: 3 additions & 1 deletion packages/codemod/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"type-check": "tsc --noEmit",
"prettier-check": "prettier --check \"./**/*.ts*\"",
"test": "vitest --config vitest.config.ts --run",
"test:watch": "vitest"
"test:watch": "vitest",
"scaffold": "tsx scripts/scaffold-codemod.ts"
},
"devDependencies": {
"@types/jscodeshift": "^0.12.0",
Expand All @@ -24,6 +25,7 @@
"@vercel/ai-tsconfig": "workspace:*",
"msw": "2.6.4",
"tsup": "^8",
"tsx": "4.7.1",
"typescript": "5.6.3",
"vitest": "2.1.4"
},
Expand Down
85 changes: 85 additions & 0 deletions packages/codemod/scripts/scaffold-codemod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import fs from 'fs';
import path from 'path';

const codemodName = process.argv[2];
if (!codemodName) {
console.error('Please provide a codemod name');
process.exit(1);
}

// Templates
const codemodTemplate = `import { API, FileInfo } from 'jscodeshift';
export default function transformer(file: FileInfo, api: API) {
const j = api.jscodeshift;
const root = j(file.source);
// TODO: Implement transform
return root.toSource();
}
`;

const testTemplate = `import { describe, it } from 'vitest';
import transformer from '../codemods/${codemodName}';
import { testTransform } from './test-utils';
describe('${codemodName}', () => {
it('transforms correctly', () => {
testTransform(transformer, '${codemodName}');
});
});
`;

const inputTemplate = `// @ts-nocheck
// TODO: Add input code
`;

const outputTemplate = `// @ts-nocheck
// TODO: Add expected output code
`;

// File paths
const paths = {
codemod: path.join(process.cwd(), 'src', 'codemods', `${codemodName}.ts`),
test: path.join(process.cwd(), 'src', 'test', `${codemodName}.test.ts`),
fixtures: path.join(process.cwd(), 'src', 'test', '__testfixtures__'),
};

// Create files
fs.writeFileSync(paths.codemod, codemodTemplate);
fs.writeFileSync(paths.test, testTemplate);
fs.writeFileSync(
path.join(paths.fixtures, `${codemodName}.input.ts`),
inputTemplate,
);
fs.writeFileSync(
path.join(paths.fixtures, `${codemodName}.output.ts`),
outputTemplate,
);

// Update bundle array
const upgradePath = path.join(process.cwd(), 'src', 'lib', 'upgrade.ts');
const upgradeContent = fs.readFileSync(upgradePath, 'utf8');

const bundleMatch = upgradeContent.match(/const bundle = \[([\s\S]*?)\];/);
if (bundleMatch) {
const currentBundle = bundleMatch[1]
.split('\n')
.filter(line => line.trim())
.map(line => line.trim().replace(/[',]/g, ''));

const newBundle = [...currentBundle, codemodName]
.sort()
.map(name => ` '${name}',`)
.join('\n');

const newContent = upgradeContent.replace(
/const bundle = \[([\s\S]*?)\];/,
`const bundle = [\n${newBundle}\n];`,
);

fs.writeFileSync(upgradePath, newContent);
}

console.log(`Created codemod files for '${codemodName}'`);
Loading

0 comments on commit 29556ed

Please sign in to comment.