sst / ion

❍ — a new engine for SST
https://ion.sst.dev
MIT License
1.04k stars 114 forks source link

Linking not working in CommonJS functions #433

Open felipemotarocha opened 1 month ago

felipemotarocha commented 1 month ago

I have the following code:

const creditAnalysisSentTopic = new sst.aws.SnsTopic('CreditAnalysisSent')
const admissionJourneyEventCreatedTopic = new sst.aws.SnsTopic('AdmissionJourneyEventCreated')

creditAnalysisSentTopic.subscribe({
    handler: 'infra/topics/credit-analysis-sent/subscriber.handler',
    nodejs: {
      esbuild: {
        external: ['@prisma/client', 'prisma'],
      },
      format: 'cjs',
    },
    link: [admissionJourneyEventCreatedTopic],
    layers: [prismaLayer.arn],
    environment,
  })

This handler tries to write a message on the admissionJourneyEventCreatedTopic but a error is being thrown, even though the topic is linked:

  Error       
|  "AdmissionJourneyEventCreated" is not linked
|  ↳ at Object.get (/Users/feliperocha/Desktop/dev/freelancing-projects/doutor-sim/node_modules/sst/dist/resource.js:48:15)
|  ↳ at makeAdmissionJourneyEventCreatedCommand (/Users/feliperocha/Desktop/dev/freelancing-projects/doutor-sim/infra/topics/admission-journey-event-created/command-builder.ts:14:24)
|  ↳ at <anonymous> (/Users/feliperocha/Desktop/dev/freelancing-projects/doutor-sim/infra/topics/credit-analysis-sent/subscriber.ts:62:9)
|  ↳ at Proxy._transactionWithCallback (/Users/feliperocha/Desktop/dev/freelancing-projects/doutor-sim/node_modules/@prisma/client/runtime/library.js:127:9534)
|  ↳ at handler (/Users/feliperocha/Desktop/dev/freelancing-projects/doutor-sim/infra/topics/credit-analysis-sent/subscriber.ts:18:3)
|  ↳ at async file:///Users/feliperocha/Desktop/dev/freelancing-projects/doutor-sim/.sst/platform/dist/nodejs-runtime/index.js:96:16

If I remove the format: 'cjs' property it works fine, but I can't do it since I'm using Prisma and Prisma needs to use the __filename variable, which is only available in CommonJS modules.

Can someone help me with this please?

jayair commented 4 weeks ago

I haven't tested this but if the linking SDK doesn't work for CJS, I would recommend not using links in this case and passing in the values as environment variables.

I don't know if we'll go back and add CJS support anytime soon.

felipemotarocha commented 4 weeks ago

Hey @jayair, thanks for the answer. I ended up moving the Lambdas back to ESM and adapting Prisma to work with it.

import type { PrismaClient as PrismaClientType } from '@prisma/client'
import { createRequire } from 'module'

const require = createRequire(import.meta.url ?? __filename)

const { PrismaClient: PrismaClientImpl } = require('@prisma/client')

export class PrismaClient extends (PrismaClientImpl as typeof PrismaClientType) {}

declare global {
  var cachedPrisma: PrismaClient
}

let prisma: PrismaClient
if (process.env.NODE_ENV === 'production') {
  prisma = new PrismaClient()
} else {
  if (!global.cachedPrisma) {
    global.cachedPrisma = new PrismaClient()
  }
  prisma = global.cachedPrisma
}

export { prisma }

Not a pretty code but it's working.