Skip to content

Commit

Permalink
feat (packages/codemod): Add codemod to rm experimental_StreamData.
Browse files Browse the repository at this point in the history
  • Loading branch information
shaper committed Nov 15, 2024
1 parent 7c205ba commit fb3a596
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/lovely-hairs-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@ai-sdk/codemod': patch
---

feat (packages/codemod): Add codemod to rm experimental_StreamData.
65 changes: 65 additions & 0 deletions packages/codemod/src/codemods/remove-experimental-streamdata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { API, FileInfo } from 'jscodeshift';

export default function transformer(file: FileInfo, api: API) {
const j = api.jscodeshift;
const root = j(file.source);

// Track imports from 'ai' package only
const targetImports = new Set<string>();

// First pass - collect imports from 'ai' package
root
.find(j.ImportDeclaration)
.filter(path => path.node.source.value === 'ai')
.forEach(path => {
path.node.specifiers?.forEach(spec => {
if (
spec.type === 'ImportSpecifier' &&
spec.imported.type === 'Identifier' &&
spec.imported.name === 'experimental_StreamData'
) {
// Track local name
targetImports.add(spec.local?.name || 'experimental_StreamData');
}
});
});

// Second pass - replace imports from 'ai' package only
root
.find(j.ImportDeclaration)
.filter(path => path.node.source.value === 'ai')
.forEach(path => {
const newSpecifiers = path.node.specifiers?.map(spec => {
if (
spec.type === 'ImportSpecifier' &&
spec.imported.type === 'Identifier' &&
spec.imported.name === 'experimental_StreamData'
) {
return j.importSpecifier(
j.identifier('StreamData'),
spec.local?.name === 'experimental_StreamData' ? null : spec.local,
);
}
return spec;
});
path.node.specifiers = newSpecifiers;
});

// Replace type/class references only for tracked imports
root
.find(j.Identifier)
.filter(path => {
// Only replace if:
// 1. It's one of our tracked imports from 'ai'
// 2. It's not part of an import declaration (to avoid replacing other imports)
return (
targetImports.has(path.node.name) &&
!j(path).closest(j.ImportDeclaration).size()
);
})
.forEach(path => {
path.node.name = 'StreamData';
});

return root.toSource();
}
1 change: 1 addition & 0 deletions packages/codemod/src/lib/upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const bundle = [
'remove-deprecated-provider-registry-exports',
'remove-experimental-ai-fn-exports',
'remove-experimental-message-types',
'remove-experimental-streamdata',
'remove-experimental-tool',
'remove-google-facade',
'remove-metadata-with-headers',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// @ts-nocheck
import { experimental_StreamData } from 'ai';
import { experimental_StreamData as StreamDataLegacy } from 'other-pkg';

// Should rename - class extension
class CustomStream extends experimental_StreamData {
// Custom implementation
}

// Should rename - type usage
const createStream = (): experimental_StreamData => {
return new experimental_StreamData();
};

// Should rename - instance check
const isStreamData = (obj: unknown): obj is experimental_StreamData => {
return obj instanceof experimental_StreamData;
};

// Should NOT rename - different package
class OtherStream extends StreamDataLegacy {
// Custom implementation
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// @ts-nocheck
import { StreamData } from 'ai';
import { experimental_StreamData as StreamDataLegacy } from 'other-pkg';

// Should rename - class extension
class CustomStream extends StreamData {
// Custom implementation
}

// Should rename - type usage
const createStream = (): StreamData => {
return new StreamData();
};

// Should rename - instance check
const isStreamData = (obj: unknown): obj is StreamData => {
return obj instanceof StreamData;
};

// Should NOT rename - different package
class OtherStream extends StreamDataLegacy {
// Custom implementation
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { describe, it } from 'vitest';
import transformer from '../codemods/remove-experimental-streamdata';
import { testTransform } from './test-utils';

describe('remove-experimental-streamdata', () => {
it('transforms correctly', () => {
testTransform(transformer, 'remove-experimental-streamdata');
});
});

0 comments on commit fb3a596

Please sign in to comment.