{"version":3,"file":"storage-list-threads-by-resource-to-list-threads.mjs","names":[],"sources":["../../../src/codemods/v1/storage-list-threads-by-resource-to-list-threads.ts"],"sourcesContent":["import type { API, FileInfo, Options } from 'jscodeshift';\nimport { createTransformer } from '../lib/create-transformer';\nimport { trackClassInstances } from '../lib/utils';\n\n/**\n * Migrates from listThreadsByResourceId() to listThreads() with filter wrapping.\n * Only transforms calls on tracked Memory instances to avoid false positives.\n *\n * Before:\n * await memory.listThreadsByResourceId({\n *   resourceId: 'user-123',\n *   page: 0,\n *   perPage: 10\n * });\n *\n * After:\n * await memory.listThreads({\n *   filter: { resourceId: 'user-123' },\n *   page: 0,\n *   perPage: 10\n * });\n */\nexport default createTransformer((fileInfo: FileInfo, api: API, options: Options, context) => {\n  const { j, root } = context;\n\n  // Track Memory class instances (including aliased imports like `import { Memory as AliasedMemory }`)\n  const memoryInstances = trackClassInstances(j, root, 'Memory', '@mastra/memory');\n\n  // Also track variables assigned from methods that might return memory stores\n  // e.g., const memoryStore = await storage.getStore('memory');\n  const potentialMemoryStores = new Set<string>();\n\n  root.find(j.VariableDeclarator).forEach(path => {\n    if (path.value.id.type === 'Identifier') {\n      const varName = path.value.id.name;\n      const init = path.value.init;\n\n      // Track variables with 'memory' or 'memoryStore' in the name as likely Memory instances\n      if (varName.toLowerCase().includes('memory')) {\n        // But NOT if it's an object literal (which would be our negative test case)\n        if (init?.type !== 'ObjectExpression') {\n          potentialMemoryStores.add(varName);\n        }\n      }\n    }\n  });\n\n  // Combine both sets\n  const allMemoryInstances = new Set([...memoryInstances, ...potentialMemoryStores]);\n\n  // Early return if no instances found\n  if (allMemoryInstances.size === 0) {\n    return;\n  }\n\n  let changeCount = 0;\n\n  // Find and transform listThreadsByResourceId() calls on tracked instances\n  root\n    .find(j.CallExpression, {\n      callee: {\n        type: 'MemberExpression',\n        property: {\n          type: 'Identifier',\n          name: 'listThreadsByResourceId',\n        },\n      },\n    })\n    .forEach(path => {\n      const { callee } = path.value;\n      if (callee.type !== 'MemberExpression') return;\n      if (callee.object.type !== 'Identifier') return;\n\n      // Only process if called on a tracked instance\n      if (!allMemoryInstances.has(callee.object.name)) return;\n\n      const args = path.value.arguments;\n      if (args.length !== 1 || args[0]?.type !== 'ObjectExpression') {\n        return;\n      }\n\n      const objArg = args[0];\n      const properties = objArg.properties;\n\n      // Find the resourceId property\n      let resourceIdProp: any = null;\n      const otherProps: any[] = [];\n\n      properties.forEach((prop: any) => {\n        if (\n          (prop.type === 'ObjectProperty' || prop.type === 'Property') &&\n          prop.key?.type === 'Identifier' &&\n          prop.key.name === 'resourceId'\n        ) {\n          resourceIdProp = prop;\n        } else {\n          otherProps.push(prop);\n        }\n      });\n\n      if (!resourceIdProp || !resourceIdProp.value) {\n        return;\n      }\n\n      // Create the new filter object\n      const filterProp = j.property(\n        'init',\n        j.identifier('filter'),\n        j.objectExpression([j.property('init', j.identifier('resourceId'), resourceIdProp.value as any)]),\n      );\n\n      // Update the method name\n      if (path.value.callee.type === 'MemberExpression' && path.value.callee.property.type === 'Identifier') {\n        path.value.callee.property.name = 'listThreads';\n      }\n\n      // Update the arguments with filter first, then other props\n      path.value.arguments = [j.objectExpression([filterProp, ...otherProps])];\n\n      changeCount++;\n    });\n\n  if (changeCount > 0) {\n    context.hasChanges = true;\n    context.messages.push(\n      `Migrated ${changeCount} listThreadsByResourceId call(s) to listThreads with filter wrapping`,\n    );\n  }\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAsBA,IAAA,2DAAe,mBAAmB,UAAoB,KAAU,SAAkB,YAAY;CAC5F,MAAM,EAAE,GAAG,SAAS;CAGpB,MAAM,kBAAkB,oBAAoB,GAAG,MAAM,UAAU,gBAAgB;CAI/E,MAAM,wCAAwB,IAAI,IAAY;CAE9C,KAAK,KAAK,EAAE,kBAAkB,CAAC,CAAC,SAAQ,SAAQ;EAC9C,IAAI,KAAK,MAAM,GAAG,SAAS,cAAc;GACvC,MAAM,UAAU,KAAK,MAAM,GAAG;GAC9B,MAAM,OAAO,KAAK,MAAM;GAGxB,IAAI,QAAQ,YAAY,CAAC,CAAC,SAAS,QAAQ,GAErC;QAAA,MAAM,SAAS,oBACjB,sBAAsB,IAAI,OAAO;GAAA;EAGvC;CACF,CAAC;CAGD,MAAM,qCAAqB,IAAI,IAAI,CAAC,GAAG,iBAAiB,GAAG,qBAAqB,CAAC;CAGjF,IAAI,mBAAmB,SAAS,GAC9B;CAGF,IAAI,cAAc;CAGlB,KACG,KAAK,EAAE,gBAAgB,EACtB,QAAQ;EACN,MAAM;EACN,UAAU;GACR,MAAM;GACN,MAAM;EACR;CACF,EACF,CAAC,CAAC,CACD,SAAQ,SAAQ;EACf,MAAM,EAAE,WAAW,KAAK;EACxB,IAAI,OAAO,SAAS,oBAAoB;EACxC,IAAI,OAAO,OAAO,SAAS,cAAc;EAGzC,IAAI,CAAC,mBAAmB,IAAI,OAAO,OAAO,IAAI,GAAG;EAEjD,MAAM,OAAO,KAAK,MAAM;EACxB,IAAI,KAAK,WAAW,KAAK,KAAK,EAAE,EAAE,SAAS,oBACzC;EAIF,MAAM,aADS,KAAK,EACK,CAAC;EAG1B,IAAI,iBAAsB;EAC1B,MAAM,aAAoB,CAAC;EAE3B,WAAW,SAAS,SAAc;GAChC,KACG,KAAK,SAAS,oBAAoB,KAAK,SAAS,eACjD,KAAK,KAAK,SAAS,gBACnB,KAAK,IAAI,SAAS,cAElB,iBAAiB;QAEjB,WAAW,KAAK,IAAI;EAExB,CAAC;EAED,IAAI,CAAC,kBAAkB,CAAC,eAAe,OACrC;EAIF,MAAM,aAAa,EAAE,SACnB,QACA,EAAE,WAAW,QAAQ,GACrB,EAAE,iBAAiB,CAAC,EAAE,SAAS,QAAQ,EAAE,WAAW,YAAY,GAAG,eAAe,KAAY,CAAC,CAAC,CAClG;EAGA,IAAI,KAAK,MAAM,OAAO,SAAS,sBAAsB,KAAK,MAAM,OAAO,SAAS,SAAS,cACvF,KAAK,MAAM,OAAO,SAAS,OAAO;EAIpC,KAAK,MAAM,YAAY,CAAC,EAAE,iBAAiB,CAAC,YAAY,GAAG,UAAU,CAAC,CAAC;EAEvE;CACF,CAAC;CAEH,IAAI,cAAc,GAAG;EACnB,QAAQ,aAAa;EACrB,QAAQ,SAAS,KACf,YAAY,YAAY,qEAC1B;CACF;AACF,CAAC"}