@goscribe/server 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/context.d.ts +2 -2
- package/dist/context.js +11 -7
- package/dist/index.d.ts +3 -4
- package/dist/index.js +1 -2
- package/dist/lib/auth.d.ts +3 -2
- package/dist/lib/auth.js +39 -36
- package/dist/lib/file.d.ts +0 -0
- package/dist/lib/file.js +1 -0
- package/dist/lib/prisma.d.ts +2 -3
- package/dist/lib/prisma.js +4 -7
- package/dist/lib/storage.d.ts +3 -0
- package/dist/lib/storage.js +10 -0
- package/dist/routers/_app.d.ts +90 -16
- package/dist/routers/_app.js +6 -9
- package/dist/routers/auth.d.ts +28 -2
- package/dist/routers/auth.js +48 -16
- package/dist/routers/workspace.d.ts +60 -14
- package/dist/routers/workspace.js +129 -30
- package/dist/server.d.ts +0 -1
- package/dist/server.js +19 -56
- package/dist/trpc.d.ts +10 -9
- package/dist/trpc.js +13 -26
- package/package.json +11 -4
- package/prisma/schema.prisma +7 -21
- package/src/context.ts +12 -4
- package/src/index.ts +3 -3
- package/src/lib/auth.ts +37 -32
- package/src/lib/prisma.ts +1 -1
- package/src/routers/_app.ts +3 -3
- package/src/routers/auth.ts +47 -2
- package/src/routers/workspace.ts +16 -15
- package/src/server.ts +2 -5
- package/src/trpc.ts +5 -11
- package/tsconfig.json +17 -10
- package/dist/context.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/lib/auth.d.ts.map +0 -1
- package/dist/lib/prisma.d.ts.map +0 -1
- package/dist/routers/_app.d.ts.map +0 -1
- package/dist/routers/auth.d.ts.map +0 -1
- package/dist/routers/sample.js +0 -21
- package/dist/routers/workspace.d.ts.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/trpc.d.ts.map +0 -1
package/src/routers/auth.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { router, publicProcedure, authedProcedure } from '../trpc';
|
|
2
|
+
import { router, publicProcedure, authedProcedure } from '../trpc.js';
|
|
3
3
|
import bcrypt from 'bcryptjs';
|
|
4
4
|
|
|
5
5
|
export const auth = router({
|
|
6
|
-
signup: publicProcedure
|
|
6
|
+
signup: publicProcedure
|
|
7
7
|
.input(z.object({
|
|
8
8
|
name: z.string().min(1),
|
|
9
9
|
email: z.string().email(),
|
|
@@ -30,5 +30,50 @@ signup: publicProcedure
|
|
|
30
30
|
|
|
31
31
|
return { id: user.id, email: user.email, name: user.name };
|
|
32
32
|
}),
|
|
33
|
+
login: publicProcedure
|
|
34
|
+
.input(z.object({
|
|
35
|
+
email: z.string().email(),
|
|
36
|
+
password: z.string().min(6),
|
|
37
|
+
}))
|
|
38
|
+
.mutation(async ({ ctx, input }) => {
|
|
39
|
+
const user = await ctx.db.user.findUnique({
|
|
40
|
+
where: { email: input.email },
|
|
41
|
+
});
|
|
42
|
+
if (!user) {
|
|
43
|
+
throw new Error("Invalid credentials");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const valid = await bcrypt.compare(input.password, user.passwordHash!);
|
|
47
|
+
if (!valid) {
|
|
48
|
+
throw new Error("Invalid credentials");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return { id: user.id, email: user.email, name: user.name };
|
|
52
|
+
}),
|
|
53
|
+
getSession: publicProcedure.query(async ({ ctx }) => {
|
|
54
|
+
const session = await ctx.db.session.findUnique({
|
|
55
|
+
where: {
|
|
56
|
+
id: ctx.session?.id,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (!session) {
|
|
61
|
+
throw new Error("Session not found");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (session.expires < new Date()) {
|
|
65
|
+
throw new Error("Session expired");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const user = await ctx.db.user.findUnique({
|
|
69
|
+
where: { id: session.userId },
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (!user) {
|
|
73
|
+
throw new Error("User not found");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return { id: session.id, userId: session.userId, user: { id: user.id, email: user.email, name: user.name, image: user.image } };
|
|
77
|
+
}),
|
|
33
78
|
});
|
|
34
79
|
|
package/src/routers/workspace.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { router, publicProcedure, authedProcedure } from '../trpc';
|
|
3
|
-
import { bucket } from '
|
|
2
|
+
import { router, publicProcedure, authedProcedure } from '../trpc.js';
|
|
3
|
+
import { bucket } from '../lib/storage.js';
|
|
4
|
+
import { FileAsset } from '@prisma/client';
|
|
4
5
|
|
|
5
6
|
export const workspace = router({
|
|
6
7
|
// Mutation with Zod input
|
|
7
|
-
list:
|
|
8
|
+
list: authedProcedure
|
|
8
9
|
.query(async ({ ctx, input }) => {
|
|
9
10
|
const workspaces = await ctx.db.workspace.findMany({
|
|
10
11
|
where: {
|
|
@@ -14,7 +15,7 @@ export const workspace = router({
|
|
|
14
15
|
return workspaces;
|
|
15
16
|
}),
|
|
16
17
|
|
|
17
|
-
create:
|
|
18
|
+
create: authedProcedure
|
|
18
19
|
.input(z.object({
|
|
19
20
|
name: z.string().min(1).max(100),
|
|
20
21
|
description: z.string().max(500).optional(),
|
|
@@ -28,7 +29,7 @@ export const workspace = router({
|
|
|
28
29
|
},
|
|
29
30
|
});
|
|
30
31
|
}),
|
|
31
|
-
get:
|
|
32
|
+
get: authedProcedure
|
|
32
33
|
.input(z.object({
|
|
33
34
|
id: z.string().uuid(),
|
|
34
35
|
}))
|
|
@@ -39,7 +40,7 @@ export const workspace = router({
|
|
|
39
40
|
},
|
|
40
41
|
});
|
|
41
42
|
}),
|
|
42
|
-
update:
|
|
43
|
+
update: authedProcedure
|
|
43
44
|
.input(z.object({
|
|
44
45
|
id: z.string().uuid(),
|
|
45
46
|
name: z.string().min(1).max(100).optional(),
|
|
@@ -56,7 +57,7 @@ export const workspace = router({
|
|
|
56
57
|
},
|
|
57
58
|
});
|
|
58
59
|
}),
|
|
59
|
-
delete:
|
|
60
|
+
delete: authedProcedure
|
|
60
61
|
.input(z.object({
|
|
61
62
|
id: z.string().uuid(),
|
|
62
63
|
}))
|
|
@@ -68,7 +69,7 @@ export const workspace = router({
|
|
|
68
69
|
});
|
|
69
70
|
return true;
|
|
70
71
|
}),
|
|
71
|
-
uploadFiles:
|
|
72
|
+
uploadFiles: authedProcedure
|
|
72
73
|
.input(z.object({
|
|
73
74
|
id: z.string().uuid(),
|
|
74
75
|
files: z.array(
|
|
@@ -121,7 +122,7 @@ export const workspace = router({
|
|
|
121
122
|
return results;
|
|
122
123
|
|
|
123
124
|
}),
|
|
124
|
-
deleteFiles:
|
|
125
|
+
deleteFiles: authedProcedure
|
|
125
126
|
.input(z.object({
|
|
126
127
|
fileId: z.array(z.string().uuid()),
|
|
127
128
|
id: z.string().uuid(),
|
|
@@ -135,13 +136,13 @@ export const workspace = router({
|
|
|
135
136
|
});
|
|
136
137
|
|
|
137
138
|
// Delete from GCS
|
|
138
|
-
files.then((fileRecords) => {
|
|
139
|
-
fileRecords.forEach((file) => {
|
|
139
|
+
files.then((fileRecords: FileAsset[]) => {
|
|
140
|
+
fileRecords.forEach((file: FileAsset) => {
|
|
140
141
|
if (file.bucket && file.objectKey) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
const gcsFile: import('@google-cloud/storage').File = bucket.file(file.objectKey);
|
|
143
|
+
gcsFile.delete({ ignoreNotFound: true }).catch((err: unknown) => {
|
|
144
|
+
console.error(`Error deleting file ${file.objectKey} from bucket ${file.bucket}:`, err);
|
|
145
|
+
});
|
|
145
146
|
}
|
|
146
147
|
});
|
|
147
148
|
});
|
package/src/server.ts
CHANGED
|
@@ -4,10 +4,9 @@ import helmet from 'helmet';
|
|
|
4
4
|
import morgan from 'morgan';
|
|
5
5
|
import compression from 'compression';
|
|
6
6
|
import * as trpcExpress from '@trpc/server/adapters/express';
|
|
7
|
-
import { authRouter } from './lib/auth';
|
|
8
7
|
|
|
9
|
-
import { appRouter } from './routers/_app';
|
|
10
|
-
import { createContext } from './context';
|
|
8
|
+
import { appRouter } from './routers/_app.js';
|
|
9
|
+
import { createContext } from './context.js';
|
|
11
10
|
|
|
12
11
|
const PORT = process.env.PORT ? Number(process.env.PORT) : 3001;
|
|
13
12
|
|
|
@@ -25,8 +24,6 @@ async function main() {
|
|
|
25
24
|
app.use(compression());
|
|
26
25
|
app.use(express.json());
|
|
27
26
|
|
|
28
|
-
app.use("/auth", authRouter); // Auth routes live under /auth/*
|
|
29
|
-
|
|
30
27
|
|
|
31
28
|
// Health (plain Express)
|
|
32
29
|
app.get('/', (_req, res) => {
|
package/src/trpc.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { initTRPC, TRPCError } from "@trpc/server";
|
|
2
2
|
import superjson from "superjson";
|
|
3
|
-
import type { Context } from "./context";
|
|
3
|
+
import type { Context } from "./context.js";
|
|
4
4
|
|
|
5
5
|
const t = initTRPC.context<Context>().create({
|
|
6
6
|
transformer: superjson,
|
|
@@ -15,20 +15,14 @@ export const publicProcedure = t.procedure;
|
|
|
15
15
|
|
|
16
16
|
/** Middleware that enforces authentication */
|
|
17
17
|
const isAuthed = middleware(({ ctx, next }) => {
|
|
18
|
-
|
|
18
|
+
const hasUser = Boolean((ctx.session as any)?.user?.id);
|
|
19
|
+
if (!ctx.session || !hasUser) {
|
|
19
20
|
throw new TRPCError({ code: "UNAUTHORIZED" });
|
|
20
21
|
}
|
|
22
|
+
|
|
21
23
|
return next({
|
|
22
24
|
ctx: {
|
|
23
|
-
|
|
24
|
-
// refine ctx: session is guaranteed, user.id is string
|
|
25
|
-
session: {
|
|
26
|
-
...ctx.session,
|
|
27
|
-
user: {
|
|
28
|
-
...ctx.session.user,
|
|
29
|
-
id: ctx.session.user.id, // typed non-null
|
|
30
|
-
},
|
|
31
|
-
},
|
|
25
|
+
session: ctx.session,
|
|
32
26
|
},
|
|
33
27
|
});
|
|
34
28
|
});
|
package/tsconfig.json
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"target": "ES2020",
|
|
4
|
-
"module": "
|
|
5
|
-
"moduleResolution": "
|
|
4
|
+
"module": "ES2020", // <-- this ensures ESM output
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"plugins": [
|
|
7
|
+
{ "transform": "typescript-transform-paths" },
|
|
8
|
+
{ "transform": "typescript-transform-paths", "afterDeclarations": true }
|
|
9
|
+
|
|
10
|
+
],
|
|
11
|
+
"baseUrl": "./",
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"declarationDir": "dist", // optional, but keeps .d.ts in dist
|
|
14
|
+
"emitDeclarationOnly": false, // unless you only want .d.ts
|
|
15
|
+
"noEmit": false, // must not be true
|
|
16
|
+
|
|
6
17
|
"esModuleInterop": true,
|
|
7
18
|
"strict": true,
|
|
8
19
|
"skipLibCheck": true,
|
|
9
|
-
"
|
|
10
|
-
"outDir": "dist",
|
|
11
|
-
"baseUrl": ".",
|
|
12
|
-
"declaration": true,
|
|
13
|
-
"declarationMap": true
|
|
20
|
+
"outDir": "dist"
|
|
14
21
|
},
|
|
15
|
-
"include": ["src
|
|
16
|
-
"exclude": ["node_modules", "dist"]
|
|
17
|
-
}
|
|
22
|
+
"include": ["src"],
|
|
23
|
+
"exclude": ["node_modules", "dist" ]
|
|
24
|
+
}
|
package/dist/context.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAGjF,wBAAsB,aAAa,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,2BAA2B;;;;;GAI5E;AAED,MAAM,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/lib/auth.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,UAAU,0HA0BnB,CAAA"}
|
package/dist/lib/prisma.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/lib/prisma.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAInD,eAAO,MAAM,MAAM,2IAIf,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_app.d.ts","sourceRoot":"","sources":["../../src/routers/_app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAKrE,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAGpB,CAAC;AAGH,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC;AACzC,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;AACxD,MAAM,MAAM,aAAa,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/routers/auth.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;GA4Bf,CAAC"}
|
package/dist/routers/sample.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sampleRouter = void 0;
|
|
4
|
-
const zod_1 = require("zod");
|
|
5
|
-
const trpc_1 = require("../trpc");
|
|
6
|
-
exports.sampleRouter = (0, trpc_1.router)({
|
|
7
|
-
// GET-like: query without input
|
|
8
|
-
hello: trpc_1.publicProcedure.query(() => {
|
|
9
|
-
return { message: 'Hello from tRPC + Express 👋' };
|
|
10
|
-
}),
|
|
11
|
-
// Mutation with Zod input
|
|
12
|
-
echo: trpc_1.publicProcedure
|
|
13
|
-
.input(zod_1.z.object({ text: zod_1.z.string().min(1) }))
|
|
14
|
-
.mutation(({ input }) => {
|
|
15
|
-
return { echoed: input.text };
|
|
16
|
-
}),
|
|
17
|
-
// Authed query
|
|
18
|
-
me: trpc_1.authedProcedure.query(({ ctx }) => {
|
|
19
|
-
return { userId: ctx.user.id, role: ctx.user.role };
|
|
20
|
-
}),
|
|
21
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/routers/workspace.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CpB,CAAC"}
|
package/dist/server.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":""}
|
package/dist/trpc.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"trpc.d.ts","sourceRoot":"","sources":["../src/trpc.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,MAAM;;;;;;;;;;EAAW,CAAC;AAC/B,eAAO,MAAM,UAAU;;;;;;;;;;sCAAe,CAAC;AACvC,eAAO,MAAM,eAAe;;;;;yLAAc,CAAC;AAsB3C,gCAAgC;AAChC,eAAO,MAAM,eAAe;;;;;;;;;;yKAAgC,CAAC"}
|