Skip to content

Commit

Permalink
tests pass if you comment out sequelize init
Browse files Browse the repository at this point in the history
  • Loading branch information
devksingh4 committed Oct 10, 2024
1 parent fd78273 commit 2655a80
Show file tree
Hide file tree
Showing 20 changed files with 1,324 additions and 316 deletions.
29 changes: 29 additions & 0 deletions cloudformation/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,35 @@ Resources:
Path: /{proxy+}
Method: ANY

AppApiLambdaFunctionVpc:
Type: AWS::Serverless::Function
DependsOn:
- AppLogGroups
Properties:
CodeUri: ../dist/src/
AutoPublishAlias: live
Runtime: nodejs20.x
Description: !Sub "${ApplicationFriendlyName} API Lambda - VPC attached"
FunctionName: !Sub ${ApplicationPrefix}-lambda-vpc
Handler: lambda.handler
MemorySize: 512
Role: !GetAtt AppSecurityRoles.Outputs.MainFunctionRoleArn
Timeout: 60
Environment:
Variables:
RunEnvironment: !Ref RunEnvironment
VpcConfig:
Ipv6AllowedForDualStack: True
SecurityGroupIds: !FindInMap [EnvironmentToCidr, !Ref RunEnvironment, SecurityGroupIds]
SubnetIds: !FindInMap [EnvironmentToCidr, !Ref RunEnvironment, SubnetIds]
Events:
LinkryEvent:
Type: Api
Properties:
RestApiId: !Ref AppApiGateway
Path: /api/v1/linkry/{proxy+}
Method: ANY

EventRecordsTable:
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: "Retain"
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"@fastify/auth": "^4.6.1",
"@fastify/aws-lambda": "^4.1.0",
"@fastify/cors": "^9.0.1",
"@sequelize/postgres": "^7.0.0-alpha.43",
"@touch4it/ical-timezones": "^1.9.0",
"discord.js": "^14.15.3",
"dotenv": "^16.4.5",
Expand Down
11 changes: 11 additions & 0 deletions src/errors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ export class InternalServerError extends BaseError<"InternalServerError"> {
}
}

export class DatabaseDeleteError extends BaseError<"DatabaseDeleteError"> {
constructor({ message }: { message: string }) {
super({
name: "DatabaseDeleteError",
id: 107,
message,
httpStatusCode: 500,
});
}
}

export class NotFoundError extends BaseError<"NotFoundError"> {
constructor({ endpointName }: { endpointName: string }) {
super({
Expand Down
50 changes: 50 additions & 0 deletions src/functions/database.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Sequelize } from "@sequelize/core";
import { PostgresDialect } from "@sequelize/postgres";
import { InternalServerError } from "../errors/index.js";
import { ShortLinkModel } from "../models/linkry.model.js";
import { FastifyInstance } from "fastify";

let logDebug: CallableFunction = console.log;
let logFatal: CallableFunction = console.log;

// Function to set the current logger for each invocation
export function setSequelizeLogger(
debugLogger: CallableFunction,
fatalLogger: CallableFunction,
) {
logDebug = (msg: string) => debugLogger(msg);
logFatal = (msg: string) => fatalLogger(msg);
}

export async function getSequelizeInstance(
fastify: FastifyInstance,
): Promise<Sequelize> {
const postgresUrl =
process.env.DATABASE_URL || fastify.secretValue?.postgres_url || "";

const sequelize = new Sequelize({
dialect: PostgresDialect,
url: postgresUrl as string,
ssl: {
rejectUnauthorized: false,
},
models: [ShortLinkModel],
logging: logDebug as (sql: string, timing?: number) => void,
pool: {
max: 2,
min: 0,
idle: 0,
acquire: 3000,
evict: 30, // lambda function timeout in seconds
},
});
try {
await sequelize.sync();
} catch (e: unknown) {
logFatal(`Could not authenticate to DB! ${e}`);
throw new InternalServerError({
message: "Could not establish database connection.",
});
}
return sequelize;
}
20 changes: 15 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@
import { randomUUID } from "crypto";
import fastify, { FastifyInstance } from "fastify";
import FastifyAuthProvider from "@fastify/auth";
import fastifyAuthPlugin from "./plugins/auth.js";
import fastifyAuthPlugin, { getSecretValue } from "./plugins/auth.js";
import protectedRoute from "./routes/protected.js";
import errorHandlerPlugin from "./plugins/errorHandler.js";
import { RunEnvironment, runEnvironments } from "./roles.js";
import { InternalServerError } from "./errors/index.js";
import eventsPlugin from "./routes/events.js";
import cors from "@fastify/cors";
import fastifyZodValidationPlugin from "./plugins/validate.js";
import { environmentConfig } from "./config.js";
import { environmentConfig, genericConfig } from "./config.js";
import organizationsPlugin from "./routes/organizations.js";
import icalPlugin from "./routes/ics.js";
import vendingPlugin from "./routes/vending.js";
import linkryPlugin from "./routes/linkry.js";
import * as dotenv from "dotenv";
import { getSequelizeInstance } from "./functions/database.js";

Check warning on line 19 in src/index.ts

View workflow job for this annotation

GitHub Actions / Run Unit Tests

'getSequelizeInstance' is defined but never used. Allowed unused vars must match /^_/u
dotenv.config();

const now = () => Date.now();
Expand Down Expand Up @@ -47,12 +49,19 @@ async function init() {
}
app.runEnvironment = process.env.RunEnvironment as RunEnvironment;
app.environmentConfig = environmentConfig[app.runEnvironment];
app.addHook("onRequest", (req, _, done) => {
app.secretValue = null;
app.sequelizeInstance = null;
app.addHook("onRequest", async (req, _) => {
if (!app.secretValue) {
app.secretValue =
(await getSecretValue(genericConfig.ConfigSecretName)) || {};
}
// if (!app.sequelizeInstance) {
// app.sequelizeInstance = await getSequelizeInstance(app);
// }
req.startTime = now();
req.log.info({ url: req.raw.url }, "received request");
done();
});

app.addHook("onResponse", (req, reply, done) => {
req.log.info(
{
Expand All @@ -71,6 +80,7 @@ async function init() {
api.register(eventsPlugin, { prefix: "/events" });
api.register(organizationsPlugin, { prefix: "/organizations" });
api.register(icalPlugin, { prefix: "/ical" });
api.register(linkryPlugin, { prefix: "/linkry" });
if (app.runEnvironment === "dev") {
api.register(vendingPlugin, { prefix: "/vending" });
}
Expand Down
45 changes: 45 additions & 0 deletions src/models/linkry.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
InferCreationAttributes,
InferAttributes,
Model,
CreationOptional,
DataTypes,
} from "@sequelize/core";
import {
AllowNull,
Attribute,
CreatedAt,
NotNull,
PrimaryKey,
Table,
UpdatedAt,
} from "@sequelize/core/decorators-legacy";

@Table({ timestamps: true, tableName: "short_links" })
export class ShortLinkModel extends Model<
InferAttributes<ShortLinkModel>,
InferCreationAttributes<ShortLinkModel>
> {
@Attribute(DataTypes.STRING)
@PrimaryKey
declare slug: string;

@Attribute(DataTypes.STRING)
@NotNull
declare full: string;

@Attribute(DataTypes.ARRAY(DataTypes.STRING))
@AllowNull
declare groups?: CreationOptional<string[]>;

@Attribute(DataTypes.STRING)
declare author: string;

@Attribute(DataTypes.DATE)
@CreatedAt
declare createdAt: CreationOptional<Date>;

@Attribute(DataTypes.DATE)
@UpdatedAt
declare updatedAt: CreationOptional<Date>;
}
2 changes: 1 addition & 1 deletion src/plugins/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from "../errors/index.js";
import { genericConfig } from "../config.js";

function intersection<T>(setA: Set<T>, setB: Set<T>): Set<T> {
export function intersection<T>(setA: Set<T>, setB: Set<T>): Set<T> {
const _intersection = new Set<T>();
for (const elem of setB) {
if (setA.has(elem)) {
Expand Down
2 changes: 2 additions & 0 deletions src/roles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ export const runEnvironments = ["dev", "prod"] as const;
export type RunEnvironment = (typeof runEnvironments)[number];
export enum AppRoles {
EVENTS_MANAGER = "manage:events",
LINKS_MANAGER = "manage:links",
LINKS_ADMIN = "admin:links",
}
export const allAppRoles = Object.values(AppRoles).filter(
(value) => typeof value === "string",
Expand Down
Loading

0 comments on commit 2655a80

Please sign in to comment.