diff --git a/packages/entity-codemod/src/transforms/__testfixtures__/v0.55.0-v0.56.0/test1.output.ts b/packages/entity-codemod/src/transforms/__testfixtures__/v0.55.0-v0.56.0/test1.output.ts index e88c54a50..c16f3d612 100644 --- a/packages/entity-codemod/src/transforms/__testfixtures__/v0.55.0-v0.56.0/test1.output.ts +++ b/packages/entity-codemod/src/transforms/__testfixtures__/v0.55.0-v0.56.0/test1.output.ts @@ -2,12 +2,10 @@ import { ViewerContext } from '@expo/entity'; import { UserEntity } from './entities/UserEntity'; import { PostEntity } from './entities/PostEntity'; -import { knexLoader, knexLoaderWithAuthorizationResults } from "@expo/entity-database-adapter-knex"; - async function loadUser(viewerContext: ViewerContext) { // Basic loader calls - only transformed when using knex-specific methods const userLoader = UserEntity.loader(viewerContext); - const postLoader = knexLoader(PostEntity, viewerContext); + const postLoader = PostEntity.knexLoader(viewerContext); // These use knex-specific methods, so they should be transformed const posts = await postLoader.loadManyByFieldEqualityConjunctionAsync([ @@ -18,7 +16,7 @@ async function loadUser(viewerContext: ViewerContext) { ]); // Loader with authorization results - only transformed when using knex methods - const userLoaderWithAuth = knexLoaderWithAuthorizationResults(UserEntity, viewerContext); + const userLoaderWithAuth = UserEntity.knexLoaderWithAuthorizationResults(viewerContext); const rawResults = await userLoaderWithAuth.loadManyByRawWhereClauseAsync('age > ?', [18]); // Loader that doesn't use knex methods - should NOT be transformed diff --git a/packages/entity-codemod/src/transforms/__testfixtures__/v0.55.0-v0.56.0/test2.output.ts b/packages/entity-codemod/src/transforms/__testfixtures__/v0.55.0-v0.56.0/test2.output.ts index 31dbd5523..4c61115d1 100644 --- a/packages/entity-codemod/src/transforms/__testfixtures__/v0.55.0-v0.56.0/test2.output.ts +++ b/packages/entity-codemod/src/transforms/__testfixtures__/v0.55.0-v0.56.0/test2.output.ts @@ -1,12 +1,10 @@ import { ViewerContext } from '@expo/entity'; import { CommentEntity } from './entities/CommentEntity'; -import { knexLoader, knexLoaderWithAuthorizationResults } from "@expo/entity-database-adapter-knex"; - // Chained calls const loadComments = async (viewerContext: ViewerContext) => { // Direct chaining with knex-specific method - const comments = await knexLoader(CommentEntity, viewerContext) + const comments = await CommentEntity.knexLoader(viewerContext) .loadManyByFieldEqualityConjunctionAsync([ { fieldName: 'postId', fieldValue: '123' } ]); @@ -17,7 +15,8 @@ const loadComments = async (viewerContext: ViewerContext) => { .loadByIDAsync('456'); // With authorization results and knex method - const commentsWithAuth = await knexLoaderWithAuthorizationResults(CommentEntity, viewerContext) + const commentsWithAuth = await CommentEntity + .knexLoaderWithAuthorizationResults(viewerContext) .loadManyByRawWhereClauseAsync('postId = ?', ['456']); // Edge cases - these should NOT be transformed diff --git a/packages/entity-codemod/src/transforms/v0.55.0-v0.56.0.ts b/packages/entity-codemod/src/transforms/v0.55.0-v0.56.0.ts index 3e65e6480..92bf3f8cf 100644 --- a/packages/entity-codemod/src/transforms/v0.55.0-v0.56.0.ts +++ b/packages/entity-codemod/src/transforms/v0.55.0-v0.56.0.ts @@ -79,9 +79,7 @@ function isKnexSpecificMethodUsed(j: API['jscodeshift'], node: any): boolean { return false; } -function transformLoaderToKnexLoader(j: API['jscodeshift'], root: Collection): boolean { - let transformed = false; - +function transformLoaderToKnexLoader(j: API['jscodeshift'], root: Collection): void { // Find all entity expressions of the form `Entity.loader(viewerContext)` root .find(j.CallExpression, { @@ -107,28 +105,20 @@ function transformLoaderToKnexLoader(j: API['jscodeshift'], root: Collection, -): boolean { - let transformed = false; - +): void { // Find all entity expressions of the form `Entity.loaderWithAuthorizationResults(viewerContext)` root .find(j.CallExpression, { @@ -154,88 +144,22 @@ function transformLoaderWithAuthorizationResultsToKnexLoaderWithAuthorizationRes if (firstChar === firstChar?.toUpperCase()) { // Check if this loader uses knex-specific methods if (isKnexSpecificMethodUsed(j, path)) { - // Transform Entity.loaderWithAuthorizationResults(viewerContext) → knexLoaderWithAuthorizationResults(Entity, viewerContext) - const entityIdentifier = loaderCallee.object; - const args = loaderCallExpression.arguments; - - j(path).replaceWith( - j.callExpression(j.identifier('knexLoaderWithAuthorizationResults'), [ - entityIdentifier, - ...args, - ]), - ); - transformed = true; + // Rename loaderWithAuthorizationResults to knexLoaderWithAuthorizationResults + if (loaderCallee.property.type === 'Identifier') { + loaderCallee.property.name = 'knexLoaderWithAuthorizationResults'; + } } } } }); - - return transformed; -} - -function addKnexImportIfNeeded( - j: API['jscodeshift'], - root: Collection, - needsKnexLoader: boolean, - needsKnexLoaderWithAuthorizationResults: boolean, -): void { - if (!needsKnexLoader && !needsKnexLoaderWithAuthorizationResults) { - return; - } - - const specifiers: string[] = []; - if (needsKnexLoader) { - specifiers.push('knexLoader'); - } - if (needsKnexLoaderWithAuthorizationResults) { - specifiers.push('knexLoaderWithAuthorizationResults'); - } - - // Check if the import already exists - const existingImport = root.find(j.ImportDeclaration, { - source: { value: '@expo/entity-database-adapter-knex' }, - }); - - if (existingImport.size() > 0) { - // Add specifiers to existing import - const importDecl = existingImport.get(); - const existingSpecifierNames = new Set( - importDecl.node.specifiers?.map((s: any) => s.imported?.name).filter(Boolean) ?? [], - ); - - for (const specifier of specifiers) { - if (!existingSpecifierNames.has(specifier)) { - importDecl.node.specifiers?.push(j.importSpecifier(j.identifier(specifier))); - } - } - } else { - // Create new import declaration - const importSpecifiers = specifiers.map((s) => j.importSpecifier(j.identifier(s))); - const importDecl = j.importDeclaration( - importSpecifiers, - j.literal('@expo/entity-database-adapter-knex'), - ); - - // Add after the last import - const allImports = root.find(j.ImportDeclaration); - if (allImports.size() > 0) { - allImports.at(-1).insertAfter(importDecl); - } else { - // No imports, add at the top - root.get().node.program.body.unshift(importDecl); - } - } } export default function transformer(file: FileInfo, api: API, _options: Options): string { const j = api.jscodeshift; const root = j.withParser('ts')(file.source); - const needsKnexLoader = transformLoaderToKnexLoader(j, root); - const needsKnexLoaderWithAuthorizationResults = - transformLoaderWithAuthorizationResultsToKnexLoaderWithAuthorizationResults(j, root); - - addKnexImportIfNeeded(j, root, needsKnexLoader, needsKnexLoaderWithAuthorizationResults); + transformLoaderToKnexLoader(j, root); + transformLoaderWithAuthorizationResultsToKnexLoaderWithAuthorizationResults(j, root); return root.toSource(); }