TypeORM not working with Lambda using SAM/esbuild: Cannot find module 'reflect-metadata'

413 Views Asked by At

I've a small lambda configured through SAM

  OrganizationPOSTFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: OrganizationPOST
      CodeUri: ../src/
      Handler: organization-post.lambdaHandler
      Timeout: 900
      MemorySize: 512
      Events:
        Organization:
          Type: Api
          Properties:
            RestApiId: !Ref ApiGateway
            Path: /organization
            Method: post
    Metadata:
      BuildMethod: esbuild
      BuildProperties:
        Minify: false
        Target: "es2020"
        Sourcemap: true
        EntryPoints:
          - organization-post.ts
        External:
          - pg-native
          - reflect-metadata #<- I tried this but doesn't work neither

All my code is placed under the src folder, including the node_modules

- src
--database
--entities
--node_modules
--my_lambda_here

the problem can't be the node_modules because I've added several packages and these work ok and I've also added reflect-metadata

my Organization Entity

import * as validator from "class-validator"

@Entity()
export class Organization extends BaseEntity {
    @PrimaryGeneratedColumn('uuid')
    id: string;

    @Column()
    @validator.IsDefined()
    name: string;


}

my DB connection IMPORTING REFLECT-METADATA

import "reflect-metadata"
import { DataSource } from 'typeorm';
import {Organization} from "../entities/Organization";

export const DB = new DataSource({
    url : process.env.DATABASE_URL,
    type: 'postgres',
    synchronize: true,
    entities: [Organization],
    migrations: [],
    logging: 'all',
});

DB.initialize()
.catch((error)=>console. Error(error))

and my lambda

import "reflect-metadata" //<- I tried import reflect-metadata here too but doesn't work neither
import {DB} from "./database/DB";
import {APIGatewayEvent, Handler} from "aws-lambda";
import {Organization} from "./entities/Organization";
import {validate} from "class-validator";

const validateOrganization = async (organization : Organization)=>{
    const errors = await validate(organization)

    if(errors.length > 0){
        throw new Error(`Invalid data for organization: ${errors.join(", ")}`)
    }
}

export const lambdaHandler : Handler = async (event : APIGatewayEvent) => {
    try {
        const body = JSON.parse(event.body||"")
        const organization : Organization = Organization.create(body)

        await validateOrganization(organization)

        const savedOrganization = DB.manager.save(organization)

        return {
            statusCode: 200,
            body: JSON.stringify({
                message: JSON.stringify(savedOrganization),
            }),
        };
    }catch (e) {
        console.error(e)
        return {
            statusCode: 500,
            body: JSON.stringify({
                message: JSON.stringify(e),
            }),
        };
    }

};

when I tried to run this project I get

 Cannot find module 'reflect-metadata'

but this is included in my package.json dependencies

  "dependencies": {
    "class-validator": "^0.14.0",
    "esbuild": "^0.14.14",
    "pg": "^8.10.0",
    "reflect-metadata": "^0.1.13",
    "typeorm": "^0.3.15"
  },

I tried import this in different places and mark as external in my SAM yaml...but I get always the same error

Do you know what could be the problem?...any help will be highly appreciated

1

There are 1 best solutions below

0
Agent boubou On

For anyone it might help, the way I resolved it was by declaring the type property inside the @Column decorators

import { Column, CreateDateColumn, UpdateDateColumn } from 'typeorm';

export class Audit {
@Column({
    default: null,
    type: 'int',
})
createdBy: number;

@CreateDateColumn({
    type: 'timestamp',
})
createdAt: Date;

@Column({
    default: null,
    type: 'int',
})
updatedBy: number;

@UpdateDateColumn({
    type: 'timestamp',
})
updatedAt: Date;
}

Depending on which database engine you're using your types may vary, but using MySql adding varchar / int etc. solved the issue