mirror of
https://github.com/fosrl/pangolin.git
synced 2025-07-12 23:15:00 +02:00
disable helmet and add esbuild
This commit is contained in:
parent
282203d9f2
commit
3c69acaab7
12 changed files with 139 additions and 68 deletions
|
@ -23,3 +23,4 @@ next-env.d.ts
|
||||||
.machinelogs*.json
|
.machinelogs*.json
|
||||||
*-audit.json
|
*-audit.json
|
||||||
config
|
config
|
||||||
|
package-lock.json
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -24,3 +24,4 @@ next-env.d.ts
|
||||||
*-audit.json
|
*-audit.json
|
||||||
migrations
|
migrations
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
tsconfig.tsbuildinfo
|
||||||
|
|
|
@ -2,9 +2,9 @@ FROM node:20-alpine AS builder
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY package*.json ./
|
COPY package.json ./
|
||||||
|
|
||||||
RUN npm ci
|
RUN npm install
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
|
@ -16,9 +16,9 @@ RUN apk add --no-cache curl
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY package*.json ./
|
COPY package.json ./
|
||||||
|
|
||||||
RUN npm ci --only=production
|
RUN npm install --omit=dev
|
||||||
|
|
||||||
COPY --from=builder /app/.next ./.next
|
COPY --from=builder /app/.next ./.next
|
||||||
COPY --from=builder /app/dist ./dist
|
COPY --from=builder /app/dist ./dist
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -3,7 +3,7 @@ all:
|
||||||
docker build -t pangolin .
|
docker build -t pangolin .
|
||||||
|
|
||||||
test:
|
test:
|
||||||
docker run -it -p 3000:3000 -p 3001:3001 --env-file=.env-docker -v ./config:/config pangolin
|
docker run -it -p 3000:3000 -p 3001:3001 --env-file=.env -v ./config:/app/config pangolin
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
docker rmi pangolin
|
docker rmi pangolin
|
12
package.json
12
package.json
|
@ -2,17 +2,19 @@
|
||||||
"name": "@fossorial/pangolin",
|
"name": "@fossorial/pangolin",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "dotenvx run -- tsx watch server/index.ts",
|
"dev": "dotenvx run -- tsx watch server/index.ts",
|
||||||
"db:generate": "drizzle-kit generate",
|
"db:generate": "drizzle-kit generate",
|
||||||
"db:push": "npx tsx server/db/migrate.ts",
|
"db:push": "npx tsx server/db/migrate.ts",
|
||||||
"db:hydrate": "npx tsx scripts/hydrate.ts",
|
"db:hydrate": "npx tsx scripts/hydrate.ts",
|
||||||
"db:studio": "drizzle-kit studio",
|
"db:studio": "drizzle-kit studio",
|
||||||
"build": "next build && tsc --project tsconfig.json && tsc-alias -p tsconfig.json",
|
"build": "mkdir -p dist && next build && node scripts/esbuild.mjs -e server/index.ts -o dist/server.mjs",
|
||||||
"start": "ENVIRONMENT=prod node dist/server/index.js",
|
"start": "ENVIRONMENT=prod node dist/server.mjs",
|
||||||
"email": "email dev --dir server/emails/templates --port 3002"
|
"email": "email dev --dir server/emails/templates --port 3002"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@esbuild-plugins/tsconfig-paths": "0.1.2",
|
||||||
"@hookform/resolvers": "3.9.0",
|
"@hookform/resolvers": "3.9.0",
|
||||||
"@lucia-auth/adapter-drizzle": "1.1.0",
|
"@lucia-auth/adapter-drizzle": "1.1.0",
|
||||||
"@node-rs/argon2": "1.8.3",
|
"@node-rs/argon2": "1.8.3",
|
||||||
|
@ -28,8 +30,11 @@
|
||||||
"cookie-parser": "1.4.6",
|
"cookie-parser": "1.4.6",
|
||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"drizzle-orm": "0.33.0",
|
"drizzle-orm": "0.33.0",
|
||||||
|
"esbuild": "0.20.1",
|
||||||
|
"esbuild-node-externals": "1.13.0",
|
||||||
"express": "4.21.0",
|
"express": "4.21.0",
|
||||||
"express-rate-limit": "7.4.0",
|
"express-rate-limit": "7.4.0",
|
||||||
|
"glob": "11.0.0",
|
||||||
"helmet": "7.1.0",
|
"helmet": "7.1.0",
|
||||||
"http-errors": "2.0.0",
|
"http-errors": "2.0.0",
|
||||||
"lucia": "3.2.0",
|
"lucia": "3.2.0",
|
||||||
|
@ -41,10 +46,12 @@
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"react-hook-form": "7.53.0",
|
"react-hook-form": "7.53.0",
|
||||||
|
"rebuild": "0.1.2",
|
||||||
"tailwind-merge": "2.5.3",
|
"tailwind-merge": "2.5.3",
|
||||||
"tailwindcss-animate": "1.0.7",
|
"tailwindcss-animate": "1.0.7",
|
||||||
"winston": "3.14.2",
|
"winston": "3.14.2",
|
||||||
"winston-daily-rotate-file": "5.0.0",
|
"winston-daily-rotate-file": "5.0.0",
|
||||||
|
"yargs": "17.7.2",
|
||||||
"zod": "3.23.8",
|
"zod": "3.23.8",
|
||||||
"zod-validation-error": "3.4.0"
|
"zod-validation-error": "3.4.0"
|
||||||
},
|
},
|
||||||
|
@ -58,6 +65,7 @@
|
||||||
"@types/nodemailer": "6.4.16",
|
"@types/nodemailer": "6.4.16",
|
||||||
"@types/react": "^18",
|
"@types/react": "^18",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18",
|
||||||
|
"@types/yargs": "17.0.33",
|
||||||
"drizzle-kit": "0.24.2",
|
"drizzle-kit": "0.24.2",
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"eslint-config-next": "14.2.13",
|
"eslint-config-next": "14.2.13",
|
||||||
|
|
74
scripts/esbuild.mjs
Normal file
74
scripts/esbuild.mjs
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
import esbuild from "esbuild";
|
||||||
|
import yargs from "yargs";
|
||||||
|
import { hideBin } from "yargs/helpers";
|
||||||
|
import { nodeExternalsPlugin } from "esbuild-node-externals";
|
||||||
|
// import { glob } from "glob";
|
||||||
|
// import path from "path";
|
||||||
|
|
||||||
|
const banner = `
|
||||||
|
// patch __dirname
|
||||||
|
// import { fileURLToPath } from "url";
|
||||||
|
// import path from "path";
|
||||||
|
// const __filename = fileURLToPath(import.meta.url);
|
||||||
|
// const __dirname = path.dirname(__filename);
|
||||||
|
|
||||||
|
// allow top level await
|
||||||
|
import { createRequire as topLevelCreateRequire } from "module";
|
||||||
|
const require = topLevelCreateRequire(import.meta.url);
|
||||||
|
`;
|
||||||
|
|
||||||
|
const argv = yargs(hideBin(process.argv))
|
||||||
|
.usage("Usage: $0 -entry [string] -out [string]")
|
||||||
|
.option("entry", {
|
||||||
|
alias: "e",
|
||||||
|
describe: "Entry point file",
|
||||||
|
type: "string",
|
||||||
|
demandOption: true,
|
||||||
|
})
|
||||||
|
.option("out", {
|
||||||
|
alias: "o",
|
||||||
|
describe: "Output file path",
|
||||||
|
type: "string",
|
||||||
|
demandOption: true,
|
||||||
|
})
|
||||||
|
.help()
|
||||||
|
.alias("help", "h").argv;
|
||||||
|
|
||||||
|
// generate a list of all package.json files in the monorepo
|
||||||
|
function getPackagePaths() {
|
||||||
|
// const packagePaths = [];
|
||||||
|
// const packageGlob = "package.json";
|
||||||
|
// const packageJsonFiles = glob.sync(packageGlob);
|
||||||
|
// for (const packageJsonFile of packageJsonFiles) {
|
||||||
|
// packagePaths.push(path.dirname(packageJsonFile) + "/package.json");
|
||||||
|
// }
|
||||||
|
// return packagePaths;
|
||||||
|
return ["package.json"];
|
||||||
|
}
|
||||||
|
|
||||||
|
esbuild
|
||||||
|
.build({
|
||||||
|
entryPoints: [argv.entry],
|
||||||
|
bundle: true,
|
||||||
|
outfile: argv.out,
|
||||||
|
format: "esm",
|
||||||
|
banner: {
|
||||||
|
js: banner,
|
||||||
|
},
|
||||||
|
platform: "node",
|
||||||
|
external: ["body-parser"],
|
||||||
|
plugins: [
|
||||||
|
nodeExternalsPlugin({
|
||||||
|
packagePath: getPackagePaths(),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
sourcemap: false,
|
||||||
|
target: "node20",
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
console.log("Build completed successfully");
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Build failed:", error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
|
@ -4,9 +4,9 @@ import * as schema from "@server/db/schema";
|
||||||
import environment from "@server/environment";
|
import environment from "@server/environment";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
||||||
const sqlite = new Database(
|
const location = path.join(environment.CONFIG_PATH, "db", "db.sqlite");
|
||||||
path.join(environment.CONFIG_PATH, "db", "db.sqlite"),
|
|
||||||
);
|
const sqlite = new Database(location);
|
||||||
export const db = drizzle(sqlite, { schema });
|
export const db = drizzle(sqlite, { schema });
|
||||||
|
|
||||||
export default db;
|
export default db;
|
||||||
|
|
|
@ -26,7 +26,7 @@ app.prepare().then(() => {
|
||||||
// External server
|
// External server
|
||||||
const externalServer = express();
|
const externalServer = express();
|
||||||
|
|
||||||
externalServer.use(helmet());
|
// externalServer.use(helmet()); // Disabled because causes issues with Next.js
|
||||||
externalServer.use(cors());
|
externalServer.use(cors());
|
||||||
externalServer.use(cookieParser());
|
externalServer.use(cookieParser());
|
||||||
externalServer.use(express.json());
|
externalServer.use(express.json());
|
||||||
|
|
|
@ -3,47 +3,47 @@
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
@layer base {
|
@layer base {
|
||||||
:root {
|
:root {
|
||||||
--background: 30 21% 95%;
|
--background: 28.4 100% 100%;
|
||||||
--foreground: 30 5% 10%;
|
--foreground: 28.4 5% 10%;
|
||||||
--card: 30 21% 90%;
|
--card: 28.4 50% 100%;
|
||||||
--card-foreground: 30 5% 15%;
|
--card-foreground: 28.4 5% 15%;
|
||||||
--popover: 30 21% 95%;
|
--popover: 28.4 100% 100%;
|
||||||
--popover-foreground: 30 95% 10%;
|
--popover-foreground: 28.4 100% 10%;
|
||||||
--primary: 30 22% 47%;
|
--primary: 28.4 72.5% 25.7%;
|
||||||
--primary-foreground: 0 0% 100%;
|
--primary-foreground: 0 0% 100%;
|
||||||
--secondary: 30 21% 72%;
|
--secondary: 28.4 30% 90%;
|
||||||
--secondary-foreground: 0 0% 0%;
|
--secondary-foreground: 0 0% 0%;
|
||||||
--muted: -8 21% 85%;
|
--muted: -9.600000000000001 30% 95%;
|
||||||
--muted-foreground: 30 5% 40%;
|
--muted-foreground: 28.4 5% 40%;
|
||||||
--accent: -8 21% 80%;
|
--accent: -9.600000000000001 30% 90%;
|
||||||
--accent-foreground: 30 5% 15%;
|
--accent-foreground: 28.4 5% 15%;
|
||||||
--destructive: 0 50% 50%;
|
--destructive: 0 100% 50%;
|
||||||
--destructive-foreground: 30 5% 90%;
|
--destructive-foreground: 28.4 5% 100%;
|
||||||
--border: 30 21% 72%;
|
--border: 28.4 30% 82%;
|
||||||
--input: 30 21% 50%;
|
--input: 28.4 30% 50%;
|
||||||
--ring: 30 22% 47%;
|
--ring: 28.4 72.5% 25.7%;
|
||||||
--radius: 0rem;
|
--radius: 0rem;
|
||||||
}
|
}
|
||||||
.dark {
|
.dark {
|
||||||
--background: 30 21% 10%;
|
--background: 28.4 50% 10%;
|
||||||
--foreground: 30 5% 90%;
|
--foreground: 28.4 5% 100%;
|
||||||
--card: 30 21% 10%;
|
--card: 28.4 50% 10%;
|
||||||
--card-foreground: 30 5% 90%;
|
--card-foreground: 28.4 5% 100%;
|
||||||
--popover: 30 21% 5%;
|
--popover: 28.4 50% 5%;
|
||||||
--popover-foreground: 30 5% 90%;
|
--popover-foreground: 28.4 5% 100%;
|
||||||
--primary: 30 22% 47%;
|
--primary: 28.4 72.5% 25.7%;
|
||||||
--primary-foreground: 0 0% 100%;
|
--primary-foreground: 0 0% 100%;
|
||||||
--secondary: 30 21% 20%;
|
--secondary: 28.4 30% 20%;
|
||||||
--secondary-foreground: 0 0% 100%;
|
--secondary-foreground: 0 0% 100%;
|
||||||
--muted: -8 21% 25%;
|
--muted: -9.600000000000001 30% 25%;
|
||||||
--muted-foreground: 30 5% 65%;
|
--muted-foreground: 28.4 5% 65%;
|
||||||
--accent: -8 21% 25%;
|
--accent: -9.600000000000001 30% 25%;
|
||||||
--accent-foreground: 30 5% 90%;
|
--accent-foreground: 28.4 5% 95%;
|
||||||
--destructive: 0 50% 50%;
|
--destructive: 0 100% 50%;
|
||||||
--destructive-foreground: 30 5% 90%;
|
--destructive-foreground: 28.4 5% 100%;
|
||||||
--border: 30 21% 50%;
|
--border: 28.4 30% 50%;
|
||||||
--input: 30 21% 50%;
|
--input: 28.4 30% 50%;
|
||||||
--ring: 30 22% 47%;
|
--ring: 28.4 72.5% 25.7%;
|
||||||
--radius: 0rem;
|
--radius: 0rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,24 @@
|
||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
import { Noto_Sans } from "next/font/google";
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Pangolin",
|
title: "Pangolin",
|
||||||
description: "",
|
description: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const inter = Noto_Sans({ subsets: ["latin"] });
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}>) {
|
}>) {
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html>
|
||||||
<body>{children}</body>
|
<body className={`${inter.className}`}>
|
||||||
|
<main>{children}</main>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return <></>;
|
||||||
<>
|
|
||||||
<h1>Hello world</h1>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
{
|
|
||||||
"extends": "./tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "ES2020",
|
|
||||||
"module": "commonjs",
|
|
||||||
"outDir": "./dist",
|
|
||||||
"noEmit": false,
|
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
|
||||||
"@server/*": ["./server/*"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"include": ["**/*.ts"]
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue