-
Notifications
You must be signed in to change notification settings - Fork 0
/
core.ts
148 lines (116 loc) · 3.99 KB
/
core.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import { db } from "@/db";
import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server";
import { createUploadthing, type FileRouter } from "uploadthing/next";
import { PDFLoader } from "langchain/document_loaders/fs/pdf"
import { OpenAIEmbeddings } from "langchain/embeddings/openai"
import { PineconeStore } from "langchain/vectorstores/pinecone"
import { pinecone } from "@/lib/pincone";
import { getUserSubscriptionPlan } from "@/lib/stripe";
import { PLANS } from "@/config/stripe";
const f = createUploadthing();
const middleware = async () => {
// This code runs on your server before upload
const { getUser } = getKindeServerSession()
const user = getUser()
// If you throw, the user will not be able to upload
if (!user || !user.id) throw new Error("Unauthorized");
const subscriptionPlan = await getUserSubscriptionPlan()
// Whatever is returned here is accessible in onUploadComplete as `metadata`
return { subscriptionPlan, userId: user.id }
}
const onUploadComplete = async ({
metadata,
file,
}: {
metadata: Awaited<ReturnType<typeof middleware>>
file: {
key: string
name: string
url: string
}
}) => {
const isFileExist = await db.file.findFirst({
where: {
key: file.key,
},
})
if(isFileExist) return
const createdFile = await db.file.create({
data: {
key: file.key,
name: file.name,
userId: metadata.userId,
url: `https://uploadthing-prod.s3.us-west-2.amazonaws.com/${file.key}`,
uploadStatus: "PROCESSING"
}
})
try {
const response = await fetch(`https://uploadthing-prod.s3.us-west-2.amazonaws.com/${file.key}`)
const blob = await response.blob()
const loader = new PDFLoader(blob)
const pageLevelDocs = await loader.load()
const pagesAmt = pageLevelDocs.length
const { subscriptionPlan } = metadata
const { isSubscribed } = subscriptionPlan
const isProExceeded =
pagesAmt >
PLANS.find((plan) => plan.name === 'Pro')!.pagesPerPdf
const isFreeExceeded =
pagesAmt >
PLANS.find((plan) => plan.name === 'Free')!
.pagesPerPdf
if (
(isSubscribed && isProExceeded) ||
(!isSubscribed && isFreeExceeded)
) {
await db.file.update({
data: {
uploadStatus: 'FAILED',
},
where: {
id: createdFile.id,
},
})
}
//vectorize and index entire document
console.log("Creating pinecone")
const pineconeIndex = pinecone.Index("pdfaskmate")
const embeddings = new OpenAIEmbeddings({
openAIApiKey: process.env.OPENAI_API_KEY
})
await PineconeStore.fromDocuments(pageLevelDocs, embeddings, {
pineconeIndex,
// namespace: createdFile.id
})
await db.file.update({
data: {
uploadStatus: "SUCCESS"
},
where: {
id: createdFile.id
}
})
} catch (err) {
console.log("error", err)
await db.file.update({
data: {
uploadStatus: "FAILED"
},
where: {
id: createdFile.id
}
})
}
}
// FileRouter for your app, can contain multiple FileRoutes
export const ourFileRouter = {
// Define as many FileRoutes as you like, each with a unique routeSlug
freePlanUploader: f({ pdf: { maxFileSize: "4MB" } })
.middleware(middleware)
.onUploadComplete(onUploadComplete),
proPlanUploader: f({ pdf: { maxFileSize: "16MB" } })
// Set permissions and file types for this FileRoute
.middleware(middleware)
.onUploadComplete(onUploadComplete),
} satisfies FileRouter;
export type OurFileRouter = typeof ourFileRouter;