aws-lambda#APIGatewayProxyEventV2 TypeScript Examples

The following examples show how to use aws-lambda#APIGatewayProxyEventV2. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: test.ts    From MDDL with MIT License 7 votes vote down vote up
createMockEvent = (
  data?: Partial<APIGatewayProxyEventV2>,
): APIGatewayProxyEventV2 => {
  return {
    headers: {
      authorization: 'my-token',
    },
    isBase64Encoded: false,
    rawPath: 'test',
    rawQueryString: 'test',
    requestContext: {
      accountId: '1111111111',
      apiId: 'apiId',
      domainName: 'domainName',
      domainPrefix: 'domainPrefix',
      http: {
        method: 'GET',
        path: 'path',
        protocol: 'HTTPS',
        sourceIp: '127.0.0.1',
        userAgent: 'Custom-UA',
      },
      requestId: '4A047E06-98D3-43AA-8501-424D8E0DEA32',
      routeKey: '4A047E06-98D3-43AA-8501-424D8E0DEA32',
      stage: 'stage',
      time: '2020-01-01T00:00:00.000Z',
      timeEpoch: 123456789,
    },
    routeKey: 'routeKey',
    version: '1',
    ...data,
  }
}
Example #2
Source File: api-gateway-v2-parse-request.ts    From oauth-app.js with MIT License 6 votes vote down vote up
export function parseRequest(request: APIGatewayProxyEventV2): OctokitRequest {
  const { method } = request.requestContext.http;
  let url = request.rawPath;
  const { stage } = request.requestContext;
  if (url.startsWith("/" + stage)) url = url.substring(stage.length + 1);
  if (request.rawQueryString) url += "?" + request.rawQueryString;
  const headers = request.headers as Record<string, string>;
  const text = async () => request.body || "";
  return { method, url, headers, text };
}
Example #3
Source File: index.ts    From cdk-examples with MIT License 6 votes vote down vote up
export async function deleteTodo(event: APIGatewayProxyEventV2): Promise<APIGatewayProxyResultV2> {

    const { body } = event

    if (!body) {

        return sendFail('invalid request')
    }

    const { id } = JSON.parse(body) as DeleteTodo

    const dynamoClient = new DynamoDB({ 
        region: 'us-east-1' 
    })

    const todoParams: DeleteItemInput = {
        Key: marshall({ id }),
        ReturnValues: 'ALL_OLD',
        TableName: process.env.TODO_TABLE_NAME
    }

    try {

        const { Attributes } = await dynamoClient.deleteItem(todoParams)

        const todo = Attributes ? unmarshall(Attributes) : null
        
        return {
            statusCode: 200,
            body: JSON.stringify({ todo })    
        }

    } catch (err) {

        console.log(err)

        return sendFail('something went wrong')
    }
}
Example #4
Source File: middleware.ts    From MDDL with MIT License 6 votes vote down vote up
formatApiGatewayResult = <E = APIGatewayProxyEventV2>(
  innerFunction: (event: E) => any | void,
): Handler<E> => async (event: E) => {
  try {
    const result = await innerFunction(event)
    if (result) {
      return createJsonResponse(result)
    }
    return createStatusCodeResponse(204)
  } catch (error) {
    if (createError.isHttpError(error)) {
      return createErrorResponse(
        error.message,
        error.statusCode,
        error.otherProps,
      )
    }

    logger.error(error)

    return createErrorResponse('An internal error occurred', 500)
  }
}
Example #5
Source File: api-gateway-v2.ts    From oauth-app.js with MIT License 6 votes vote down vote up
export function createAWSLambdaAPIGatewayV2Handler(
  app: OAuthApp<Options<ClientType>>,
  {
    pathPrefix,
    onUnhandledRequest = onUnhandledRequestDefaultAWSAPIGatewayV2,
  }: HandlerOptions & {
    onUnhandledRequest?: (
      event: APIGatewayProxyEventV2
    ) => Promise<APIGatewayProxyStructuredResultV2>;
  } = {}
) {
  return async function (event: APIGatewayProxyEventV2) {
    const request = parseRequest(event);
    const response = await handleRequest(app, { pathPrefix }, request);
    return response ? sendResponse(response) : onUnhandledRequest(event);
  };
}
Example #6
Source File: index.ts    From MDDL with MIT License 6 votes vote down vote up
submitDocumentsAccessedEvent = async (props: {
  ownerId: string
  user: User
  documents: DocumentAccessed[]
  event: APIGatewayProxyEventV2
}) => {
  const { ownerId, user, documents, event } = props
  const activities = documents.map(({ document, files }) =>
    createActivityInput({
      user,
      type: ActivityActionTypeEnum.DOCUMENTACCESSED,
      resource: document,
      resourceType: ActivityResourceTypeEnum.DOCUMENT,
      relatedResources: files.map((r) =>
        toActivityResource(r, ActivityResourceTypeEnum.DOCUMENTFILE),
      ),
      event,
    }),
  )
  return await submitActivities(ownerId, activities)
}
Example #7
Source File: index.ts    From cdk-examples with MIT License 6 votes vote down vote up
export async function getAll(event: APIGatewayProxyEventV2): Promise<APIGatewayProxyResultV2> {

    const dynamoClient = new DynamoDB({ 
        region: 'us-east-1' 
    })

    const scanTodo: ScanInput = {
        TableName: process.env.TODO_TABLE_NAME
    }

    try {

        const { Items } = await dynamoClient.scan(scanTodo)

        const userData = Items ? Items.map(item => unmarshall(item)) : []

        return {
            statusCode: 200,
            body: JSON.stringify({ listTodo: userData})
        }

    } catch (err) {

        console.log(err)

        return {
            statusCode: 400,
            body: JSON.stringify({
                message: 'something went wrong'
            })
        }
    }
}
Example #8
Source File: getByUserId.test.ts    From MDDL with MIT License 5 votes vote down vote up
describe('getByUserId', () => {
  const userId = 'myUserId'
  let event: APIGatewayProxyEventV2

  beforeEach(() => {
    mockUserData(userId)
    event = setUserId(
      userId,
      createMockEvent({
        pathParameters: {
          userId,
        },
      }),
    )
  })

  it('returns document', async () => {
    toMockedFunction(getDocumentsByOwnerId).mockImplementationOnce(() =>
      Promise.resolve([
        DocumentModel.fromJson({
          id: 'myDocumentId1',
          ownerId: userId,
          name: 'My First File',
          createdAt: new Date('2015-01-12T13:14:15Z'),
          createdBy: userId,
          updatedBy: userId,
        }),
        DocumentModel.fromJson({
          id: 'myDocumentId2',
          ownerId: userId,
          name: 'My Second File',
          createdAt: new Date('2015-01-27T13:14:15Z'),
          createdBy: userId,
          updatedBy: userId,
          thumbnailPath: 'my-thumbnail-path',
        }),
      ]),
    )
    expect(await getByUserId(event)).toMatchInlineSnapshot(`
      Object {
        "body": "{\\"documents\\":[{\\"name\\":\\"My First File\\",\\"createdDate\\":\\"2015-01-12T13:14:15.000Z\\",\\"id\\":\\"myDocumentId1\\",\\"links\\":[{\\"href\\":\\"/documents/myDocumentId1\\",\\"rel\\":\\"self\\",\\"type\\":\\"GET\\"}]},{\\"name\\":\\"My Second File\\",\\"createdDate\\":\\"2015-01-27T13:14:15.000Z\\",\\"id\\":\\"myDocumentId2\\",\\"links\\":[{\\"href\\":\\"/documents/myDocumentId2\\",\\"rel\\":\\"self\\",\\"type\\":\\"GET\\"},{\\"href\\":\\"https://presigned-url.for/my-thumbnail-path?filename=thumbnail.png&disposition=inline\\",\\"rel\\":\\"thumbnail\\",\\"type\\":\\"GET\\"}]}]}",
        "cookies": Array [],
        "headers": Object {
          "Content-Type": "application/json",
        },
        "isBase64Encoded": false,
        "statusCode": 200,
      }
    `)
  })
  it('returns empty when none found', async () => {
    toMockedFunction(getDocumentsByOwnerId).mockImplementationOnce(() =>
      Promise.resolve([]),
    )
    expect(await getByUserId(event)).toMatchInlineSnapshot(`
      Object {
        "body": "{\\"documents\\":[]}",
        "cookies": Array [],
        "headers": Object {
          "Content-Type": "application/json",
        },
        "isBase64Encoded": false,
        "statusCode": 200,
      }
    `)
  })
})
Example #9
Source File: index.ts    From cdk-examples with MIT License 5 votes vote down vote up
export async function queryTodo(event: APIGatewayProxyEventV2): Promise<APIGatewayProxyResultV2> {

    const { body } = event

    if (!body) return sendError('invalid request')
    
    const data = JSON.parse(body) as UserInput

    const dynamoClient = new DynamoDB({ 
        region: 'us-east-1' 
    })

    const queryTodo: QueryInput = {
        KeyConditionExpression: '#todoOwner = :userId',
        ExpressionAttributeNames: {
            '#todoOwner': 'owner'
        }, 
        ExpressionAttributeValues: marshall({
            ':userId': data.owner
        }),
        IndexName: 'ownerIndex',
        TableName: process.env.TODO_TABLE_NAME
    }
    
    try {

        const { Items } = await dynamoClient.query(queryTodo)

        const listTodo = Items ? Items.map(item => unmarshall(item)) : []

        return {
            statusCode: 200,
            body: JSON.stringify({ listTodo })
        }

    } catch (err) {

        console.log(err)

        return sendError('something went wrong')
    }
}
Example #10
Source File: acceptTerms.test.ts    From MDDL with MIT License 5 votes vote down vote up
describe('acceptTerms', () => {
  const userId = 'myUserId'
  let event: APIGatewayProxyEventV2

  beforeEach(() => {
    event = setUserId(
      userId,
      createMockEvent({
        pathParameters: {
          userId,
        },
      }),
    )
  })

  it('processes the update', async () => {
    const baseUserData = mockUserData(userId)
    toMockedFunction(updateUser).mockImplementationOnce(async (u) =>
      User.fromDatabaseJson({
        ...baseUserData,
        attributes: {
          termsOfUseAccepted: true,
        },
      }),
    )
    expect(await acceptTerms(event)).toMatchInlineSnapshot(`
      Object {
        "body": "{\\"id\\":\\"myUserId\\",\\"givenName\\":\\"Jane\\",\\"familyName\\":\\"Citizen\\",\\"email\\":\\"[email protected]\\",\\"name\\":\\"Jane Citizen\\",\\"termsOfUseAccepted\\":true,\\"links\\":[]}",
        "cookies": Array [],
        "headers": Object {
          "Content-Type": "application/json",
        },
        "isBase64Encoded": false,
        "statusCode": 200,
      }
    `)
  })

  it('blocks update if terms of use is already accepted', async () => {
    mockUserData(userId, undefined, {
      termsOfUseAccepted: true,
    })
    expect(await acceptTerms(event)).toMatchInlineSnapshot(`
      Object {
        "body": "{\\"message\\":\\"terms of use already accepted for user!\\"}",
        "cookies": Array [],
        "headers": Object {
          "Content-Type": "application/json",
        },
        "isBase64Encoded": false,
        "statusCode": 400,
      }
    `)
  })
})
Example #11
Source File: index.ts    From cdk-examples with MIT License 5 votes vote down vote up
export async function update(event: APIGatewayProxyEventV2): Promise<APIGatewayProxyResultV2> {

    const { body } = event

    if (!body) {

        return sendFail('invalid request')
    }

    const { id, done } = JSON.parse(body) as UpdateTodo

    const dynamoClient = new DynamoDB({ 
        region: 'us-east-1' 
    })

    const todoParams: UpdateItemInput = {
        Key: marshall({ id }),
        UpdateExpression: 'set done = :done',
        ExpressionAttributeValues: marshall({
            ':done': done
        }),
        ReturnValues: 'ALL_NEW',
        TableName: process.env.UPDATE_TABLE_NAME
    }

    try {

        const { Attributes } = await dynamoClient.updateItem(todoParams)

        const todo = Attributes ? unmarshall(Attributes) : null
        
        return {
            statusCode: 200,
            body: JSON.stringify({ todo })    
        }

    } catch (err) {

        console.log(err)

        return sendFail('something went wrong')
    }
}
Example #12
Source File: middleware.ts    From MDDL with MIT License 5 votes vote down vote up
combineRequest = (event: APIGatewayProxyEventV2): APIGatewayRequest => {
  return {
    event,
  }
}
Example #13
Source File: index.ts    From cdk-examples with MIT License 5 votes vote down vote up
export async function myFunction(event: APIGatewayProxyEventV2): Promise<APIGatewayProxyResultV2> {
    
    return {
        statusCode: 200,
        body: JSON.stringify({ message: 'hello from ts lambda' })
    }
}
Example #14
Source File: addAccountDelegate.test.ts    From MDDL with MIT License 5 votes vote down vote up
describe('addAccountDelegate', () => {
  const userId = 'myUserId'
  const email = 'myEmail'
  const delegateEmail = '[email protected]'
  const accountDelegateId = 'myAccountDelegateId'
  let event: APIGatewayProxyEventV2

  beforeEach(() => {
    mockUserData(userId, email)
    event = setUserId(
      userId,
      createMockEvent({
        pathParameters: {
          userId,
        },
      }),
    )
  })

  it('returns 404 if user not found', async () => {
    const requirePermissionToUserImpl = (
      await importMock('@/services/users/authorization')
    ).requirePermissionToUserImpl
    requirePermissionToUserImpl.mockImplementationOnce(async (request) => {
      throw new createError.NotFound('user not found')
    })
    expect(await addAccountDelegate(event)).toMatchInlineSnapshot(`
      Object {
        "body": "{\\"message\\":\\"user not found\\"}",
        "cookies": Array [],
        "headers": Object {
          "Content-Type": "application/json",
        },
        "isBase64Encoded": false,
        "statusCode": 404,
      }
    `)
  })

  it('returns response if found', async () => {
    event.body = JSON.stringify({
      email: delegateEmail,
    })
    const data = {
      id: accountDelegateId,
      accountId: userId,
      delegateEmail,
      status: UserDelegatedAccessStatus.INVITATIONSENT,
      inviteValidUntil: addDaysFromNow(5),
      createdAt: new Date('2015-01-12T13:14:15Z'),
    }
    toMockedFunction(getUserById).mockImplementation(async (userId: string) => {
      return User.fromDatabaseJson({
        id: userId,
        givenName: userId,
        familyName: userId,
      })
    })
    toMockedFunction(createAccountDelegate).mockImplementationOnce(async () => {
      return AccountDelegate.fromDatabaseJson(data)
    })
    expect(await addAccountDelegate(event)).toMatchInlineSnapshot(`
      Object {
        "body": "{\\"createdDate\\":\\"2015-01-12T13:14:15.000Z\\",\\"email\\":\\"[email protected]\\",\\"id\\":\\"myAccountDelegateId\\",\\"links\\":[{\\"href\\":\\"/delegates/myAccountDelegateId\\",\\"rel\\":\\"delete\\",\\"type\\":\\"DELETE\\"}],\\"status\\":\\"INVITATION_SENT\\"}",
        "cookies": Array [],
        "headers": Object {
          "Content-Type": "application/json",
        },
        "isBase64Encoded": false,
        "statusCode": 200,
      }
    `)
  })
})
Example #15
Source File: api-gateway-v2.ts    From oauth-app.js with MIT License 5 votes vote down vote up
async function onUnhandledRequestDefaultAWSAPIGatewayV2(
  event: APIGatewayProxyEventV2
): Promise<APIGatewayProxyStructuredResultV2> {
  const request = parseRequest(event);
  const response = onUnhandledRequestDefault(request);
  return sendResponse(response);
}
Example #16
Source File: deleteAccountDelegate.test.ts    From MDDL with MIT License 5 votes vote down vote up
describe('deleteAccountDelegate', () => {
  const userId = 'myUserId'
  const email = 'myEmail'
  const accountId = 'otherAccountId'
  const accountDelegateId = 'myAccountDelegateId'
  let event: APIGatewayProxyEventV2

  beforeEach(() => {
    mockUserData(userId)
    event = setUserId(
      userId,
      createMockEvent({
        pathParameters: {
          delegateId: accountDelegateId,
        },
      }),
    )
  })

  it('returns 404 if delegate not found', async () => {
    const requirePermissionToAccountDelegateImpl = (
      await importMock('@/services/accountDelegates/authorization')
    ).requirePermissionToAccountDelegateImpl
    requirePermissionToAccountDelegateImpl.mockImplementationOnce(async () => {
      throw new createError.NotFound('accountDelegate not found')
    })
    expect(await deleteAccountDelegateHandler(event)).toMatchInlineSnapshot(`
      Object {
        "body": "{\\"message\\":\\"accountDelegate not found\\"}",
        "cookies": Array [],
        "headers": Object {
          "Content-Type": "application/json",
        },
        "isBase64Encoded": false,
        "statusCode": 404,
      }
    `)
  })

  it('returns response if deleted', async () => {
    const data = {
      id: accountDelegateId,
      accountId: accountId,
      delegateEmail: email,
      status: UserDelegatedAccessStatus.INVITATIONSENT,
      inviteValidUntil: addDaysFromNow(5),
      createdAt: new Date('2015-01-12T13:14:15Z'),
    }
    toMockedFunction(getUserById).mockImplementation(async (userId: string) => {
      return User.fromDatabaseJson({
        id: userId,
        givenName: userId,
        familyName: userId,
      })
    })
    toMockedFunction(getAccountDelegateById).mockImplementationOnce(
      async () => {
        return AccountDelegate.fromDatabaseJson(data)
      },
    )
    toMockedFunction(deleteAccountDelegate).mockImplementationOnce(
      async () => 1,
    )
    expect(await deleteAccountDelegateHandler(event)).toMatchInlineSnapshot(`
      Object {
        "cookies": Array [],
        "isBase64Encoded": false,
        "statusCode": 204,
      }
    `)
  })
})
Example #17
Source File: aws-lambda-api-gateway-v2.test.ts    From oauth-app.js with MIT License 4 votes vote down vote up
describe("createAWSLambdaAPIGatewayV2Handler(app)", () => {
  it("supports oauth app", async () => {
    const app = new OAuthApp({
      clientType: "oauth-app",
      clientId: "0123",
      clientSecret: "0123secret",
    });
    createAWSLambdaAPIGatewayV2Handler(app);
  });

  it("supports github app", async () => {
    const app = new OAuthApp({
      clientType: "github-app",
      clientId: "0123",
      clientSecret: "0123secret",
    });
    createAWSLambdaAPIGatewayV2Handler(app);
  });

  it("fail-over to default unhandled request handler", async () => {
    const appMock = {};
    const handleRequest = createAWSLambdaAPIGatewayV2Handler(
      appMock as unknown as OAuthApp
    );

    const response = await handleRequest({
      requestContext: { http: { method: "GET" }, stage: "prod" },
      rawPath: "/prod/unknown",
    } as APIGatewayProxyEventV2);

    expect(response.statusCode).toBe(404);
  });

  it("allow pre-flight requests", async () => {
    const app = new OAuthApp({ clientId: "0123", clientSecret: "0123secret" });
    const handleRequest = createAWSLambdaAPIGatewayV2Handler(app);

    const response = await handleRequest({
      requestContext: { http: { method: "OPTIONS" }, stage: "prod" },
      rawPath: "/prod/api/github/oauth/token",
    } as APIGatewayProxyEventV2);

    expect(response.statusCode).toStrictEqual(200);
    expect(response.headers!["access-control-allow-origin"]).toBe("*");
    expect(response.headers!["access-control-allow-methods"]).toBe("*");
    expect(response.headers!["access-control-allow-headers"]).toBe(
      "Content-Type, User-Agent, Authorization"
    );
  });

  it("supports $default stage", async () => {
    const app = new OAuthApp({ clientId: "0123", clientSecret: "0123secret" });
    const handleRequest = createAWSLambdaAPIGatewayV2Handler(app);

    const response = await handleRequest({
      requestContext: { http: { method: "GET" }, stage: "$default" },
      rawPath: "/api/github/oauth/login",
    } as APIGatewayProxyEventV2);

    expect(response.statusCode).toBe(302);
    const url = new URL(response.headers!.location as string);
    expect(url.origin).toBe("https://github.com");
    expect(url.pathname).toBe("/login/oauth/authorize");
    expect(url.searchParams.get("client_id")).toBe("0123");
    expect(url.searchParams.get("state")).toMatch(/^\w+$/);
    expect(url.searchParams.get("scope")).toBeNull();
  });

  it("supports named stage", async () => {
    const app = new OAuthApp({ clientId: "0123", clientSecret: "0123secret" });
    const handleRequest = createAWSLambdaAPIGatewayV2Handler(app);

    const response = await handleRequest({
      requestContext: { http: { method: "GET" }, stage: "prod" },
      rawPath: "/prod/api/github/oauth/login",
    } as APIGatewayProxyEventV2);

    expect(response.statusCode).toBe(302);
    const url = new URL(response.headers!.location as string);
    expect(url.origin).toBe("https://github.com");
    expect(url.pathname).toBe("/login/oauth/authorize");
    expect(url.searchParams.get("client_id")).toBe("0123");
    expect(url.searchParams.get("state")).toMatch(/^\w+$/);
    expect(url.searchParams.get("scope")).toBeNull();
  });

  it("passes query string to generic request handler correctly", async () => {
    const app = new OAuthApp({ clientId: "0123", clientSecret: "0123secret" });
    const handleRequest = createAWSLambdaAPIGatewayV2Handler(app);

    const response = await handleRequest({
      requestContext: { http: { method: "GET" }, stage: "prod" },
      rawPath: "/prod/api/github/oauth/login",
      rawQueryString: "state=mystate123&scopes=one,two,three",
    } as APIGatewayProxyEventV2);

    expect(response.statusCode).toBe(302);
    const url = new URL(response.headers!.location as string);
    expect(url.origin).toBe("https://github.com");
    expect(url.pathname).toBe("/login/oauth/authorize");
    expect(url.searchParams.get("client_id")).toBe("0123");
    expect(url.searchParams.get("state")).toBe("mystate123");
    expect(url.searchParams.get("scope")).toBe("one,two,three");
  });
});
Example #18
Source File: putDocumentById.test.ts    From MDDL with MIT License 4 votes vote down vote up
describe('putDocumentById', () => {
  const documentId = 'myDocumentId'
  const userId = 'myUserId'
  let event: APIGatewayProxyEventV2

  beforeEach(() => {
    mockUserData(userId)
    toMockedFunction(getDocumentById).mockImplementationOnce(async () =>
      Document.fromDatabaseJson({
        id: documentId,
        ownerId: userId,
        name: documentId,
      }),
    )
    event = setUserId(
      userId,
      createMockEvent({
        pathParameters: {
          documentId,
        },
      }),
    )
  })

  it('fails validation on no body', async () => {
    expect(await putDocumentById(event)).toEqual(
      expect.objectContaining({
        body: '{"message":"validation error: body was expected but empty"}',
      }),
    )
  })

  it('validation requires name or description', async () => {
    event.body = JSON.stringify({})
    expect(await putDocumentById(event)).toEqual(
      expect.objectContaining({
        body:
          '{"message":"validation error: \\"value\\" must contain at least one of [name, description]"}',
      }),
    )
  })

  it('updates name', async () => {
    toMockedFunction(updateDocument).mockImplementationOnce(async () => 1)
    const body = {
      name: 'test update',
    }
    event.body = JSON.stringify(body)
    const result = (await putDocumentById(
      event,
    )) as APIGatewayProxyStructuredResultV2
    expect(result).toMatchInlineSnapshot(`
      Object {
        "cookies": Array [],
        "isBase64Encoded": false,
        "statusCode": 204,
      }
    `)
    expect(toMockedFunction(updateDocument)).toHaveBeenCalledWith(
      documentId,
      expect.objectContaining(body),
    )
  })

  it('updates description', async () => {
    toMockedFunction(updateDocument).mockImplementationOnce(async () => 1)
    const body = {
      description: 'test update',
    }
    event.body = JSON.stringify(body)
    const result = (await putDocumentById(
      event,
    )) as APIGatewayProxyStructuredResultV2
    expect(result).toMatchInlineSnapshot(`
      Object {
        "cookies": Array [],
        "isBase64Encoded": false,
        "statusCode": 204,
      }
    `)
    expect(toMockedFunction(updateDocument)).toHaveBeenCalledWith(
      documentId,
      expect.objectContaining(body),
    )
  })
})