Skip to content

Commit

Permalink
feat: add AdonisJS alongside Express
Browse files Browse the repository at this point in the history
  • Loading branch information
AdrianAndersen committed Jan 22, 2025
1 parent b681df5 commit 6dc1269
Show file tree
Hide file tree
Showing 350 changed files with 3,368 additions and 928 deletions.
1 change: 1 addition & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
APP_KEY=
PORT=
SERVER_PATH=
API_ENV=
Expand Down
15 changes: 14 additions & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@
"exports": "./dist/index.js",
"type": "module",
"scripts": {
"dev": "tsx watch --env-file=.env ./src/index.ts",
"dev": "tsx watch --env-file=.env src/index.ts",
"build": "pkgroll --sourcemap --tsconfig=tsconfig.build.json",
"build:sentry": "pnpm build && pnpm run sentry:sourcemaps",
"serve": "node --env-file=.env ./dist/index.js",
"start": "tsx --env-file=.env src/bin/server.ts",
"test": "API_ENV=test tsx src/bin/test.ts",
"sentry:sourcemaps": "sentry-cli sourcemaps inject --org boklisten --project backend ./dist && sentry-cli sourcemaps upload --org boklisten --project backend ./dist"
},
"dependencies": {
"@adonisjs/auth": "^9.3.1",
"@adonisjs/core": "^6.17.1",
"@adonisjs/cors": "^2.2.1",
"@boklisten/bl-email": "^1.8.2",
"@boklisten/bl-post-office": "^0.5.56",
"@napi-rs/image": "^1.9.2",
Expand All @@ -39,6 +43,7 @@
"@types/sinon": "^17.0.3",
"@types/sinon-chai": "^4.0.0",
"@types/validator": "^13.12.2",
"@vinejs/vine": "^3.0.0",
"canvas": "^3.1.0",
"cors": "^2.8.5",
"express": "^4.21.2",
Expand All @@ -58,17 +63,25 @@
"pdfkit": "^0.16.0",
"qrcode": "^1.5.4",
"qs": "^6.14.0",
"reflect-metadata": "^0.2.2",
"request": "^2.88.2",
"request-promise": "^4.2.6",
"twilio": "^5.4.2",
"validator": "^13.12.0",
"winston": "^3.17.0"
},
"devDependencies": {
"@adonisjs/assembler": "^7.8.2",
"@adonisjs/eslint-config": "^1.3.0",
"@adonisjs/prettier-config": "^1.4.0",
"@adonisjs/tsconfig": "^1.4.0",
"@japa/api-client": "^3.0.3",
"@japa/assert": "^4.0.1",
"@japa/plugin-adonisjs": "^4.0.0",
"@japa/runner": "^4.1.0",
"chai": "^5.1.2",
"chai-as-promised": "^8.0.1",
"pino-pretty": "^13.0.0",
"pkgroll": "^2.6.1",
"sinon": "^19.0.2",
"sinon-chai": "^4.0.0",
Expand Down
31 changes: 31 additions & 0 deletions backend/src/adonisrc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { defineConfig } from "@adonisjs/core/app";

export default defineConfig({
commands: [() => import("@adonisjs/core/commands")],
providers: [
() => import("@adonisjs/core/providers/app_provider"),
() => import("@adonisjs/core/providers/hash_provider"),
{
file: () => import("@adonisjs/core/providers/repl_provider"),
environment: ["repl", "test"],
},
() => import("@adonisjs/core/providers/vinejs_provider"),
() => import("@adonisjs/cors/cors_provider"),
],

preloads: [
() => import("@backend/start/routes.js"),
() => import("@backend/start/kernel.js"),
],

tests: {
suites: [
{
files: ["src/tests/**/*.spec.ts"],
name: "unit",
timeout: 2000,
},
],
forceExit: false,
},
});
12 changes: 12 additions & 0 deletions backend/src/app/exceptions/handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { HttpContext, ExceptionHandler } from "@adonisjs/core/http";
import app from "@adonisjs/core/services/app";

export default class HttpExceptionHandler extends ExceptionHandler {
protected override debug = !app.inProduction;
override async handle(error: unknown, ctx: HttpContext) {
return super.handle(error, ctx);
}
override async report(error: unknown, ctx: HttpContext) {
return super.report(error, ctx);
}
}
12 changes: 12 additions & 0 deletions backend/src/app/middleware/container_bindings_middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { HttpContext } from "@adonisjs/core/http";
import { Logger } from "@adonisjs/core/logger";
import type { NextFn } from "@adonisjs/core/types/http";

export default class ContainerBindingsMiddleware {
handle(ctx: HttpContext, next: NextFn) {
ctx.containerResolver.bindValue(HttpContext, ctx);
ctx.containerResolver.bindValue(Logger, ctx.logger);

return next();
}
}
11 changes: 11 additions & 0 deletions backend/src/app/middleware/force_json_response_middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { HttpContext } from "@adonisjs/core/http";
import type { NextFn } from "@adonisjs/core/types/http";

export default class ForceJsonResponseMiddleware {
async handle({ request }: HttpContext, next: NextFn) {
const headers = request.headers();
headers.accept = "application/json";

return next();
}
}
25 changes: 25 additions & 0 deletions backend/src/bin/console.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import "reflect-metadata";
import { Ignitor, prettyPrintError } from "@adonisjs/core";

const APP_ROOT = new URL("../", import.meta.url);
const IMPORTER = (filePath: string) => {
if (filePath.startsWith("./") || filePath.startsWith("../")) {
return import(new URL(filePath, APP_ROOT).href);
}
return import(filePath);
};

new Ignitor(APP_ROOT, { importer: IMPORTER })
.tap((app) => {
app.booting(async () => {
// await import("#start/env"); fixme migrate to adonis env
});
app.listen("SIGTERM", () => app.terminate());
app.listenIf(app.managedByPm2, "SIGINT", () => app.terminate());
})
.ace()
.handle(process.argv.splice(2))
.catch((error) => {
process.exitCode = 1;
prettyPrintError(error);
});
25 changes: 25 additions & 0 deletions backend/src/bin/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import "reflect-metadata";
import { Ignitor, prettyPrintError } from "@adonisjs/core";

const APP_ROOT = new URL("../", import.meta.url);
const IMPORTER = (filePath: string) => {
if (filePath.startsWith("./") || filePath.startsWith("../")) {
return import(new URL(filePath, APP_ROOT).href);
}
return import(filePath);
};

new Ignitor(APP_ROOT, { importer: IMPORTER })
.tap((app) => {
app.booting(async () => {
// await import("#start/env"); fixme migrate to AdonisJS env
});
app.listen("SIGTERM", () => app.terminate());
app.listenIf(app.managedByPm2, "SIGINT", () => app.terminate());
})
.httpServer()
.start()
.catch((error) => {
process.exitCode = 1;
prettyPrintError(error);
});
38 changes: 32 additions & 6 deletions backend/src/bin/test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,36 @@
import "reflect-metadata";
import { Ignitor, prettyPrintError } from "@adonisjs/core";
import { apiClient } from "@japa/api-client";
import { assert } from "@japa/assert";
import { pluginAdonisJS } from "@japa/plugin-adonisjs";
import { configure, processCLIArgs, run } from "@japa/runner";

processCLIArgs(process.argv.splice(2));
configure({
files: ["src/tests/**/*.spec.ts"],
plugins: [assert()],
});
const APP_ROOT = new URL("../", import.meta.url);
const IMPORTER = (filePath: string) => {
if (filePath.startsWith("./") || filePath.startsWith("../")) {
return import(new URL(filePath, APP_ROOT).href);
}
return import(filePath);
};

run();
new Ignitor(APP_ROOT, { importer: IMPORTER })
.tap((app) => {
app.booting(async () => {
// await import('#start/env') fixme migrate to Adonis Env
});
app.listen("SIGTERM", () => app.terminate());
app.listenIf(app.managedByPm2, "SIGINT", () => app.terminate());
})
.testRunner()
.configure(async (app) => {
processCLIArgs(process.argv.splice(2));
configure({
...app.rcFile.tests,
plugins: [assert(), apiClient(), pluginAdonisJS(app)],
});
})
.run(() => run())
.catch((error) => {
process.exitCode = 1;
prettyPrintError(error);
});
43 changes: 0 additions & 43 deletions backend/src/collections/bl-collections.ts

This file was deleted.

20 changes: 20 additions & 0 deletions backend/src/config/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Secret } from "@adonisjs/core/helpers";
import { defineConfig } from "@adonisjs/core/http";
import app from "@adonisjs/core/services/app";
import { BlEnv } from "@backend/express/config/env.js";

export const appKey = new Secret(BlEnv.APP_KEY);

export const http = defineConfig({
generateRequestId: true,
allowMethodSpoofing: false,
useAsyncLocalStorage: false,
cookie: {
domain: "",
path: "/",
maxAge: "2h",
httpOnly: true,
secure: app.inProduction,
sameSite: "lax",
},
});
27 changes: 27 additions & 0 deletions backend/src/config/bodyparser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { defineConfig } from "@adonisjs/core/bodyparser";

const bodyParserConfig = defineConfig({
allowedMethods: ["POST", "PUT", "PATCH", "DELETE"],
form: {
convertEmptyStringsToNull: true,
types: ["application/x-www-form-urlencoded"],
},
json: {
convertEmptyStringsToNull: true,
types: [
"application/json",
"application/json-patch+json",
"application/vnd.api+json",
"application/csp-report",
],
},
multipart: {
autoProcess: true,
convertEmptyStringsToNull: true,
processManually: [],
limit: "20mb",
types: ["multipart/form-data"],
},
});

export default bodyParserConfig;
13 changes: 13 additions & 0 deletions backend/src/config/cors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { defineConfig } from "@adonisjs/cors";

const corsConfig = defineConfig({
enabled: true,
origin: true,
methods: ["GET", "HEAD", "POST", "PUT", "DELETE"],
headers: true,
exposeHeaders: [],
credentials: true,
maxAge: 90,
});

export default corsConfig;
21 changes: 21 additions & 0 deletions backend/src/config/hash.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { defineConfig, drivers } from "@adonisjs/core/hash";

const hashConfig = defineConfig({
default: "scrypt",

list: {
scrypt: drivers.scrypt({
cost: 16384,
blockSize: 8,
parallelization: 1,
maxMemory: 33554432,
}),
},
});

export default hashConfig;

declare module "@adonisjs/core/types" {
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface HashersList extends InferHashers<typeof hashConfig> {}
}
27 changes: 27 additions & 0 deletions backend/src/config/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { defineConfig, targets } from "@adonisjs/core/logger";
import app from "@adonisjs/core/services/app";

const loggerConfig = defineConfig({
default: "app",

loggers: {
app: {
enabled: true,
name: "backend",
level: "debug",
transport: {
targets: targets()
.pushIf(!app.inProduction, targets.pretty())
.pushIf(app.inProduction, targets.file({ destination: 1 }))
.toArray(),
},
},
},
});

export default loggerConfig;

declare module "@adonisjs/core/types" {
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface LoggersList extends InferLoggers<typeof loggerConfig> {}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import BlCrypto from "@backend/express-config/bl-crypto.js";
import BlCrypto from "@backend/express/config/bl-crypto.js";
import { BlError } from "@shared/bl-error/bl-error.js";

function createUserBlid(provider: string, providerId: string): Promise<string> {
Expand Down
Loading

0 comments on commit 6dc1269

Please sign in to comment.