mirror of
https://github.com/kyantech/Palmr.git
synced 2025-10-22 22:02:00 +00:00
feat: enhance pre-push validation and update ESLint configurations
- Updated the Husky pre-push hook to validate all applications (web, docs, and server) before pushing changes, improving code quality checks. - Modified ESLint configurations for the docs app to include additional ignored directories, ensuring cleaner linting results. - Refactored the HomePage component in the docs app to improve structure and readability, while reintroducing the Highlight component for better content presentation. - Added a .prettierignore file in the server app to exclude specific directories from formatting, enhancing development workflow. - Updated various import statements across multiple files for consistency and clarity.
This commit is contained in:
@@ -1,2 +1,12 @@
|
||||
echo "🔍 Running pre-push validation for web app..."
|
||||
cd apps/web && pnpm validate
|
||||
echo "🔍 Running pre-push validation for all apps..."
|
||||
|
||||
echo "📱 Validating web app..."
|
||||
cd apps/web && pnpm validate
|
||||
|
||||
echo "📚 Validating docs app..."
|
||||
cd ../docs && pnpm validate
|
||||
|
||||
echo "🖥️ Validating server app..."
|
||||
cd ../server && pnpm validate
|
||||
|
||||
echo "✅ All validations passed!"
|
@@ -62,6 +62,6 @@ export default [
|
||||
},
|
||||
// Ignore ESLint errors in @/ui directory
|
||||
{
|
||||
ignores: ["src/components/ui/**/*"],
|
||||
ignores: ["src/components/ui/**/*", "src/components/magicui/**/*"],
|
||||
},
|
||||
];
|
||||
|
@@ -59,23 +59,6 @@ const images = [
|
||||
|
||||
const docsLink = "/docs/3.1-beta";
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<>
|
||||
<main className="relative z-[2] w-full px-4 py-6 sm:px-6 lg:px-8">
|
||||
<div className="relative mx-auto max-w-screen-xl bg-background">
|
||||
<Hero />
|
||||
<LogoShowcase />
|
||||
<Feedback />
|
||||
<Features />
|
||||
<GetStarted />
|
||||
</div>
|
||||
</main>
|
||||
<FullWidthFooter />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function Hero() {
|
||||
return (
|
||||
<section className="relative z-[2] flex flex-col border-x border-t px-6 pt-12 pb-10 md:px-12 md:pt-16 max-md:text-center">
|
||||
@@ -136,6 +119,18 @@ function Feedback() {
|
||||
);
|
||||
}
|
||||
|
||||
function Highlight({ icon: Icon, heading, children }: { icon: LucideIcon; heading: ReactNode; children: ReactNode }) {
|
||||
return (
|
||||
<div className="border-l border-t px-6 py-12">
|
||||
<div className="mb-4 flex items-center gap-2 text-fd-muted-foreground">
|
||||
<Icon className="size-6" />
|
||||
<h2 className="text-sm font-medium">{heading}</h2>
|
||||
</div>
|
||||
<span className="font-medium">{children}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Features() {
|
||||
return (
|
||||
<>
|
||||
@@ -218,18 +213,6 @@ function Features() {
|
||||
);
|
||||
}
|
||||
|
||||
function Highlight({ icon: Icon, heading, children }: { icon: LucideIcon; heading: ReactNode; children: ReactNode }) {
|
||||
return (
|
||||
<div className="border-l border-t px-6 py-12">
|
||||
<div className="mb-4 flex items-center gap-2 text-fd-muted-foreground">
|
||||
<Icon className="size-6" />
|
||||
<h2 className="text-sm font-medium">{heading}</h2>
|
||||
</div>
|
||||
<span className="font-medium">{children}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function GetStarted() {
|
||||
return (
|
||||
<section className="flex w-full flex-1">
|
||||
@@ -321,3 +304,20 @@ function FullWidthFooter() {
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<>
|
||||
<main className="relative z-[2] w-full px-4 py-6 sm:px-6 lg:px-8">
|
||||
<div className="relative mx-auto max-w-screen-xl bg-background">
|
||||
<Hero />
|
||||
<LogoShowcase />
|
||||
<Feedback />
|
||||
<Features />
|
||||
<GetStarted />
|
||||
</div>
|
||||
</main>
|
||||
<FullWidthFooter />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
6
apps/server/.prettierignore
Normal file
6
apps/server/.prettierignore
Normal file
@@ -0,0 +1,6 @@
|
||||
/node_modules
|
||||
/dist
|
||||
/build
|
||||
/uploads
|
||||
/temp-chunks
|
||||
/prisma/migrations
|
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"plugins": ["@trivago/prettier-plugin-sort-imports"],
|
||||
"importOrder": ["<THIRD_PARTY_MODULES>", "", "^@/(.*)$", "^[./]"],
|
||||
"importOrderParserPlugins": ["typescript", "jsx", "decorators-legacy"],
|
||||
"plugins": ["@ianvs/prettier-plugin-sort-imports", "prettier-plugin-sort-json"],
|
||||
"printWidth": 120,
|
||||
"singleQuote": false,
|
||||
"tabWidth": 2,
|
||||
|
@@ -1,24 +1,45 @@
|
||||
import pluginJs from "@eslint/js";
|
||||
import eslintConfigPrettier from "eslint-config-prettier";
|
||||
import importPlugin from "eslint-plugin-import";
|
||||
import globals from "globals";
|
||||
import tseslint from "typescript-eslint";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { FlatCompat } from "@eslint/eslintrc";
|
||||
import js from "@eslint/js";
|
||||
import typescriptEslintEslintPlugin from "@typescript-eslint/eslint-plugin";
|
||||
import tsParser from "@typescript-eslint/parser";
|
||||
import prettier from "eslint-plugin-prettier";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname,
|
||||
recommendedConfig: js.configs.recommended,
|
||||
allConfig: js.configs.all,
|
||||
});
|
||||
|
||||
/** @type {import('eslint').Linter.Config[]} */
|
||||
export default [
|
||||
{ files: ["**/*.{js,mjs,cjs,ts}"] },
|
||||
{ languageOptions: { globals: globals.browser } },
|
||||
pluginJs.configs.recommended,
|
||||
importPlugin.flatConfigs.recommended,
|
||||
eslintConfigPrettier,
|
||||
...tseslint.configs.recommended,
|
||||
...compat.extends("prettier"),
|
||||
{
|
||||
plugins: {
|
||||
prettier,
|
||||
},
|
||||
rules: {
|
||||
"import/no-unresolved": "off",
|
||||
"import/no-named-as-default": "off",
|
||||
"@typescript-eslint/no-unused-vars": "warn",
|
||||
"prettier/prettier": "error",
|
||||
camelcase: "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["**/*.+(ts|tsx)"],
|
||||
plugins: {
|
||||
"@typescript-eslint": typescriptEslintEslintPlugin,
|
||||
},
|
||||
languageOptions: {
|
||||
parser: tsParser,
|
||||
},
|
||||
rules: {
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||
"no-use-before-define": [0],
|
||||
"@typescript-eslint/no-use-before-define": [1],
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-require-imports": "off",
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
@@ -19,10 +19,12 @@
|
||||
"dev": "tsx watch src/server.ts",
|
||||
"build": "tsc -p tsconfig.json",
|
||||
"start": "node dist/server.js",
|
||||
"lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"",
|
||||
"lint:fix": "eslint \"src/**/*.{js,jsx,ts,tsx}\" --fix",
|
||||
"lint": "eslint \"src/**/*.+(ts|tsx)\"",
|
||||
"lint:fix": "eslint \"src/**/*.+(ts|tsx)\" --fix",
|
||||
"format": "prettier . --write",
|
||||
"format:check": "prettier . --check",
|
||||
"type-check": "npx tsc --noEmit",
|
||||
"validate": "pnpm format && pnpm lint:fix && pnpm type-check",
|
||||
"db:seed": "ts-node prisma/seed.js"
|
||||
},
|
||||
"prisma": {
|
||||
@@ -53,20 +55,22 @@
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.19.0",
|
||||
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
||||
"@eslint/eslintrc": "3.3.1",
|
||||
"@eslint/js": "9.30.0",
|
||||
"@ianvs/prettier-plugin-sort-imports": "4.4.2",
|
||||
"@types/bcryptjs": "^2.4.6",
|
||||
"@types/node": "^22.13.4",
|
||||
"@types/nodemailer": "^6.4.17",
|
||||
"eslint": "^9.19.0",
|
||||
"eslint-config-prettier": "^10.0.1",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"globals": "^15.14.0",
|
||||
"prettier": "3.4.2",
|
||||
"@typescript-eslint/eslint-plugin": "8.35.1",
|
||||
"@typescript-eslint/parser": "8.35.1",
|
||||
"eslint": "9.30.0",
|
||||
"eslint-config-prettier": "9.1.0",
|
||||
"eslint-plugin-prettier": "5.5.1",
|
||||
"prettier": "3.6.2",
|
||||
"prettier-plugin-sort-json": "4.1.1",
|
||||
"prisma": "^6.3.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "^5.7.3",
|
||||
"typescript-eslint": "^8.23.0"
|
||||
"typescript": "^5.7.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
5559
apps/server/pnpm-lock.yaml
generated
5559
apps/server/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable no-undef */
|
||||
const { PrismaClient } = require('@prisma/client');
|
||||
const crypto = require('crypto');
|
||||
const { PrismaClient } = require("@prisma/client");
|
||||
const crypto = require("crypto");
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
@@ -147,7 +147,7 @@ const defaultConfigs = [
|
||||
value: "http://localhost:3333",
|
||||
type: "string",
|
||||
group: "general",
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
const defaultAuthProviders = [
|
||||
@@ -167,8 +167,8 @@ const defaultAuthProviders = [
|
||||
description: "Sign in with your Google account",
|
||||
docs: "https://developers.google.com/identity/protocols/oauth2",
|
||||
supportsDiscovery: true,
|
||||
authMethod: "body"
|
||||
})
|
||||
authMethod: "body",
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "discord",
|
||||
@@ -186,8 +186,8 @@ const defaultAuthProviders = [
|
||||
description: "Sign in with your Discord account",
|
||||
docs: "https://discord.com/developers/docs/topics/oauth2",
|
||||
supportsDiscovery: false,
|
||||
authMethod: "body"
|
||||
})
|
||||
authMethod: "body",
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "github",
|
||||
@@ -204,8 +204,8 @@ const defaultAuthProviders = [
|
||||
metadata: JSON.stringify({
|
||||
description: "Sign in with your GitHub account",
|
||||
docs: "https://docs.github.com/en/developers/apps/building-oauth-apps",
|
||||
specialHandling: "email_fetch_required"
|
||||
})
|
||||
specialHandling: "email_fetch_required",
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "auth0",
|
||||
@@ -222,8 +222,8 @@ const defaultAuthProviders = [
|
||||
metadata: JSON.stringify({
|
||||
description: "Sign in with Auth0 - Replace 'your-tenant' with your Auth0 domain",
|
||||
docs: "https://auth0.com/docs/get-started/authentication-and-authorization-flow",
|
||||
supportsDiscovery: true
|
||||
})
|
||||
supportsDiscovery: true,
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "kinde",
|
||||
@@ -240,8 +240,8 @@ const defaultAuthProviders = [
|
||||
metadata: JSON.stringify({
|
||||
description: "Sign in with Kinde - Replace 'your-tenant' with your Kinde domain",
|
||||
docs: "https://kinde.com/docs/developer-tools/about/",
|
||||
supportsDiscovery: true
|
||||
})
|
||||
supportsDiscovery: true,
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "zitadel",
|
||||
@@ -259,8 +259,8 @@ const defaultAuthProviders = [
|
||||
description: "Sign in with Zitadel - Replace with your Zitadel instance URL",
|
||||
docs: "https://zitadel.com/docs/guides/integrate/login/oidc",
|
||||
supportsDiscovery: true,
|
||||
authMethod: "basic"
|
||||
})
|
||||
authMethod: "basic",
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "authentik",
|
||||
@@ -277,8 +277,8 @@ const defaultAuthProviders = [
|
||||
metadata: JSON.stringify({
|
||||
description: "Sign in with Authentik - Replace with your Authentik instance URL",
|
||||
docs: "https://goauthentik.io/docs/providers/oauth2",
|
||||
supportsDiscovery: true
|
||||
})
|
||||
supportsDiscovery: true,
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "frontegg",
|
||||
@@ -295,8 +295,8 @@ const defaultAuthProviders = [
|
||||
metadata: JSON.stringify({
|
||||
description: "Sign in with Frontegg - Replace 'your-tenant' with your Frontegg tenant",
|
||||
docs: "https://docs.frontegg.com",
|
||||
supportsDiscovery: true
|
||||
})
|
||||
supportsDiscovery: true,
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -370,4 +370,4 @@ main()
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
});
|
||||
|
@@ -1,13 +1,14 @@
|
||||
import { registerSwagger } from "./config/swagger.config";
|
||||
import { envTimeoutOverrides } from "./config/timeout.config";
|
||||
import { prisma } from "./shared/prisma";
|
||||
import crypto from "node:crypto";
|
||||
import fastifyCookie from "@fastify/cookie";
|
||||
import { fastifyCors } from "@fastify/cors";
|
||||
import fastifyJwt from "@fastify/jwt";
|
||||
import { fastifySwaggerUi } from "@fastify/swagger-ui";
|
||||
import { fastify } from "fastify";
|
||||
import { validatorCompiler, serializerCompiler, ZodTypeProvider } from "fastify-type-provider-zod";
|
||||
import crypto from "node:crypto";
|
||||
import { serializerCompiler, validatorCompiler, ZodTypeProvider } from "fastify-type-provider-zod";
|
||||
|
||||
import { registerSwagger } from "./config/swagger.config";
|
||||
import { envTimeoutOverrides } from "./config/timeout.config";
|
||||
import { prisma } from "./shared/prisma";
|
||||
|
||||
export async function buildApp() {
|
||||
const jwtConfig = await prisma.appConfig.findUnique({
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { S3Client } from "@aws-sdk/client-s3";
|
||||
|
||||
import { env } from "../env";
|
||||
import { StorageConfig } from "../types/storage";
|
||||
import { S3Client } from "@aws-sdk/client-s3";
|
||||
|
||||
export const storageConfig: StorageConfig = {
|
||||
endpoint: env.S3_ENDPOINT || "",
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
|
||||
import { EmailService } from "../email/service";
|
||||
import { LogoService } from "./logo.service";
|
||||
import { AppService } from "./service";
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
const isDocker = (() => {
|
||||
try {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { prisma } from "../../shared/prisma";
|
||||
import sharp from "sharp";
|
||||
|
||||
import { prisma } from "../../shared/prisma";
|
||||
|
||||
export class LogoService {
|
||||
async uploadLogo(buffer: Buffer): Promise<string> {
|
||||
try {
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import { prisma } from "../../shared/prisma";
|
||||
import { AppController } from "./controller";
|
||||
import { ConfigResponseSchema, BulkUpdateConfigSchema } from "./dto";
|
||||
import { FastifyInstance } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
import { prisma } from "../../shared/prisma";
|
||||
import { AppController } from "./controller";
|
||||
import { BulkUpdateConfigSchema, ConfigResponseSchema } from "./dto";
|
||||
|
||||
export async function appRoutes(app: FastifyInstance) {
|
||||
const appController = new AppController();
|
||||
|
||||
|
@@ -1,3 +1,5 @@
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
|
||||
import { UpdateAuthProviderSchema } from "./dto";
|
||||
import { AuthProvidersService } from "./service";
|
||||
import {
|
||||
@@ -9,7 +11,6 @@ import {
|
||||
UpdateProviderRequest,
|
||||
UpdateProvidersOrderRequest,
|
||||
} from "./types";
|
||||
import { FastifyRequest, FastifyReply } from "fastify";
|
||||
|
||||
const COOKIE_MAX_AGE = 7 * 24 * 60 * 60 * 1000;
|
||||
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import { FastifyInstance } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
import { prisma } from "../../shared/prisma";
|
||||
import { AuthProvidersController } from "./controller";
|
||||
import { CreateAuthProviderSchema, UpdateProvidersOrderSchema } from "./dto";
|
||||
import { FastifyInstance } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
export async function authProvidersRoutes(fastify: FastifyInstance) {
|
||||
const authProvidersController = new AuthProvidersController();
|
||||
|
@@ -1,21 +1,22 @@
|
||||
import crypto from "crypto";
|
||||
|
||||
import { prisma } from "../../shared/prisma";
|
||||
import {
|
||||
providersConfig,
|
||||
detectProviderType,
|
||||
getProviderScopes,
|
||||
shouldSupportDiscovery,
|
||||
getFallbackEndpoints,
|
||||
DISCOVERY_PATHS,
|
||||
getFallbackEndpoints,
|
||||
getProviderScopes,
|
||||
providersConfig,
|
||||
shouldSupportDiscovery,
|
||||
} from "./providers.config";
|
||||
import {
|
||||
ProviderConfig,
|
||||
ProviderUserInfo,
|
||||
TokenResponse,
|
||||
ProviderEndpoints,
|
||||
RequestContextService,
|
||||
PendingState,
|
||||
ProviderConfig,
|
||||
ProviderEndpoints,
|
||||
ProviderUserInfo,
|
||||
RequestContextService,
|
||||
TokenResponse,
|
||||
} from "./types";
|
||||
import crypto from "crypto";
|
||||
|
||||
// Constants
|
||||
const DEFAULT_BASE_URL = "http://localhost:3000";
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import { env } from "../../env";
|
||||
import { LoginSchema, RequestPasswordResetSchema, createResetPasswordSchema } from "./dto";
|
||||
import { AuthService } from "./service";
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
|
||||
import { env } from "../../env";
|
||||
import { createResetPasswordSchema, LoginSchema, RequestPasswordResetSchema } from "./dto";
|
||||
import { AuthService } from "./service";
|
||||
|
||||
export class AuthController {
|
||||
private authService = new AuthService();
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { ConfigService } from "../config/service";
|
||||
import { z } from "zod";
|
||||
|
||||
import { ConfigService } from "../config/service";
|
||||
|
||||
const configService = new ConfigService();
|
||||
|
||||
export const createPasswordSchema = async () => {
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
import { ConfigService } from "../config/service";
|
||||
import { validatePasswordMiddleware } from "../user/middleware";
|
||||
import { AuthController } from "./controller";
|
||||
import { RequestPasswordResetSchema, createResetPasswordSchema } from "./dto";
|
||||
import { FastifyInstance, FastifyRequest, FastifyReply } from "fastify";
|
||||
import { z } from "zod";
|
||||
import { createResetPasswordSchema, RequestPasswordResetSchema } from "./dto";
|
||||
|
||||
const configService = new ConfigService();
|
||||
|
||||
|
@@ -1,11 +1,12 @@
|
||||
import crypto from "node:crypto";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
import { prisma } from "../../shared/prisma";
|
||||
import { ConfigService } from "../config/service";
|
||||
import { EmailService } from "../email/service";
|
||||
import { UserResponseSchema } from "../user/dto";
|
||||
import { PrismaUserRepository } from "../user/repository";
|
||||
import { LoginInput } from "./dto";
|
||||
import bcrypt from "bcryptjs";
|
||||
import crypto from "node:crypto";
|
||||
|
||||
export class AuthService {
|
||||
private userRepository = new PrismaUserRepository();
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { ConfigService } from "../config/service";
|
||||
import nodemailer from "nodemailer";
|
||||
|
||||
import { ConfigService } from "../config/service";
|
||||
|
||||
interface SmtpConfig {
|
||||
smtpEnabled: string;
|
||||
smtpHost: string;
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
|
||||
import { prisma } from "../../shared/prisma";
|
||||
import { ConfigService } from "../config/service";
|
||||
import { RegisterFileSchema, RegisterFileInput, UpdateFileSchema, CheckFileInput, CheckFileSchema } from "./dto";
|
||||
import { CheckFileInput, CheckFileSchema, RegisterFileInput, RegisterFileSchema, UpdateFileSchema } from "./dto";
|
||||
import { FileService } from "./service";
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
|
||||
export class FileController {
|
||||
private fileService = new FileService();
|
||||
|
@@ -1,7 +1,8 @@
|
||||
import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
import { FileController } from "./controller";
|
||||
import { CheckFileSchema, RegisterFileSchema, UpdateFileSchema } from "./dto";
|
||||
import { FastifyInstance, FastifyRequest, FastifyReply } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
export async function fileRoutes(app: FastifyInstance) {
|
||||
const fileController = new FileController();
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import { FilesystemStorageProvider } from "../../providers/filesystem-storage.provider";
|
||||
import { FileService } from "../file/service";
|
||||
import { FastifyRequest, FastifyReply } from "fastify";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import { pipeline } from "stream/promises";
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
|
||||
import { FilesystemStorageProvider } from "../../providers/filesystem-storage.provider";
|
||||
import { FileService } from "../file/service";
|
||||
|
||||
export class FilesystemController {
|
||||
private fileService = new FileService();
|
||||
|
@@ -1,7 +1,8 @@
|
||||
import { FilesystemController } from "./controller";
|
||||
import { FastifyInstance, FastifyRequest } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
import { FilesystemController } from "./controller";
|
||||
|
||||
export async function filesystemRoutes(app: FastifyInstance) {
|
||||
const filesystemController = new FilesystemController();
|
||||
|
||||
|
@@ -1,7 +1,8 @@
|
||||
import { HealthController } from "./controller";
|
||||
import { FastifyInstance } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
import { HealthController } from "./controller";
|
||||
|
||||
export async function healthRoutes(app: FastifyInstance) {
|
||||
const healthController = new HealthController();
|
||||
|
||||
|
@@ -1,13 +1,14 @@
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
|
||||
import {
|
||||
CreateReverseShareSchema,
|
||||
UpdateReverseShareSchema,
|
||||
UpdateReverseSharePasswordSchema,
|
||||
UploadToReverseShareSchema,
|
||||
ReverseSharePasswordSchema,
|
||||
GetPresignedUrlSchema,
|
||||
ReverseSharePasswordSchema,
|
||||
UpdateReverseSharePasswordSchema,
|
||||
UpdateReverseShareSchema,
|
||||
UploadToReverseShareSchema,
|
||||
} from "./dto";
|
||||
import { ReverseShareService } from "./service";
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
|
||||
export class ReverseShareController {
|
||||
private reverseShareService = new ReverseShareService();
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
import { prisma } from "../../shared/prisma";
|
||||
import { CreateReverseShareInput, UpdateReverseShareInput } from "./dto";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
export class ReverseShareRepository {
|
||||
async create(data: CreateReverseShareInput, creatorId: string) {
|
||||
|
@@ -1,18 +1,19 @@
|
||||
import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
import { ReverseShareController } from "./controller";
|
||||
import {
|
||||
CreateReverseShareSchema,
|
||||
UpdateReverseShareSchema,
|
||||
UpdateReverseSharePasswordSchema,
|
||||
ReverseShareResponseSchema,
|
||||
ReverseSharePublicSchema,
|
||||
ReverseSharePasswordSchema,
|
||||
ReverseShareFileSchema,
|
||||
UploadToReverseShareSchema,
|
||||
GetPresignedUrlSchema,
|
||||
ReverseShareFileSchema,
|
||||
ReverseSharePasswordSchema,
|
||||
ReverseSharePublicSchema,
|
||||
ReverseShareResponseSchema,
|
||||
UpdateReverseShareFileSchema,
|
||||
UpdateReverseSharePasswordSchema,
|
||||
UpdateReverseShareSchema,
|
||||
UploadToReverseShareSchema,
|
||||
} from "./dto";
|
||||
import { FastifyInstance, FastifyRequest, FastifyReply } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
export async function reverseShareRoutes(app: FastifyInstance) {
|
||||
const reverseShareController = new ReverseShareController();
|
||||
|
@@ -1,12 +1,13 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
|
||||
import { FileService } from "../file/service";
|
||||
import {
|
||||
CreateReverseShareInput,
|
||||
ReverseShareResponseSchema,
|
||||
UpdateReverseShareInput,
|
||||
UploadToReverseShareInput,
|
||||
ReverseShareResponseSchema,
|
||||
} from "./dto";
|
||||
import { ReverseShareRepository } from "./repository";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
|
||||
interface ReverseShareData {
|
||||
id: string;
|
||||
|
@@ -1,12 +1,13 @@
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
|
||||
import {
|
||||
CreateShareSchema,
|
||||
UpdateShareSchema,
|
||||
UpdateSharePasswordSchema,
|
||||
UpdateShareFilesSchema,
|
||||
UpdateSharePasswordSchema,
|
||||
UpdateShareRecipientsSchema,
|
||||
UpdateShareSchema,
|
||||
} from "./dto";
|
||||
import { ShareService } from "./service";
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
|
||||
export class ShareController {
|
||||
private shareService = new ShareService();
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import type { Share, ShareSecurity } from "@prisma/client";
|
||||
|
||||
import { prisma } from "../../shared/prisma";
|
||||
import type { CreateShareInput } from "./dto";
|
||||
import type { Share, ShareSecurity } from "@prisma/client";
|
||||
|
||||
export interface IShareRepository {
|
||||
createShare(data: CreateShareInput & { securityId: string; creatorId: string }): Promise<Share>;
|
||||
|
@@ -1,15 +1,16 @@
|
||||
import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
import { ShareController } from "./controller";
|
||||
import {
|
||||
CreateShareSchema,
|
||||
ShareResponseSchema,
|
||||
UpdateShareSchema,
|
||||
UpdateSharePasswordSchema,
|
||||
UpdateShareFilesSchema,
|
||||
UpdateShareRecipientsSchema,
|
||||
ShareAliasResponseSchema,
|
||||
ShareResponseSchema,
|
||||
UpdateShareFilesSchema,
|
||||
UpdateSharePasswordSchema,
|
||||
UpdateShareRecipientsSchema,
|
||||
UpdateShareSchema,
|
||||
} from "./dto";
|
||||
import { FastifyInstance, FastifyRequest, FastifyReply } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
export async function shareRoutes(app: FastifyInstance) {
|
||||
const shareController = new ShareController();
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
import { prisma } from "../../shared/prisma";
|
||||
import { EmailService } from "../email/service";
|
||||
import { CreateShareInput, UpdateShareInput, ShareResponseSchema } from "./dto";
|
||||
import { PrismaShareRepository, IShareRepository } from "./repository";
|
||||
import bcrypt from "bcryptjs";
|
||||
import { CreateShareInput, ShareResponseSchema, UpdateShareInput } from "./dto";
|
||||
import { IShareRepository, PrismaShareRepository } from "./repository";
|
||||
|
||||
export class ShareService {
|
||||
constructor(private readonly shareRepository: IShareRepository = new PrismaShareRepository()) {}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
|
||||
import { StorageService } from "./service";
|
||||
import { FastifyRequest, FastifyReply } from "fastify";
|
||||
|
||||
export class StorageController {
|
||||
private storageService = new StorageService();
|
||||
|
@@ -1,7 +1,8 @@
|
||||
import { StorageController } from "./controller";
|
||||
import { FastifyInstance } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
import { StorageController } from "./controller";
|
||||
|
||||
export async function storageRoutes(app: FastifyInstance) {
|
||||
const storageController = new StorageController();
|
||||
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import { IS_RUNNING_IN_CONTAINER } from "../../utils/container-detection";
|
||||
import { ConfigService } from "../config/service";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { exec } from "child_process";
|
||||
import fs from "node:fs";
|
||||
import { promisify } from "util";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
|
||||
import { IS_RUNNING_IN_CONTAINER } from "../../utils/container-detection";
|
||||
import { ConfigService } from "../config/service";
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
const prisma = new PrismaClient();
|
||||
|
@@ -1,9 +1,8 @@
|
||||
import sharp from "sharp";
|
||||
|
||||
import { prisma } from "../../shared/prisma";
|
||||
|
||||
|
||||
export class AvatarService {
|
||||
|
||||
async uploadAvatar(buffer: Buffer): Promise<string> {
|
||||
try {
|
||||
const metadata = await sharp(buffer).metadata();
|
||||
@@ -12,20 +11,20 @@ export class AvatarService {
|
||||
}
|
||||
|
||||
const webpBuffer = await sharp(buffer)
|
||||
.resize(100, 100, {
|
||||
.resize(100, 100, {
|
||||
fit: "cover",
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 }
|
||||
background: { r: 255, g: 255, b: 255, alpha: 0 },
|
||||
})
|
||||
.webp({
|
||||
.webp({
|
||||
quality: 60,
|
||||
effort: 6,
|
||||
nearLossless: true,
|
||||
alphaQuality: 100,
|
||||
lossless: true
|
||||
lossless: true,
|
||||
})
|
||||
.toBuffer();
|
||||
|
||||
return `data:image/webp;base64,${webpBuffer.toString('base64')}`;
|
||||
return `data:image/webp;base64,${webpBuffer.toString("base64")}`;
|
||||
} catch (error) {
|
||||
console.error("Error processing avatar:", error);
|
||||
throw error;
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import { AvatarService } from "./avatar.service";
|
||||
import { UpdateUserSchema, createRegisterUserSchema } from "./dto";
|
||||
import { UserService } from "./service";
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
|
||||
import { AvatarService } from "./avatar.service";
|
||||
import { createRegisterUserSchema, UpdateUserSchema } from "./dto";
|
||||
import { UserService } from "./service";
|
||||
|
||||
export class UserController {
|
||||
private userService = new UserService();
|
||||
private avatarService = new AvatarService();
|
||||
@@ -101,7 +102,7 @@ export class UserController {
|
||||
return reply.status(400).send({ error: "No file uploaded" });
|
||||
}
|
||||
|
||||
if (!file.mimetype.startsWith('image/')) {
|
||||
if (!file.mimetype.startsWith("image/")) {
|
||||
return reply.status(400).send({ error: "Only images are allowed" });
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { ConfigService } from "../config/service";
|
||||
import { z } from "zod";
|
||||
|
||||
import { ConfigService } from "../config/service";
|
||||
|
||||
const configService = new ConfigService();
|
||||
|
||||
export const BaseRegisterUserSchema = z.object({
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { FastifyReply, FastifyRequest } from "fastify";
|
||||
|
||||
import { ConfigService } from "../config/service";
|
||||
import { FastifyRequest, FastifyReply } from "fastify";
|
||||
|
||||
const configService = new ConfigService();
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import type { User } from "@prisma/client";
|
||||
|
||||
import { prisma } from "../../shared/prisma";
|
||||
import type { RegisterUserInput, UpdateUserInput } from "./dto";
|
||||
import type { User } from "@prisma/client";
|
||||
|
||||
export interface IUserRepository {
|
||||
createUser(data: RegisterUserInput & { password: string }): Promise<User>;
|
||||
|
@@ -1,10 +1,11 @@
|
||||
import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
import { prisma } from "../../shared/prisma";
|
||||
import { createPasswordSchema } from "../auth/dto";
|
||||
import { UserController } from "./controller";
|
||||
import { UpdateUserSchema, UserResponseSchema } from "./dto";
|
||||
import { validatePasswordMiddleware } from "./middleware";
|
||||
import { FastifyInstance, FastifyRequest, FastifyReply } from "fastify";
|
||||
import { z } from "zod";
|
||||
|
||||
export async function userRoutes(app: FastifyInstance) {
|
||||
const userController = new UserController();
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import { RegisterUserInput, UserResponseSchema } from "./dto";
|
||||
import { PrismaUserRepository, IUserRepository } from "./repository";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
import { RegisterUserInput, UserResponseSchema } from "./dto";
|
||||
import { IUserRepository, PrismaUserRepository } from "./repository";
|
||||
|
||||
type UserWithPassword = {
|
||||
id: string;
|
||||
email?: string;
|
||||
|
@@ -1,6 +1,3 @@
|
||||
import { env } from "../env";
|
||||
import { StorageProvider } from "../types/storage";
|
||||
import { IS_RUNNING_IN_CONTAINER } from "../utils/container-detection";
|
||||
import * as crypto from "crypto";
|
||||
import * as fsSync from "fs";
|
||||
import * as fs from "fs/promises";
|
||||
@@ -8,6 +5,10 @@ import * as path from "path";
|
||||
import { Transform } from "stream";
|
||||
import { pipeline } from "stream/promises";
|
||||
|
||||
import { env } from "../env";
|
||||
import { StorageProvider } from "../types/storage";
|
||||
import { IS_RUNNING_IN_CONTAINER } from "../utils/container-detection";
|
||||
|
||||
export class FilesystemStorageProvider implements StorageProvider {
|
||||
private static instance: FilesystemStorageProvider;
|
||||
private uploadsDir: string;
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import { s3Client, bucketName } from "../config/storage.config";
|
||||
import { StorageProvider } from "../types/storage";
|
||||
import { DeleteObjectCommand, GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3";
|
||||
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
||||
|
||||
import { bucketName, s3Client } from "../config/storage.config";
|
||||
import { StorageProvider } from "../types/storage";
|
||||
|
||||
export class S3StorageProvider implements StorageProvider {
|
||||
constructor() {
|
||||
if (!s3Client) {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env node
|
||||
import * as readline from "readline";
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import bcrypt from "bcryptjs";
|
||||
import * as readline from "readline";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
|
@@ -1,3 +1,9 @@
|
||||
import * as fs from "fs/promises";
|
||||
import crypto from "node:crypto";
|
||||
import path from "path";
|
||||
import fastifyMultipart from "@fastify/multipart";
|
||||
import fastifyStatic from "@fastify/static";
|
||||
|
||||
import { buildApp } from "./app";
|
||||
import { env } from "./env";
|
||||
import { appRoutes } from "./modules/app/routes";
|
||||
@@ -11,11 +17,6 @@ import { shareRoutes } from "./modules/share/routes";
|
||||
import { storageRoutes } from "./modules/storage/routes";
|
||||
import { userRoutes } from "./modules/user/routes";
|
||||
import { IS_RUNNING_IN_CONTAINER } from "./utils/container-detection";
|
||||
import fastifyMultipart from "@fastify/multipart";
|
||||
import fastifyStatic from "@fastify/static";
|
||||
import * as fs from "fs/promises";
|
||||
import crypto from "node:crypto";
|
||||
import path from "path";
|
||||
|
||||
if (typeof globalThis.crypto === "undefined") {
|
||||
globalThis.crypto = crypto.webcrypto as any;
|
||||
|
1
apps/server/src/types/fastify.d.ts
vendored
1
apps/server/src/types/fastify.d.ts
vendored
@@ -1,4 +1,3 @@
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
import type { FastifyRequest } from "fastify";
|
||||
|
||||
declare module "fastify" {
|
||||
|
@@ -1,11 +1,8 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"display": "Node 22",
|
||||
"_version": "22.0.0",
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"es2023"
|
||||
],
|
||||
"lib": ["es2023"],
|
||||
"module": "node16",
|
||||
"target": "es2022",
|
||||
"strict": true,
|
||||
@@ -16,12 +13,9 @@
|
||||
"rootDir": "./src",
|
||||
"baseUrl": "./src",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
||||
"display": "Node 22",
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
|
Reference in New Issue
Block a user