mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-10-01 07:37:55 -05:00
Add server
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"name": "vite-template-solid",
|
||||
"name": "sendou.ink",
|
||||
"version": "0.0.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"start": "vite",
|
||||
"dev": "vite",
|
||||
|
||||
144
server/index.ts
Normal file
144
server/index.ts
Normal file
@@ -0,0 +1,144 @@
|
||||
import { EventEmitter } from "events";
|
||||
import express from "express";
|
||||
import * as trpc from "@trpc/server";
|
||||
import { z } from "zod";
|
||||
import * as trpcExpress from "@trpc/server/adapters/express/dist/trpc-server-adapters-express.cjs";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
|
||||
const createContext = ({
|
||||
req,
|
||||
res,
|
||||
}: trpcExpress.CreateExpressContextOptions) => {
|
||||
const getUser = () => {
|
||||
if (req.headers.authorization !== "secret") {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
name: "alex",
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
req,
|
||||
res,
|
||||
user: getUser(),
|
||||
};
|
||||
};
|
||||
type Context = trpc.inferAsyncReturnType<typeof createContext>;
|
||||
|
||||
function createRouter() {
|
||||
return trpc.router<Context>();
|
||||
}
|
||||
|
||||
// --------- create procedures etc
|
||||
|
||||
let id = 0;
|
||||
|
||||
const ee = new EventEmitter();
|
||||
const db = {
|
||||
posts: [
|
||||
{
|
||||
id: ++id,
|
||||
title: "hello",
|
||||
},
|
||||
],
|
||||
messages: [createMessage("initial message")],
|
||||
};
|
||||
function createMessage(text: string) {
|
||||
const msg = {
|
||||
id: ++id,
|
||||
text,
|
||||
createdAt: Date.now(),
|
||||
updatedAt: Date.now(),
|
||||
};
|
||||
ee.emit("newMessage", msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
const posts = createRouter()
|
||||
.mutation("create", {
|
||||
input: z.object({
|
||||
title: z.string(),
|
||||
}),
|
||||
resolve: ({ input }) => {
|
||||
const post = {
|
||||
id: ++id,
|
||||
...input,
|
||||
};
|
||||
db.posts.push(post);
|
||||
return post;
|
||||
},
|
||||
})
|
||||
.query("list", {
|
||||
resolve: () => db.posts,
|
||||
});
|
||||
|
||||
const messages = createRouter()
|
||||
.query("list", {
|
||||
resolve: () => db.messages,
|
||||
})
|
||||
.mutation("add", {
|
||||
input: z.string(),
|
||||
resolve: async ({ input }) => {
|
||||
const msg = createMessage(input);
|
||||
|
||||
db.messages.push(msg);
|
||||
|
||||
return msg;
|
||||
},
|
||||
});
|
||||
|
||||
// root router to call
|
||||
export const appRouter = createRouter()
|
||||
.query("hello", {
|
||||
input: z.string().nullish(),
|
||||
resolve: ({ input, ctx }) => {
|
||||
return `hello ${input ?? ctx.user?.name ?? "world"}`;
|
||||
},
|
||||
})
|
||||
.merge("post.", posts)
|
||||
.merge(
|
||||
"admin.",
|
||||
createRouter().query("secret", {
|
||||
resolve: ({ ctx }) => {
|
||||
if (!ctx.user) {
|
||||
throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||
}
|
||||
if (ctx.user?.name !== "alex") {
|
||||
throw new TRPCError({ code: "FORBIDDEN" });
|
||||
}
|
||||
return {
|
||||
secret: "sauce",
|
||||
};
|
||||
},
|
||||
})
|
||||
)
|
||||
.merge("messages.", messages);
|
||||
|
||||
export type AppRouter = typeof appRouter;
|
||||
|
||||
async function main() {
|
||||
// express implementation
|
||||
const app = express();
|
||||
|
||||
app.use((req, _res, next) => {
|
||||
// request logger
|
||||
console.log("⬅️ ", req.method, req.path, req.body ?? req.query);
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
app.use(
|
||||
"/trpc",
|
||||
trpcExpress.createExpressMiddleware({
|
||||
router: appRouter,
|
||||
createContext,
|
||||
})
|
||||
);
|
||||
app.get("/", (_req, res) => res.send("hello"));
|
||||
app.listen(2021, () => {
|
||||
console.log("listening on port 2021");
|
||||
});
|
||||
}
|
||||
|
||||
main();
|
||||
1321
server/package-lock.json
generated
Normal file
1321
server/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
22
server/package.json
Normal file
22
server/package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "@sendou.ink/server",
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev": "node --experimental-specifier-resolution=node --loader ts-node/esm index.ts",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@trpc/server": "^9.13.0",
|
||||
"express": "^4.17.1",
|
||||
"zod": "^3.11.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.13",
|
||||
"ts-node": "^10.4.0"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
|
||||
Reference in New Issue
Block a user