routing-controllers icon indicating copy to clipboard operation
routing-controllers copied to clipboard

question: @Param not type casted

Open NicholasMKim opened this issue 2 years ago • 24 comments

I was trying to... Context:

  • Migrating from serverless to sst
  • Added @vendia/serverless-express during migration (but not 100% sure if this is necessary but without this sst threw an error of stream.listeners is not a function)

The problem: After migrating to sst @Param doesn't cast id: number into number.

app.ts

import "reflect-metadata";
import { createExpressServer } from "routing-controllers";
import serverlessExpress from "@vendia/serverless-express";
import { APIGatewayProxyHandlerV2 } from "aws-lambda";


const app = createExpressServer({
  classTransformer: true,
  controllers: [/** controllers */]
});

export const handler: APIGatewayProxyHandlerV2 = (event, context) => {
  const instance = serverlessExpress({ app });
  return instance(event, context, () => {
    console.log("Server started");
  });
};

oneOfTheControllers.ts

@JsonController("/api/v1")
export class ListingController {
  @Get("/listing/agent-team/:agentTeamId")
  @OnUndefined(404)
  @OnNull(404)
  async getListingsByAgentTeamId(
    @CurrentUser() user: any,
    @Param("agentTeamId") agentTeamId: number
  ) {
    // agentTeamId is string
    authValidator(Number(agentTeamId), user, "agentTeamId");
    const listings = await ListingModel.getListingsByAgentTeamId(
      user.agentTeamId
    );
    return listings;
  }
}

NicholasMKim avatar Jun 09 '23 03:06 NicholasMKim

Well this indeed seems weird. Could you setup a repro repo so I can debug?

attilaorosz avatar Jun 09 '23 07:06 attilaorosz

Here is the link for testing and it acts the same.

https://github.com/mkim871/sst-testing/blob/4640f178b68f481757c17231062c7f4f7fda702d/packages/functions/src/app.ts#L26

NicholasMKim avatar Jun 11 '23 10:06 NicholasMKim

Is there a chance you are missing "emitDecoratorMetadata": true, from your tsconfig.json?

attilaorosz avatar Jun 11 '23 17:06 attilaorosz

I think that's not the issue. My main project has "emitDecoratorMetadata": true and I just tested the testing repo with that too 🥲. Do you know which function is responsible for class-transformer?

NicholasMKim avatar Jun 12 '23 00:06 NicholasMKim

Unfortunately I have no experience with sst. I tried your repo locally, adding emitDecoratorMetadata: true and it worked as intended. The transformation happens here: https://github.com/typestack/routing-controllers/blob/90ebb6a11e0a1d2f9f9da143c034576cdb564fa6/src/ActionParameterHandler.ts#LL215C21-L215C21

attilaorosz avatar Jun 12 '23 18:06 attilaorosz

Screenshot 2023-06-13 at 11 33 18 AM

When I log the targetname, it is undefined. Can versions be a problem? Such as ts, node or class-transformer?

NicholasMKim avatar Jun 12 '23 23:06 NicholasMKim

Could you try to log the values here? https://github.com/typestack/routing-controllers/blob/90ebb6a11e0a1d2f9f9da143c034576cdb564fa6/src/metadata/ParamMetadata.ts#LL123C1-L123C1

To see of explicitType is set or ParamTypes is resolved correctly.

attilaorosz avatar Jun 13 '23 06:06 attilaorosz

Screenshot 2023-06-13 at 7 47 27 PM

What have I done wrong 😂. btw, Much appreciated for helping. You are the legend!

NicholasMKim avatar Jun 13 '23 07:06 NicholasMKim

Well it seems like emitDecoratorMetadata is not set so you are not getting type information. Are you sure it is set correctly?

attilaorosz avatar Jun 13 '23 08:06 attilaorosz

It seems right to me https://github.com/mkim871/sst-testing/blob/main/packages/functions/tsconfig.json

NicholasMKim avatar Jun 13 '23 09:06 NicholasMKim

Sorry for the very long delay. Did you find a solution to this? The tsconfig.json indeed looks ok to me.

attilaorosz avatar Aug 15 '23 17:08 attilaorosz

Just ran into this issue as well. tsconfig.json was:

{
  "extends": "@cappsule/tsconfig/node.json",
  "include": ["src", "./db/**/*", "./scripts/**/*", "./generated/**/*"],

  "exclude": [
    "node_modules",
    "./coverage",
    "./dist",
    "__tests__",
    "jest.config.js"
  ],
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  }
}

The problem was we were dumping it into prisma which expected a number, a simple Number(param) fixed it but yea not sure what the cause is.

Should note that it worked in dev mode so something happens during compile to not cast it i guess.

nick-paloma avatar Dec 08 '23 00:12 nick-paloma

What do you use to compile typescript? I know we had issues with esbuild and type casting from decorators.

attilaorosz avatar Dec 08 '23 07:12 attilaorosz

good question, unless I'm mistaken, we're using swc and this is the .swcrc

{
  "env": {
    "target": {
      "node": 18
    }
  },
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "decorators": true
    }
  },
  "module": {
    "type": "commonjs"
  },
  "sourceMaps": "inline"
}

nick-paloma avatar Dec 10 '23 20:12 nick-paloma

You have reflect-metadata imported, right?

attilaorosz avatar Dec 10 '23 21:12 attilaorosz

yea and its in the dist too "reflect-metadata": "^0.1.13",

nick-paloma avatar Dec 10 '23 21:12 nick-paloma

Could you try to make a simple repro repo for this so I can debug it further?

attilaorosz avatar Dec 10 '23 21:12 attilaorosz

sure mate, ill ping here when its done

nick-paloma avatar Dec 10 '23 21:12 nick-paloma

heres the repo

Prod:

yarn && yarn build && yarn start:prod

Dev:

yarn && yarn start:dev

Navigate to: http://localhost:9876/test/1

On prod it should give:

{"type":"string"}

And on dev it'll be:

{"type":"number"}

nick-paloma avatar Dec 11 '23 01:12 nick-paloma

It seems like you are missing some config in .swcrc. Could you try adding

"transform": {
  "legacyDecorator": true,
  "decoratorMetadata": true
}

into the "jsc" block?

attilaorosz avatar Dec 11 '23 10:12 attilaorosz

That got it for me. Can't believe I missed that one. Although it might not have been the case for OP

Thanks much

nick-paloma avatar Dec 11 '23 20:12 nick-paloma