improve path handling and add flags section to config

This commit is contained in:
Milo Schwartz 2024-10-25 00:05:43 -04:00
parent ce19cc4ba4
commit 50e1a7abe1
No known key found for this signature in database
6 changed files with 42 additions and 25 deletions

2
.gitignore vendored
View file

@ -26,3 +26,5 @@ migrations
package-lock.json package-lock.json
tsconfig.tsbuildinfo tsconfig.tsbuildinfo
config.yml config.yml
dist
.dist

View file

@ -22,7 +22,8 @@ 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
COPY ./config/config.example.yml ./
COPY server/db/names.json /app/dist/names.json COPY ./config/config.example.yml ./dist/config.example.yml
COPY ./server/db/names.json ./dist/names.json
CMD ["npm", "start"] CMD ["npm", "start"]

View file

@ -3,6 +3,10 @@ import { fromError } from "zod-validation-error";
import path from "path"; import path from "path";
import fs from "fs"; import fs from "fs";
import yaml from "js-yaml"; import yaml from "js-yaml";
import { fileURLToPath } from "url";
export const __FILENAME = fileURLToPath(import.meta.url);
export const __DIRNAME = path.dirname(__FILENAME);
export const APP_PATH = path.join("config"); export const APP_PATH = path.join("config");
@ -37,6 +41,12 @@ const environmentSchema = z.object({
no_reply: z.string().email().optional(), no_reply: z.string().email().optional(),
}) })
.optional(), .optional(),
flags: z
.object({
allow_org_subdomain_changing: z.boolean().optional(),
require_email_verification: z.boolean().optional(),
})
.optional(),
}); });
const loadConfig = (configPath: string) => { const loadConfig = (configPath: string) => {
@ -64,7 +74,7 @@ if (fs.existsSync(configFilePath1)) {
environment = loadConfig(configFilePath2); environment = loadConfig(configFilePath2);
} }
if (!environment) { if (!environment) {
const exampleConfigPath = path.join("config.example.yml"); const exampleConfigPath = path.join(__DIRNAME, "config.example.yml");
if (fs.existsSync(exampleConfigPath)) { if (fs.existsSync(exampleConfigPath)) {
try { try {
const exampleConfigContent = fs.readFileSync( const exampleConfigContent = fs.readFileSync(

View file

@ -1,27 +1,26 @@
import { fileURLToPath } from 'url'; import { join } from "path";
import { dirname, join } from 'path'; import { readFileSync } from "fs";
import { readFileSync } from 'fs'; import { db } from "@server/db";
import { db } from '@server/db'; import { sites } from "./schema";
import { sites } from './schema'; import { eq, and } from "drizzle-orm";
import { eq, and } from 'drizzle-orm'; import { __DIRNAME } from "@server/config";
// Get the directory name of the current module
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Load the names from the names.json file // Load the names from the names.json file
const file = join(__dirname, 'names.json'); const file = join(__DIRNAME, "names.json");
export const names = JSON.parse(readFileSync(file, 'utf-8')); export const names = JSON.parse(readFileSync(file, "utf-8"));
export async function getUniqueName(orgId: string): Promise<string> { export async function getUniqueName(orgId: string): Promise<string> {
let loops = 0; let loops = 0;
while (true) { while (true) {
if (loops > 100) { if (loops > 100) {
throw new Error('Could not generate a unique name'); throw new Error("Could not generate a unique name");
} }
const name = generateName(); const name = generateName();
const count = await db.select({ niceId: sites.niceId, orgId: sites.orgId }).from(sites).where(and(eq(sites.niceId, name), eq(sites.orgId, orgId))); const count = await db
.select({ niceId: sites.niceId, orgId: sites.orgId })
.from(sites)
.where(and(eq(sites.niceId, name), eq(sites.orgId, orgId)));
if (count.length === 0) { if (count.length === 0) {
return name; return name;
} }
@ -31,7 +30,12 @@ export async function getUniqueName(orgId: string): Promise<string> {
export function generateName(): string { export function generateName(): string {
return ( return (
names.descriptors[Math.floor(Math.random() * names.descriptors.length)] + "-" + names.descriptors[
Math.floor(Math.random() * names.descriptors.length)
] +
"-" +
names.animals[Math.floor(Math.random() * names.animals.length)] names.animals[Math.floor(Math.random() * names.animals.length)]
).toLowerCase().replace(/\s/g, '-'); )
} .toLowerCase()
.replace(/\s/g, "-");
}

View file

@ -8,10 +8,10 @@ export const errorHandlerMiddleware: ErrorRequestHandler = (
error, error,
req, req,
res: Response<ErrorResponse>, res: Response<ErrorResponse>,
next: NextFunction, next: NextFunction
) => { ) => {
const statusCode = error.statusCode || HttpCode.INTERNAL_SERVER_ERROR; const statusCode = error.statusCode || HttpCode.INTERNAL_SERVER_ERROR;
if (config.app.environment !== "prod") { if (process.env.ENVIRONMENT !== "prod") {
logger.error(error); logger.error(error);
} }
res?.status(statusCode).send({ res?.status(statusCode).send({
@ -20,6 +20,6 @@ export const errorHandlerMiddleware: ErrorRequestHandler = (
error: true, error: true,
message: error.message || "Internal Server Error", message: error.message || "Internal Server Error",
status: statusCode, status: statusCode,
stack: config.app.environment === "prod" ? null : error.stack, stack: process.env.ENVIRONMENT === "prod" ? null : error.stack,
}); });
}; };

View file

@ -1,7 +1,7 @@
import axios from "axios"; import axios from "axios";
export const api = axios.create({ export const api = axios.create({
baseURL: "https://fossorial.io/api/v1", baseURL: process.env.NEXT_PUBLIC_EXTERNAL_API_BASE_URL,
timeout: 10000, timeout: 10000,
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@ -9,7 +9,7 @@ export const api = axios.create({
}); });
export const internal = axios.create({ export const internal = axios.create({
baseURL: "http://pangolin:3000/api/v1", baseURL: process.env.NEXT_PUBLIC_INTERNAL_API_BASE_URL,
timeout: 10000, timeout: 10000,
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",