From fb3a5966ef9b98a67594f1b4db69af60b795fa30 Mon Sep 17 00:00:00 2001 From: Walter Korman Date: Thu, 14 Nov 2024 18:29:20 -0800 Subject: [PATCH] feat (packages/codemod): Add codemod to rm experimental_StreamData. --- .changeset/lovely-hairs-help.md | 5 ++ .../remove-experimental-streamdata.ts | 65 +++++++++++++++++++ packages/codemod/src/lib/upgrade.ts | 1 + .../remove-experimental-streamdata.input.ts | 23 +++++++ .../remove-experimental-streamdata.output.ts | 23 +++++++ .../remove-experimental-streamdata.test.ts | 9 +++ 6 files changed, 126 insertions(+) create mode 100644 .changeset/lovely-hairs-help.md create mode 100644 packages/codemod/src/codemods/remove-experimental-streamdata.ts create mode 100644 packages/codemod/src/test/__testfixtures__/remove-experimental-streamdata.input.ts create mode 100644 packages/codemod/src/test/__testfixtures__/remove-experimental-streamdata.output.ts create mode 100644 packages/codemod/src/test/remove-experimental-streamdata.test.ts diff --git a/.changeset/lovely-hairs-help.md b/.changeset/lovely-hairs-help.md new file mode 100644 index 000000000000..d8f352e2c05b --- /dev/null +++ b/.changeset/lovely-hairs-help.md @@ -0,0 +1,5 @@ +--- +'@ai-sdk/codemod': patch +--- + +feat (packages/codemod): Add codemod to rm experimental_StreamData. diff --git a/packages/codemod/src/codemods/remove-experimental-streamdata.ts b/packages/codemod/src/codemods/remove-experimental-streamdata.ts new file mode 100644 index 000000000000..188a0bdb45b1 --- /dev/null +++ b/packages/codemod/src/codemods/remove-experimental-streamdata.ts @@ -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(); + + // 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(); +} diff --git a/packages/codemod/src/lib/upgrade.ts b/packages/codemod/src/lib/upgrade.ts index 70b644dbda4b..8ef7c31e3c2c 100644 --- a/packages/codemod/src/lib/upgrade.ts +++ b/packages/codemod/src/lib/upgrade.ts @@ -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', diff --git a/packages/codemod/src/test/__testfixtures__/remove-experimental-streamdata.input.ts b/packages/codemod/src/test/__testfixtures__/remove-experimental-streamdata.input.ts new file mode 100644 index 000000000000..2a5dc4ffda63 --- /dev/null +++ b/packages/codemod/src/test/__testfixtures__/remove-experimental-streamdata.input.ts @@ -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 +} diff --git a/packages/codemod/src/test/__testfixtures__/remove-experimental-streamdata.output.ts b/packages/codemod/src/test/__testfixtures__/remove-experimental-streamdata.output.ts new file mode 100644 index 000000000000..74da2ce87740 --- /dev/null +++ b/packages/codemod/src/test/__testfixtures__/remove-experimental-streamdata.output.ts @@ -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 +} diff --git a/packages/codemod/src/test/remove-experimental-streamdata.test.ts b/packages/codemod/src/test/remove-experimental-streamdata.test.ts new file mode 100644 index 000000000000..44bb3fa032b0 --- /dev/null +++ b/packages/codemod/src/test/remove-experimental-streamdata.test.ts @@ -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'); + }); +});