done #3

Merged
BenjaminPalko merged 1 commit from linter-and-formatting into master 2024-12-03 16:23:39 -05:00
15 changed files with 226 additions and 177 deletions

13
.editorconfig Normal file
View file

@ -0,0 +1,13 @@
root = true
[*]
end_of_line = lf
insert_final_newline = false
[*.{js,ts}]
indent_style = tab
indent_size = 4
[{*.{yml,mjs,json}}]
indent_style = space
indent_size = 2

View file

@ -1,12 +1,14 @@
name: PR Checks name: PR Checks
on: [pull_request] on: [pull_request]
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2 - uses: oven-sh/setup-bun@v2
with: with:
bun-version: latest bun-version: latest
- name: build - name: install
run: bun run clean && bun run build run: bun install
- name: build
run: bun run clean && bun run build

BIN
bun.lockb

Binary file not shown.

13
eslint.config.mjs Normal file
View file

@ -0,0 +1,13 @@
import pluginJs from '@eslint/js';
import eslintConfigPrettier from 'eslint-config-prettier';
import globals from 'globals';
import tseslint from 'typescript-eslint';
/** @type {import('eslint').Linter.Config[]} */
export default [
{ files: ['**/*.{js,mjs,cjs,ts}'] },
{ languageOptions: { globals: globals.browser } },
pluginJs.configs.recommended,
...tseslint.configs.recommended,
eslintConfigPrettier,
];

View file

@ -1,23 +1,23 @@
import { type YogaLogger } from "graphql-yoga"; import { type YogaLogger } from 'graphql-yoga';
import pino from "pino"; import pino from 'pino';
export const logger = pino(); export const logger = pino();
export const yogaLogger: YogaLogger = { export const yogaLogger: YogaLogger = {
debug(...args) { debug(...args) {
// @ts-ignore // @ts-expect-error types dont match
logger.debug(...args); logger.debug(...args);
}, },
info(...args) { info(...args) {
// @ts-ignore // @ts-expect-error types dont match
logger.info(...args); logger.info(...args);
}, },
warn(...args) { warn(...args) {
// @ts-ignore // @ts-expect-error types dont match
logger.warn(...args); logger.warn(...args);
}, },
error(...args) { error(...args) {
// @ts-ignore // @ts-expect-error types dont match
logger.error(...args); logger.error(...args);
}, },
}; };

View file

@ -1,28 +1,36 @@
{ {
"name": "hestia", "name": "hestia",
"module": "src/index.ts", "module": "src/index.ts",
"type": "module", "type": "module",
"scripts": { "scripts": {
"build": "bun build ./src/index.ts --outdir ./build", "build": "bun build ./src/index.ts --outdir ./build",
"clean": "rm -rf ./build", "clean": "rm -rf ./build",
"dev": "bun --watch src/index.ts | pino-pretty", "dev": "bun --watch src/index.ts | pino-pretty",
"prisma:generate": "prisma generate" "format": "prettier . --write",
}, "lint": "",
"devDependencies": { "prisma:generate": "prisma generate"
"@types/bun": "latest", },
"prisma": "^6.0.1" "devDependencies": {
}, "@eslint/js": "^9.16.0",
"peerDependencies": { "@types/bun": "latest",
"typescript": "^5.0.0" "eslint": "^9.16.0",
}, "eslint-config-prettier": "^9.1.0",
"dependencies": { "globals": "^15.13.0",
"@pothos/core": "^4.3.0", "prettier": "3.4.1",
"@pothos/plugin-prisma": "^4.4.0", "prisma": "^6.0.1",
"@prisma/client": "6.0.1", "typescript-eslint": "^8.17.0"
"graphql": "^16.9.0", },
"graphql-yoga": "^5.10.4", "peerDependencies": {
"pino": "^9.5.0", "typescript": "^5.0.0"
"pino-pretty": "^13.0.0", },
"zod": "^3.23.8" "dependencies": {
} "@pothos/core": "^4.3.0",
"@pothos/plugin-prisma": "^4.4.0",
"@prisma/client": "6.0.1",
"graphql": "^16.9.0",
"graphql-yoga": "^5.10.4",
"pino": "^9.5.0",
"pino-pretty": "^13.0.0",
"zod": "^3.23.8"
}
} }

13
prettier.config.mjs Normal file
View file

@ -0,0 +1,13 @@
/**
* @see https://prettier.io/docs/en/configuration.html
* @type {import("prettier").Config}
*/
const config = {
trailingComma: 'es5',
tabWidth: 4,
useTabs: true,
semi: true,
singleQuote: true,
};
export default config;

View file

@ -1,22 +1,22 @@
import { logger } from "@lib/logger"; import { logger } from '@lib/logger';
import { z } from "zod"; import { z } from 'zod';
export interface Configuration { export interface Configuration {
app_version: string; app_version: string;
} }
export const LoadConfig = (): Configuration => { export const LoadConfig = (): Configuration => {
const { success, data, error } = z const { success, data, error } = z
.object({ .object({
APP_VERSION: z.string().default("development"), APP_VERSION: z.string().default('development'),
}) })
.safeParse(process.env); .safeParse(process.env);
if (!success) { if (!success) {
logger.error(error.message); logger.error(error.message);
} }
return { return {
app_version: data!.APP_VERSION, app_version: data!.APP_VERSION,
}; };
}; };

View file

@ -1,15 +1,15 @@
import { logger } from "@lib/logger"; import { logger } from '@lib/logger';
import { yoga } from "./yoga"; import { yoga } from './yoga';
const server = Bun.serve({ const server = Bun.serve({
fetch: yoga.fetch, fetch: yoga.fetch,
error: (error) => { error: (error) => {
logger.error(error.message); logger.error(error.message);
return new Response("", { return new Response('', {
status: 500, status: 500,
statusText: "You fucked the goose", statusText: 'You fucked the goose',
}); });
}, },
}); });
logger.info(`Server is running on: ${server.url}${yoga.graphqlEndpoint}`); logger.info(`Server is running on: ${server.url}${yoga.graphqlEndpoint}`);

View file

@ -1,3 +1,3 @@
import { PrismaClient } from "@prisma/client"; import { PrismaClient } from '@prisma/client';
export const prisma = new PrismaClient(); export const prisma = new PrismaClient();

View file

@ -1,29 +1,29 @@
import type { Configuration } from "@app/config"; import type { Configuration } from '@app/config';
import { prisma } from "@app/prisma"; import { prisma } from '@app/prisma';
import SchemaBuilder from "@pothos/core"; import SchemaBuilder from '@pothos/core';
import PrismaPlugin, { import PrismaPlugin, {
type PrismaTypesFromClient, type PrismaTypesFromClient,
} from "@pothos/plugin-prisma"; } from '@pothos/plugin-prisma';
import type { YogaInitialContext } from "graphql-yoga"; import type { YogaInitialContext } from 'graphql-yoga';
type Context = YogaInitialContext & { type Context = YogaInitialContext & {
config: Configuration; config: Configuration;
}; };
export const builder = new SchemaBuilder<{ export const builder = new SchemaBuilder<{
Context: Context; Context: Context;
PrismaTypes: PrismaTypesFromClient<typeof prisma>; PrismaTypes: PrismaTypesFromClient<typeof prisma>;
}>({ }>({
plugins: [PrismaPlugin], plugins: [PrismaPlugin],
prisma: { prisma: {
client: prisma, client: prisma,
// defaults to false, uses /// comments from prisma schema as descriptions // defaults to false, uses /// comments from prisma schema as descriptions
// for object types, relations and exposed fields. // for object types, relations and exposed fields.
// descriptions can be omitted by setting description to false // descriptions can be omitted by setting description to false
exposeDescriptions: false, exposeDescriptions: false,
// use where clause from prismaRelatedConnection for totalCount (defaults to true) // use where clause from prismaRelatedConnection for totalCount (defaults to true)
filterConnectionTotalCount: true, filterConnectionTotalCount: true,
// warn when not using a query parameter correctly // warn when not using a query parameter correctly
onUnusedQuery: process.env.NODE_ENV === "production" ? null : "warn", onUnusedQuery: process.env.NODE_ENV === 'production' ? null : 'warn',
}, },
}); });

View file

@ -1,10 +1,10 @@
import { LoadConfig } from "@app/config"; import { LoadConfig } from '@app/config';
import type { YogaInitialContext } from "graphql-yoga"; import type { YogaInitialContext } from 'graphql-yoga';
export const context = (initialContext: YogaInitialContext) => { export const context = (initialContext: YogaInitialContext) => {
const config = LoadConfig(); const config = LoadConfig();
return { return {
...initialContext, ...initialContext,
config, config,
}; };
}; };

View file

@ -1,10 +1,10 @@
import { yogaLogger } from "@lib/logger"; import { yogaLogger } from '@lib/logger';
import { createYoga } from "graphql-yoga"; import { createYoga } from 'graphql-yoga';
import { context } from "./context"; import { context } from './context';
import { schema } from "./schema"; import { schema } from './schema';
export const yoga = createYoga({ export const yoga = createYoga({
schema, schema,
context: context, context: context,
logging: yogaLogger, logging: yogaLogger,
}); });

View file

@ -1,43 +1,43 @@
import { prisma } from "@app/prisma"; import { prisma } from '@app/prisma';
import { builder } from "./builder"; import { builder } from './builder';
const User = builder.prismaObject("User", { const User = builder.prismaObject('User', {
fields: (t) => ({ fields: (t) => ({
id: t.exposeID("id"), id: t.exposeID('id'),
email: t.exposeString("email"), email: t.exposeString('email'),
name: t.exposeString("name"), name: t.exposeString('name'),
posts: t.relation("posts"), posts: t.relation('posts'),
}), }),
}); });
const Post = builder.prismaObject("Post", { const Post = builder.prismaObject('Post', {
fields: (t) => ({ fields: (t) => ({
id: t.exposeID("id"), id: t.exposeID('id'),
title: t.exposeString("title"), title: t.exposeString('title'),
content: t.exposeString("content"), content: t.exposeString('content'),
published: t.exposeBoolean("published"), published: t.exposeBoolean('published'),
author: t.relation("author"), author: t.relation('author'),
}), }),
}); });
builder.queryType({ builder.queryType({
fields: (t) => ({ fields: (t) => ({
version: t.string({ version: t.string({
resolve: (parent, args, context) => context.config.app_version, resolve: (parent, args, context) => context.config.app_version,
}), }),
users: t.prismaField({ users: t.prismaField({
type: [User], type: [User],
resolve: async () => { resolve: async () => {
return await prisma.user.findMany(); return await prisma.user.findMany();
}, },
}), }),
posts: t.prismaField({ posts: t.prismaField({
type: [Post], type: [Post],
resolve: async () => { resolve: async () => {
return await prisma.post.findMany(); return await prisma.post.findMany();
}, },
}), }),
}), }),
}); });
export const schema = builder.toSchema(); export const schema = builder.toSchema();

View file

@ -1,36 +1,36 @@
{ {
"compilerOptions": { "compilerOptions": {
// Enable latest features // Enable latest features
"lib": ["ESNext", "DOM"], "lib": ["ESNext", "DOM"],
"target": "ESNext", "target": "ESNext",
"module": "ESNext", "module": "ESNext",
"moduleDetection": "force", "moduleDetection": "force",
"jsx": "react-jsx", "jsx": "react-jsx",
"allowJs": true, "allowJs": true,
// Bundler mode // Bundler mode
"moduleResolution": "bundler", "moduleResolution": "bundler",
"allowImportingTsExtensions": true, "allowImportingTsExtensions": true,
"verbatimModuleSyntax": true, "verbatimModuleSyntax": true,
"noEmit": true, "noEmit": true,
// Best practices // Best practices
"strict": true, "strict": true,
"skipLibCheck": true, "skipLibCheck": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
// Some stricter flags (disabled by default) // Some stricter flags (disabled by default)
"noUnusedLocals": false, "noUnusedLocals": false,
"noUnusedParameters": false, "noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false, "noPropertyAccessFromIndexSignature": false,
// Path mapping // Path mapping
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@app": ["./src"], "@app": ["./src"],
"@app/*": ["./src/*"], "@app/*": ["./src/*"],
"@lib": ["./lib"], "@lib": ["./lib"],
"@lib/*": ["./lib/*"] "@lib/*": ["./lib/*"]
} }
} }
} }