@studious-lms/server 1.2.41 → 1.2.43

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.
Files changed (144) hide show
  1. package/TODO.md +2 -0
  2. package/dist/exportType.d.ts.map +1 -1
  3. package/dist/exportType.js +4 -0
  4. package/dist/exportType.js.map +1 -0
  5. package/dist/index.d.ts +1 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +32 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/instrument.d.ts +2 -0
  10. package/dist/instrument.d.ts.map +1 -0
  11. package/dist/instrument.js +11 -0
  12. package/dist/instrument.js.map +1 -0
  13. package/dist/lib/fileUpload.d.ts.map +1 -1
  14. package/dist/lib/fileUpload.js +4 -0
  15. package/dist/lib/fileUpload.js.map +1 -0
  16. package/dist/lib/googleCloudStorage.d.ts.map +1 -1
  17. package/dist/lib/googleCloudStorage.js +4 -0
  18. package/dist/lib/googleCloudStorage.js.map +1 -0
  19. package/dist/lib/jsonConversion.d.ts.map +1 -1
  20. package/dist/lib/jsonConversion.js +4 -0
  21. package/dist/lib/jsonConversion.js.map +1 -0
  22. package/dist/lib/jsonStyles.d.ts.map +1 -1
  23. package/dist/lib/jsonStyles.js +4 -0
  24. package/dist/lib/jsonStyles.js.map +1 -0
  25. package/dist/lib/notificationHandler.d.ts.map +1 -1
  26. package/dist/lib/notificationHandler.js +4 -0
  27. package/dist/lib/notificationHandler.js.map +1 -0
  28. package/dist/lib/prisma.d.ts.map +1 -1
  29. package/dist/lib/prisma.js +4 -0
  30. package/dist/lib/prisma.js.map +1 -0
  31. package/dist/lib/pusher.d.ts.map +1 -1
  32. package/dist/lib/pusher.js +4 -0
  33. package/dist/lib/pusher.js.map +1 -0
  34. package/dist/lib/thumbnailGenerator.d.ts.map +1 -1
  35. package/dist/lib/thumbnailGenerator.js +4 -0
  36. package/dist/lib/thumbnailGenerator.js.map +1 -0
  37. package/dist/middleware/auth.d.ts.map +1 -1
  38. package/dist/middleware/auth.js +4 -0
  39. package/dist/middleware/auth.js.map +1 -0
  40. package/dist/middleware/logging.d.ts.map +1 -1
  41. package/dist/middleware/logging.js +4 -0
  42. package/dist/middleware/logging.js.map +1 -0
  43. package/dist/routers/_app.d.ts +0 -108
  44. package/dist/routers/_app.d.ts.map +1 -1
  45. package/dist/routers/_app.js +4 -0
  46. package/dist/routers/_app.js.map +1 -0
  47. package/dist/routers/agenda.d.ts.map +1 -1
  48. package/dist/routers/agenda.js +4 -0
  49. package/dist/routers/agenda.js.map +1 -0
  50. package/dist/routers/announcement.d.ts.map +1 -1
  51. package/dist/routers/announcement.js +4 -0
  52. package/dist/routers/announcement.js.map +1 -0
  53. package/dist/routers/assignment.d.ts.map +1 -1
  54. package/dist/routers/assignment.js +4 -0
  55. package/dist/routers/assignment.js.map +1 -0
  56. package/dist/routers/attendance.d.ts.map +1 -1
  57. package/dist/routers/attendance.js +4 -0
  58. package/dist/routers/attendance.js.map +1 -0
  59. package/dist/routers/auth.d.ts.map +1 -1
  60. package/dist/routers/auth.js +4 -0
  61. package/dist/routers/auth.js.map +1 -0
  62. package/dist/routers/class.d.ts.map +1 -1
  63. package/dist/routers/class.js +4 -0
  64. package/dist/routers/class.js.map +1 -0
  65. package/dist/routers/comment.d.ts +0 -36
  66. package/dist/routers/comment.d.ts.map +1 -1
  67. package/dist/routers/comment.js +4 -21
  68. package/dist/routers/comment.js.map +1 -0
  69. package/dist/routers/conversation.d.ts.map +1 -1
  70. package/dist/routers/conversation.js +4 -0
  71. package/dist/routers/conversation.js.map +1 -0
  72. package/dist/routers/event.d.ts.map +1 -1
  73. package/dist/routers/event.js +4 -0
  74. package/dist/routers/event.js.map +1 -0
  75. package/dist/routers/file.d.ts.map +1 -1
  76. package/dist/routers/file.js +4 -0
  77. package/dist/routers/file.js.map +1 -0
  78. package/dist/routers/folder.d.ts.map +1 -1
  79. package/dist/routers/folder.js +4 -0
  80. package/dist/routers/folder.js.map +1 -0
  81. package/dist/routers/labChat.d.ts.map +1 -1
  82. package/dist/routers/labChat.js +4 -0
  83. package/dist/routers/labChat.js.map +1 -0
  84. package/dist/routers/marketing.d.ts.map +1 -1
  85. package/dist/routers/marketing.js +4 -0
  86. package/dist/routers/marketing.js.map +1 -0
  87. package/dist/routers/message.d.ts.map +1 -1
  88. package/dist/routers/message.js +4 -0
  89. package/dist/routers/message.js.map +1 -0
  90. package/dist/routers/notifications.d.ts.map +1 -1
  91. package/dist/routers/notifications.js +4 -0
  92. package/dist/routers/notifications.js.map +1 -0
  93. package/dist/routers/school.js +2 -0
  94. package/dist/routers/section.d.ts.map +1 -1
  95. package/dist/routers/section.js +4 -0
  96. package/dist/routers/section.js.map +1 -0
  97. package/dist/routers/user.d.ts.map +1 -1
  98. package/dist/routers/user.js +4 -0
  99. package/dist/routers/user.js.map +1 -0
  100. package/dist/routers/worksheet.d.ts +0 -39
  101. package/dist/routers/worksheet.d.ts.map +1 -1
  102. package/dist/routers/worksheet.js +22 -5
  103. package/dist/routers/worksheet.js.map +1 -0
  104. package/dist/seedDatabase.d.ts.map +1 -1
  105. package/dist/seedDatabase.js +4 -0
  106. package/dist/seedDatabase.js.map +1 -0
  107. package/dist/socket/handlers.d.ts.map +1 -1
  108. package/dist/socket/handlers.js +4 -0
  109. package/dist/socket/handlers.js.map +1 -0
  110. package/dist/trpc.d.ts.map +1 -1
  111. package/dist/trpc.js +4 -0
  112. package/dist/trpc.js.map +1 -0
  113. package/dist/types/trpc.d.ts.map +1 -1
  114. package/dist/types/trpc.js +4 -0
  115. package/dist/types/trpc.js.map +1 -0
  116. package/dist/utils/aiUser.d.ts.map +1 -1
  117. package/dist/utils/aiUser.js +4 -0
  118. package/dist/utils/aiUser.js.map +1 -0
  119. package/dist/utils/email.d.ts.map +1 -1
  120. package/dist/utils/email.js +4 -0
  121. package/dist/utils/email.js.map +1 -0
  122. package/dist/utils/generateInviteCode.d.ts.map +1 -1
  123. package/dist/utils/generateInviteCode.js +4 -0
  124. package/dist/utils/generateInviteCode.js.map +1 -0
  125. package/dist/utils/inference.d.ts.map +1 -1
  126. package/dist/utils/inference.js +4 -3
  127. package/dist/utils/inference.js.map +1 -0
  128. package/dist/utils/logger.d.ts.map +1 -1
  129. package/dist/utils/logger.js +4 -0
  130. package/dist/utils/logger.js.map +1 -0
  131. package/dist/utils/prismaErrorHandler.d.ts.map +1 -1
  132. package/dist/utils/prismaErrorHandler.js +4 -0
  133. package/dist/utils/prismaErrorHandler.js.map +1 -0
  134. package/dist/utils/prismaWrapper.d.ts.map +1 -1
  135. package/dist/utils/prismaWrapper.js +4 -0
  136. package/dist/utils/prismaWrapper.js.map +1 -0
  137. package/package.json +8 -3
  138. package/src/index.ts +42 -0
  139. package/src/instrument.ts +8 -0
  140. package/src/routers/comment.ts +1 -21
  141. package/src/routers/worksheet.ts +27 -4
  142. package/src/trpc.ts +2 -0
  143. package/src/utils/inference.ts +0 -4
  144. package/tsconfig.json +9 -2
package/TODO.md ADDED
@@ -0,0 +1,2 @@
1
+ router --> server --> model
2
+ router: make lots of middleware. call middleware
@@ -1 +1 @@
1
- {"version":3,"file":"exportType.d.ts","sourceRoot":"","sources":["../src/exportType.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"exportType.d.ts","sourceRoot":"/","sources":["exportType.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"}
@@ -3,4 +3,8 @@
3
3
  * This is used to export the types for the server
4
4
  * to the client via npmjs
5
5
  */
6
+
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a04570aa-7e76-52f1-b955-58b2dac7510a")}catch(e){}}();
6
8
  export {};
9
+ //# sourceMappingURL=exportType.js.map
10
+ //# debugId=a04570aa-7e76-52f1-b955-58b2dac7510a
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exportType.js","sources":["exportType.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Export types for the server\n * This is used to export the types for the server\n * to the client via npmjs\n */\n\nexport type { AppRouter } from \"./routers/_app.js\";\nexport type { RouterInputs } from \"./routers/_app.js\";\nexport type { RouterOutputs } from \"./routers/_app.js\";"],"names":[],"mappings":"AAAA;;;;GAIG","debug_id":"a04570aa-7e76-52f1-b955-58b2dac7510a"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export {};
1
+ import "./instrument.js";
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"AAiBA,OAAO,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
+
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="98b1ae42-791e-5668-a2f9-5b3781e34928")}catch(e){}}();
1
3
  import express from 'express';
2
4
  import { createServer } from 'http';
3
5
  import { Server } from 'socket.io';
@@ -10,6 +12,8 @@ import { logger } from './utils/logger.js';
10
12
  import { setupSocketHandlers } from './socket/handlers.js';
11
13
  import { bucket } from './lib/googleCloudStorage.js';
12
14
  import { prisma } from './lib/prisma.js';
15
+ import * as Sentry from "@sentry/node";
16
+ import "./instrument.js";
13
17
  dotenv.config();
14
18
  const app = express();
15
19
  // CORS middleware
@@ -77,11 +81,28 @@ app.use((req, res, next) => {
77
81
  });
78
82
  next();
79
83
  });
84
+ app.use("/panel", async (_, res) => {
85
+ if (process.env.NODE_ENV !== "development") {
86
+ return res.status(404).send("Not Found");
87
+ }
88
+ // Dynamically import renderTrpcPanel only in development
89
+ const { renderTrpcPanel } = await import("trpc-ui");
90
+ return res.send(renderTrpcPanel(appRouter, {
91
+ url: "/trpc", // Base url of your trpc server
92
+ meta: {
93
+ title: "Studious Backend",
94
+ description: "This is the backend for the Studious application.",
95
+ },
96
+ }));
97
+ });
80
98
  // Create HTTP server
81
99
  const httpServer = createServer(app);
82
100
  app.get('/health', (req, res) => {
83
101
  res.status(200).json({ message: 'OK' });
84
102
  });
103
+ app.get('/test-sentry', (req, res) => {
104
+ throw new Error('Test error');
105
+ });
85
106
  // Setup Socket.IO
86
107
  const io = new Server(httpServer, {
87
108
  cors: {
@@ -361,6 +382,15 @@ app.use('/trpc', createExpressMiddleware({
361
382
  return createTRPCContext({ req, res });
362
383
  },
363
384
  }));
385
+ // IMPORTANT: Sentry error handler must be added AFTER all other middleware and routes
386
+ // but BEFORE any other error handlers
387
+ Sentry.setupExpressErrorHandler(app);
388
+ // app.use(function onError(err, req, res, next) {
389
+ // // The error id is attached to `res.sentry` to be returned
390
+ // // and optionally displayed to the user for support.
391
+ // res.statusCode = 500;
392
+ // res.end(res.sentry + "\n");
393
+ // });
364
394
  const PORT = process.env.PORT || 3001;
365
395
  httpServer.listen(PORT, () => {
366
396
  logger.info(`Server running on port ${PORT}`, {
@@ -385,3 +415,5 @@ logger.info('CORS Configuration', {
385
415
  process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'
386
416
  ]
387
417
  });
418
+ //# sourceMappingURL=index.js.map
419
+ //# debugId=98b1ae42-791e-5668-a2f9-5b3781e34928
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["index.ts"],"sourceRoot":"/","sourcesContent":["import express from 'express';\nimport type { Request, Response } from 'express';\nimport { createServer } from 'http';\nimport { Server } from 'socket.io';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport { createExpressMiddleware } from '@trpc/server/adapters/express';\nimport { appRouter } from './routers/_app.js';\nimport { createTRPCContext, createCallerFactory } from './trpc.js';\nimport { logger } from './utils/logger.js';\nimport { setupSocketHandlers } from './socket/handlers.js';\nimport { bucket } from './lib/googleCloudStorage.js';\nimport { prisma } from './lib/prisma.js';\nimport * as Sentry from \"@sentry/node\";\n\nimport { renderTrpcPanel } from \"trpc-panel\";\n\nimport \"./instrument.js\";\n\ndotenv.config();\n\nconst app = express();\n\n// CORS middleware\napp.use(cors({\n origin: [\n 'http://localhost:3000', // Frontend development server\n 'http://localhost:3001', // Server port\n 'http://127.0.0.1:3000', // Alternative localhost\n 'http://127.0.0.1:3001', // Alternative localhost\n 'https://www.studious.sh', // Production frontend\n 'https://studious.sh', // Production frontend (without www)\n process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'\n ],\n credentials: true,\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\n allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'x-user'],\n optionsSuccessStatus: 200\n}));\n\n// Handle preflight OPTIONS requests\napp.options('*', (req, res) => {\n const allowedOrigins = [\n 'http://localhost:3000',\n 'http://localhost:3001', \n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:3001',\n 'https://www.studious.sh', // Production frontend\n 'https://studious.sh', // Production frontend (without www)\n process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'\n ];\n \n const origin = req.headers.origin;\n if (origin && allowedOrigins.includes(origin)) {\n res.header('Access-Control-Allow-Origin', origin);\n } else {\n res.header('Access-Control-Allow-Origin', 'http://localhost:3000');\n }\n \n res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');\n res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With, x-user');\n res.header('Access-Control-Allow-Credentials', 'true');\n res.sendStatus(200);\n});\n\n// CORS debugging middleware\napp.use((req, res, next) => {\n if (req.method === 'OPTIONS' || req.path.includes('trpc')) {\n logger.info('CORS Request', {\n method: req.method,\n path: req.path,\n origin: req.headers.origin,\n userAgent: req.headers['user-agent']\n });\n }\n next();\n});\n\n// Response time logging middleware\napp.use((req, res, next) => {\n const start = Date.now();\n res.on('finish', () => {\n const duration = Date.now() - start;\n logger.info('Request completed', {\n method: req.method,\n path: req.path,\n statusCode: res.statusCode,\n duration: `${duration}ms`\n });\n });\n next();\n});\n\napp.use(\"/panel\", async (_, res) => {\n if (process.env.NODE_ENV !== \"development\") {\n return res.status(404).send(\"Not Found\");\n }\n\n // Dynamically import renderTrpcPanel only in development\n const { renderTrpcPanel } = await import(\"trpc-ui\");\n\n return res.send(\n renderTrpcPanel(appRouter, {\n url: \"/trpc\", // Base url of your trpc server\n meta: {\n title: \"Studious Backend\",\n description:\n \"This is the backend for the Studious application.\",\n },\n })\n );\n});\n\n\n// Create HTTP server\nconst httpServer = createServer(app);\n\napp.get('/health', (req, res) => {\n res.status(200).json({ message: 'OK' });\n});\n\napp.get('/test-sentry', (req, res) => {\n throw new Error('Test error');\n});\n\n// Setup Socket.IO\nconst io = new Server(httpServer, {\n cors: {\n origin: [\n 'http://localhost:3000', // Frontend development server\n 'http://localhost:3001', // Server port\n 'http://127.0.0.1:3000', // Alternative localhost\n 'http://127.0.0.1:3001', // Alternative localhost\n 'https://www.studious.sh', // Production frontend\n 'https://studious.sh', // Production frontend (without www)\n process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'\n ],\n methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\n credentials: true,\n allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'Access-Control-Allow-Origin', 'x-user']\n },\n transports: ['websocket', 'polling'],\n pingTimeout: 60000,\n pingInterval: 25000,\n connectTimeout: 45000,\n path: '/socket.io/',\n allowEIO3: true\n});\n\n// Add server-level logging\nio.engine.on('connection_error', (err: Error) => {\n logger.error('Socket connection error', { error: err.message });\n});\n\n// Setup socket handlers\nsetupSocketHandlers(io);\n\n// File serving endpoint for secure file access\napp.get('/api/files/:fileId', async (req, res) => {\n try {\n const fileId = decodeURIComponent(req.params.fileId);\n // console.log('File request:', { fileId, originalPath: req.params.fileId });\n \n // Get user from request headers\n const userHeader = req.headers['x-user'];\n if (!userHeader) {\n return res.status(401).json({ error: 'Authentication required' });\n }\n\n const token = typeof userHeader === 'string' ? userHeader : userHeader[0];\n\n // Find user by session token\n const user = await prisma.user.findFirst({\n where: {\n sessions: {\n some: {\n id: token\n }\n }\n },\n select: {\n id: true,\n username: true,\n }\n });\n\n if (!user) {\n return res.status(401).json({ error: 'Invalid or expired session' });\n }\n\n // Find file in database by path\n const fileRecord = await prisma.file.findFirst({\n where: { id: fileId },\n include: {\n user: true,\n assignment: {\n include: {\n class: {\n include: {\n students: true,\n teachers: true\n }\n }\n }\n },\n submission: {\n include: {\n student: true,\n assignment: {\n include: {\n class: {\n include: {\n teachers: true\n }\n }\n }\n }\n }\n },\n annotations: {\n include: {\n student: true,\n assignment: {\n include: {\n class: {\n include: {\n teachers: true\n }\n }\n }\n }\n }\n },\n folder: {\n include: {\n class: {\n include: {\n students: true,\n teachers: true\n }\n }\n }\n },\n classDraft: {\n include: {\n students: true,\n teachers: true\n }\n }\n }\n });\n\n if (!fileRecord) {\n return res.status(404).json({ error: 'File not found in database' });\n }\n\n // Check if user has permission to access this file\n let hasPermission = false;\n\n // Check if user created the file\n if (fileRecord.userId === user.id) {\n hasPermission = true;\n }\n\n // Check if file is related to a class where user is a member\n if (!hasPermission) {\n // Check assignment files\n if (fileRecord.assignment?.class) {\n const classData = fileRecord.assignment.class;\n const isStudent = classData.students.some(student => student.id === user.id);\n const isTeacher = classData.teachers.some(teacher => teacher.id === user.id);\n if (isStudent || isTeacher) {\n hasPermission = true;\n }\n }\n\n if (!hasPermission && fileRecord.annotations) {\n const annotation = fileRecord.annotations;\n if (annotation.studentId === user.id) {\n hasPermission = true;\n } else if (annotation.assignment?.class?.teachers.some(teacher => teacher.id === user.id)) {\n hasPermission = true;\n }\n }\n\n // Check submission files (student can access their own submissions, teachers can access all submissions in their class)\n if (!hasPermission && fileRecord.submission) {\n const submission = fileRecord.submission;\n if (submission.studentId === user.id) {\n hasPermission = true; // Student accessing their own submission\n } else if (submission.assignment?.class?.teachers.some(teacher => teacher.id === user.id)) {\n hasPermission = true; // Teacher accessing submission in their class\n }\n }\n\n // Check folder files\n if (!hasPermission && fileRecord.folder?.class) {\n const classData = fileRecord.folder.class;\n const isStudent = classData.students.some(student => student.id === user.id);\n const isTeacher = classData.teachers.some(teacher => teacher.id === user.id);\n if (isStudent || isTeacher) {\n hasPermission = true;\n }\n }\n\n // Check class draft files\n if (!hasPermission && fileRecord.classDraft) {\n const classData = fileRecord.classDraft;\n const isStudent = classData.students.some(student => student.id === user.id);\n const isTeacher = classData.teachers.some(teacher => teacher.id === user.id);\n if (isStudent || isTeacher) {\n hasPermission = true;\n }\n }\n }\n\n if (!hasPermission) {\n return res.status(403).json({ error: 'Access denied - insufficient permissions' });\n }\n \n const filePath = fileRecord.path;\n \n // Get file from Google Cloud Storage\n const file = bucket.file(filePath);\n const [exists] = await file.exists();\n \n if (!exists) {\n return res.status(404).json({ error: 'File not found in storage', filePath });\n }\n \n // Get file metadata\n const [metadata] = await file.getMetadata();\n \n // Set appropriate headers\n res.set({\n 'Content-Type': metadata.contentType || 'application/octet-stream',\n 'Content-Length': metadata.size,\n 'Cache-Control': 'public, max-age=31536000', // 1 year cache\n 'ETag': metadata.etag,\n });\n \n // Stream file to response\n const stream = file.createReadStream();\n stream.pipe(res);\n \n stream.on('error', (error) => {\n logger.error('Error streaming file:', {error});\n if (!res.headersSent) {\n res.status(500).json({ error: 'Error streaming file' });\n }\n });\n \n } catch (error) {\n logger.error('Error serving file:', {error});\n res.status(500).json({ error: 'Internal server error' });\n }\n});\n\n// File upload endpoint for secure file uploads (supports both POST and PUT)\napp.post('/api/upload/:filePath', async (req, res) => {\n handleFileUpload(req, res);\n});\n\napp.put('/api/upload/:filePath', async (req, res) => {\n handleFileUpload(req, res);\n});\n\nfunction handleFileUpload(req: any, res: any) {\n try {\n const filePath = decodeURIComponent(req.params.filePath);\n \n // Set CORS headers for upload endpoint\n const origin = req.headers.origin;\n const allowedOrigins = [\n 'http://localhost:3000',\n 'http://localhost:3001', \n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:3001',\n 'https://www.studious.sh', // Production frontend\n 'https://studious.sh', // Production frontend (without www)\n process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'\n ];\n \n if (origin && allowedOrigins.includes(origin)) {\n res.header('Access-Control-Allow-Origin', origin);\n } else {\n res.header('Access-Control-Allow-Origin', 'http://localhost:3000');\n }\n \n res.header('Access-Control-Allow-Credentials', 'true');\n \n // Get content type from headers\n const contentType = req.headers['content-type'] || 'application/octet-stream';\n \n // Create a new file in the bucket\n const file = bucket.file(filePath);\n \n // Create a write stream to Google Cloud Storage\n const writeStream = file.createWriteStream({\n metadata: {\n contentType,\n },\n });\n \n // Handle stream events\n writeStream.on('error', (error) => {\n logger.error('Error uploading file:', {error});\n if (!res.headersSent) {\n res.status(500).json({ error: 'Error uploading file' });\n }\n });\n \n writeStream.on('finish', () => {\n res.status(200).json({ \n success: true, \n filePath,\n message: 'File uploaded successfully' \n });\n });\n \n // Pipe the request body to the write stream\n req.pipe(writeStream);\n \n } catch (error) {\n logger.error('Error handling file upload:', {error});\n res.status(500).json({ error: 'Internal server error' });\n }\n}\n\n// Create caller\nconst createCaller = createCallerFactory(appRouter);\n\n// Setup tRPC middleware\napp.use(\n '/trpc',\n createExpressMiddleware({\n router: appRouter,\n createContext: async ({ req, res }: { req: Request; res: Response }) => {\n return createTRPCContext({ req, res });\n },\n })\n);\n\n// IMPORTANT: Sentry error handler must be added AFTER all other middleware and routes\n// but BEFORE any other error handlers\nSentry.setupExpressErrorHandler(app);\n\n// app.use(function onError(err, req, res, next) {\n// // The error id is attached to `res.sentry` to be returned\n// // and optionally displayed to the user for support.\n// res.statusCode = 500;\n// res.end(res.sentry + \"\\n\");\n// });\n\n\nconst PORT = process.env.PORT || 3001;\n\nhttpServer.listen(PORT, () => {\n logger.info(`Server running on port ${PORT}`, { \n port: PORT,\n services: ['tRPC', 'Socket.IO']\n });\n}); \n\n// log all env variables\nlogger.info('Configurations', {\n NODE_ENV: process.env.NODE_ENV,\n PORT: process.env.PORT,\n NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,\n LOG_MODE: process.env.LOG_MODE,\n});\n\n// Log CORS configuration\nlogger.info('CORS Configuration', {\n allowedOrigins: [\n 'http://localhost:3000',\n 'http://localhost:3001', \n 'http://127.0.0.1:3000',\n 'http://127.0.0.1:3001',\n process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'\n ]\n});"],"names":[],"mappings":"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","debug_id":"98b1ae42-791e-5668-a2f9-5b3781e34928"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=instrument.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instrument.d.ts","sourceRoot":"/","sources":["instrument.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3b5b7cd2-f37c-57ab-8732-c3fffd851def")}catch(e){}}();
3
+ import * as Sentry from "@sentry/node";
4
+ Sentry.init({
5
+ dsn: "https://5440f33877e8e19d7644624f5d3d2f10@o4510401976860672.ingest.de.sentry.io/4510402093514832",
6
+ // Setting this option to true will send default PII data to Sentry.
7
+ // For example, automatic IP address collection on events
8
+ sendDefaultPii: true,
9
+ });
10
+ //# sourceMappingURL=instrument.js.map
11
+ //# debugId=3b5b7cd2-f37c-57ab-8732-c3fffd851def
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instrument.js","sources":["instrument.ts"],"sourceRoot":"/","sourcesContent":["import * as Sentry from \"@sentry/node\";\n\nSentry.init({\n dsn: \"https://5440f33877e8e19d7644624f5d3d2f10@o4510401976860672.ingest.de.sentry.io/4510402093514832\",\n // Setting this option to true will send default PII data to Sentry.\n // For example, automatic IP address collection on events\n sendDefaultPii: true,\n});\n"],"names":[],"mappings":";;AAAA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AAEvC,MAAM,CAAC,IAAI,CAAC;IACV,GAAG,EAAE,iGAAiG;IACtG,oEAAoE;IACpE,yDAAyD;IACzD,cAAc,EAAE,IAAI;CACrB,CAAC,CAAC","debug_id":"3b5b7cd2-f37c-57ab-8732-c3fffd851def"}
@@ -1 +1 @@
1
- {"version":3,"file":"fileUpload.d.ts","sourceRoot":"","sources":["../../src/lib/fileUpload.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAEd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAEd;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,IAAI,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB;AAKD;;GAEG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,YAAY,CAAC,CAKvB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,QAAQ,EAAE,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAKzB;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUlE;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,gBAAgB,CAAC,CA8F3B;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,OAAO,EACtB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CA+Df;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,cAAc,EAAE,EACvB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAiB7B"}
1
+ {"version":3,"file":"fileUpload.d.ts","sourceRoot":"/","sources":["lib/fileUpload.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAEd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAEd;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,IAAI,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB;AAKD;;GAEG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,YAAY,CAAC,CAKvB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,QAAQ,EAAE,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAKzB;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUlE;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,gBAAgB,CAAC,CA8F3B;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,OAAO,EACtB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CA+Df;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,cAAc,EAAE,EACvB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,YAAY,CAAC,EAAE,MAAM,EACrB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAiB7B"}
@@ -1,3 +1,5 @@
1
+
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3f314f15-c12a-5b67-8292-da15932c8b4f")}catch(e){}}();
1
3
  import { TRPCError } from "@trpc/server";
2
4
  import { v4 as uuidv4 } from "uuid";
3
5
  import { getSignedUrl, objectExists } from "./googleCloudStorage.js";
@@ -266,3 +268,5 @@ export async function createDirectUploadFiles(files, userId, directory, assignme
266
268
  });
267
269
  }
268
270
  }
271
+ //# sourceMappingURL=fileUpload.js.map
272
+ //# debugId=3f314f15-c12a-5b67-8292-da15932c8b4f
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileUpload.js","sources":["lib/fileUpload.ts"],"sourceRoot":"/","sourcesContent":["import { TRPCError } from \"@trpc/server\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { getSignedUrl, objectExists } from \"./googleCloudStorage.js\";\nimport { generateMediaThumbnail } from \"./thumbnailGenerator.js\";\nimport { prisma } from \"./prisma.js\";\nimport { logger } from \"../utils/logger.js\";\n\nexport interface FileData {\n name: string;\n type: string;\n size: number;\n // No data field - for direct file uploads\n}\n\nexport interface DirectFileData {\n name: string;\n type: string;\n size: number;\n // No data field - for direct file uploads\n}\n\nexport interface UploadedFile {\n id: string;\n name: string;\n type: string;\n size: number;\n path: string;\n thumbnailId?: string;\n}\n\nexport interface DirectUploadFile {\n id: string;\n name: string;\n type: string;\n size: number;\n path: string;\n uploadUrl: string;\n uploadExpiresAt: Date;\n uploadSessionId: string;\n}\n\n// DEPRECATED: These functions are no longer used - files are uploaded directly to GCS\n// Use createDirectUploadFile() and createDirectUploadFiles() instead\n\n/**\n * @deprecated Use createDirectUploadFile instead\n */\nexport async function uploadFile(\n file: FileData,\n userId: string,\n directory?: string,\n assignmentId?: string\n): Promise<UploadedFile> {\n throw new TRPCError({\n code: 'NOT_IMPLEMENTED',\n message: 'uploadFile is deprecated. Use createDirectUploadFile instead.',\n });\n}\n\n/**\n * @deprecated Use createDirectUploadFiles instead\n */\nexport async function uploadFiles(\n files: FileData[], \n userId: string,\n directory?: string\n): Promise<UploadedFile[]> {\n throw new TRPCError({\n code: 'NOT_IMPLEMENTED',\n message: 'uploadFiles is deprecated. Use createDirectUploadFiles instead.',\n });\n}\n\n/**\n * Gets a signed URL for a file\n * @param filePath The path of the file in Google Cloud Storage\n * @returns The signed URL\n */\nexport async function getFileUrl(filePath: string): Promise<string> {\n try {\n return await getSignedUrl(filePath);\n } catch (error) {\n console.error('Error getting signed URL:', error);\n throw new TRPCError({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'Failed to get file URL',\n });\n }\n}\n\n/**\n * Creates a file record for direct upload and generates signed URL\n * @param file The file metadata (no base64 data)\n * @param userId The ID of the user uploading the file\n * @param directory Optional directory to store the file in\n * @param assignmentId Optional assignment ID to associate the file with\n * @param submissionId Optional submission ID to associate the file with\n * @returns The direct upload file information with signed URL\n */\nexport async function createDirectUploadFile(\n file: DirectFileData,\n userId: string,\n directory?: string,\n assignmentId?: string,\n submissionId?: string,\n announcementId?: string\n): Promise<DirectUploadFile> {\n try {\n // Validate file extension matches MIME type\n const fileExtension = file.name.split('.').pop()?.toLowerCase();\n const mimeType = file.type.toLowerCase();\n \n const extensionMimeMap: Record<string, string[]> = {\n 'jpg': ['image/jpeg'],\n 'jpeg': ['image/jpeg'],\n 'png': ['image/png'],\n 'gif': ['image/gif'],\n 'webp': ['image/webp']\n };\n \n if (fileExtension && extensionMimeMap[fileExtension]) {\n if (!extensionMimeMap[fileExtension].includes(mimeType)) {\n throw new Error(`File extension .${fileExtension} does not match MIME type ${mimeType}`);\n }\n }\n \n // Create a unique filename\n const uniqueFilename = `${uuidv4()}.${fileExtension}`;\n \n // Construct the full path\n const filePath = directory \n ? `${directory}/${uniqueFilename}`\n : uniqueFilename;\n \n // Generate upload session ID\n const uploadSessionId = uuidv4();\n \n // Generate backend proxy upload URL (not direct GCS)\n const baseUrl = process.env.BACKEND_URL || 'http://localhost:3001';\n const uploadUrl = `${baseUrl}/api/upload/${encodeURIComponent(filePath)}`;\n const uploadExpiresAt = new Date(Date.now() + 15 * 60 * 1000); // 15 minutes from now\n \n // Create file record in database with PENDING status\n const fileRecord = await prisma.file.create({\n data: {\n name: file.name,\n type: file.type,\n size: file.size,\n path: filePath,\n uploadStatus: 'PENDING',\n uploadUrl,\n uploadExpiresAt,\n uploadSessionId,\n user: {\n connect: { id: userId }\n },\n ...(directory && {\n folder: {\n connect: {id: directory},\n },\n }),\n ...(assignmentId && {\n assignment: {\n connect: { id: assignmentId }\n }\n }),\n ...(submissionId && {\n submission: {\n connect: { id: submissionId }\n }\n }),\n ...(announcementId && {\n announcement: {\n connect: { id: announcementId }\n }\n })\n },\n });\n \n return {\n id: fileRecord.id,\n name: file.name,\n type: file.type,\n size: file.size,\n path: filePath,\n uploadUrl,\n uploadExpiresAt,\n uploadSessionId\n };\n } catch (error) {\n logger.error('Error creating direct upload file:', {error: error instanceof Error ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n } : error});\n throw new TRPCError({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'Failed to create direct upload file',\n });\n }\n}\n\n/**\n * Confirms a direct upload was successful\n * @param fileId The ID of the file record\n * @param uploadSuccess Whether the upload was successful\n * @param errorMessage Optional error message if upload failed\n */\nexport async function confirmDirectUpload(\n fileId: string,\n uploadSuccess: boolean,\n errorMessage?: string\n): Promise<void> {\n try {\n // First fetch the file record to get the object path\n const fileRecord = await prisma.file.findUnique({\n where: { id: fileId },\n select: { path: true }\n });\n\n if (!fileRecord) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: 'File record not found',\n });\n }\n\n let actualUploadSuccess = uploadSuccess;\n let actualErrorMessage = errorMessage;\n\n // If uploadSuccess is true, verify the object actually exists in GCS\n if (uploadSuccess) {\n try {\n const exists = await objectExists(process.env.GOOGLE_CLOUD_BUCKET_NAME!, fileRecord.path);\n if (!exists) {\n actualUploadSuccess = false;\n actualErrorMessage = 'File upload reported as successful but object not found in Google Cloud Storage';\n logger.error(`File upload verification failed for ${fileId}: object ${fileRecord.path} not found in GCS`);\n }\n } catch (error) {\n logger.error(`Error verifying file existence in GCS for ${fileId}:`, {error: error instanceof Error ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n } : error});\n actualUploadSuccess = false;\n actualErrorMessage = 'Failed to verify file existence in Google Cloud Storage';\n }\n }\n\n const updateData: any = {\n uploadStatus: actualUploadSuccess ? 'COMPLETED' : 'FAILED',\n uploadProgress: actualUploadSuccess ? 100 : 0,\n };\n \n if (!actualUploadSuccess && actualErrorMessage) {\n updateData.uploadError = actualErrorMessage;\n updateData.uploadRetryCount = { increment: 1 };\n }\n \n if (actualUploadSuccess) {\n updateData.uploadedAt = new Date();\n }\n \n await prisma.file.update({\n where: { id: fileId },\n data: updateData\n });\n } catch (error) {\n logger.error('Error confirming direct upload:', {error});\n throw new TRPCError({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'Failed to confirm upload',\n });\n }\n}\n\n/**\n * Updates upload progress for a direct upload\n * @param fileId The ID of the file record\n * @param progress Progress percentage (0-100)\n */\nexport async function updateUploadProgress(\n fileId: string,\n progress: number\n): Promise<void> {\n try {\n // await prisma.file.update({\n // where: { id: fileId },\n // data: {\n // uploadStatus: 'UPLOADING',\n // uploadProgress: Math.min(100, Math.max(0, progress))\n // }\n // });\n const current = await prisma.file.findUnique({ where: { id: fileId }, select: { uploadStatus: true } });\n if (!current || ['COMPLETED','FAILED','CANCELLED'].includes(current.uploadStatus as string)) return;\n const clamped = Math.min(100, Math.max(0, progress));\n await prisma.file.update({\n where: { id: fileId },\n data: {\n uploadStatus: 'UPLOADING',\n uploadProgress: clamped\n }\n });\n } catch (error) {\n logger.error('Error updating upload progress:', {error: error instanceof Error ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n } : error}); \n throw new TRPCError({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'Failed to update upload progress',\n });\n }\n}\n\n/**\n * Creates multiple direct upload files\n * @param files Array of file metadata\n * @param userId The ID of the user uploading the files\n * @param directory Optional subdirectory to store the files in\n * @param assignmentId Optional assignment ID to associate files with\n * @param submissionId Optional submission ID to associate files with\n * @returns Array of direct upload file information\n */\nexport async function createDirectUploadFiles(\n files: DirectFileData[], \n userId: string,\n directory?: string,\n assignmentId?: string,\n submissionId?: string,\n announcementId?: string\n): Promise<DirectUploadFile[]> {\n try {\n const uploadPromises = files.map(file => \n createDirectUploadFile(file, userId, directory, assignmentId, submissionId, announcementId)\n );\n return await Promise.all(uploadPromises);\n } catch (error) {\n logger.error('Error creating direct upload files:', {error: error instanceof Error ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n } : error});\n throw new TRPCError({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'Failed to create direct upload files',\n });\n }\n}"],"names":[],"mappings":"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","debug_id":"3f314f15-c12a-5b67-8292-da15932c8b4f"}
@@ -1 +1 @@
1
- {"version":3,"file":"googleCloudStorage.d.ts","sourceRoot":"","sources":["../../src/lib/googleCloudStorage.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,MAAM,wCAAwD,CAAC;AAQ5E;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,GAAG,OAAgB,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsB7H;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhE;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAW3F"}
1
+ {"version":3,"file":"googleCloudStorage.d.ts","sourceRoot":"/","sources":["lib/googleCloudStorage.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,MAAM,wCAAwD,CAAC;AAQ5E;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,GAAG,OAAgB,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsB7H;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhE;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAW3F"}
@@ -1,3 +1,5 @@
1
+
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9b454706-4b58-5463-84af-0b042762f2e8")}catch(e){}}();
1
3
  import dotenv from 'dotenv';
2
4
  dotenv.config();
3
5
  import { Storage } from '@google-cloud/storage';
@@ -76,3 +78,5 @@ export async function objectExists(bucketName, objectPath) {
76
78
  });
77
79
  }
78
80
  }
81
+ //# sourceMappingURL=googleCloudStorage.js.map
82
+ //# debugId=9b454706-4b58-5463-84af-0b042762f2e8
@@ -0,0 +1 @@
1
+ {"version":3,"file":"googleCloudStorage.js","sources":["lib/googleCloudStorage.ts"],"sourceRoot":"/","sourcesContent":["import dotenv from 'dotenv';\ndotenv.config();\nimport { Storage } from '@google-cloud/storage';\nimport { TRPCError } from '@trpc/server';\n\nconst storage = new Storage({\n projectId: process.env.GOOGLE_CLOUD_PROJECT_ID,\n credentials: {\n client_email: process.env.GOOGLE_CLOUD_CLIENT_EMAIL,\n private_key: process.env.GOOGLE_CLOUD_PRIVATE_KEY?.replace(/\\\\n/g, '\\n'),\n },\n});\n\nexport const bucket = storage.bucket(process.env.GOOGLE_CLOUD_BUCKET_NAME!);\n\n// Short expiration time for signed URLs (5 minutes)\nconst SIGNED_URL_EXPIRATION = 5 * 60 * 1000;\n\n// DEPRECATED: This function is no longer used - files are uploaded directly to GCS\n// The backend proxy upload endpoint in index.ts handles direct uploads\n\n/**\n * Gets a signed URL for a file\n * @param filePath The path of the file in the bucket\n * @returns The signed URL\n */\nexport async function getSignedUrl(filePath: string, action: 'read' | 'write' = 'read', contentType?: string): Promise<string> {\n try {\n const options: any = {\n version: 'v4',\n action: action,\n expires: Date.now() + SIGNED_URL_EXPIRATION,\n };\n\n // For write operations, add content type if provided\n if (action === 'write' && contentType) {\n options.contentType = contentType;\n }\n\n const [url] = await bucket.file(filePath).getSignedUrl(options);\n return url;\n } catch (error) {\n console.error('Error getting signed URL:', error);\n throw new TRPCError({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'Failed to get signed URL',\n });\n }\n}\n\n/**\n * Deletes a file from Google Cloud Storage\n * @param filePath The path of the file to delete\n */\nexport async function deleteFile(filePath: string): Promise<void> {\n try {\n await bucket.file(filePath).delete();\n } catch (error) {\n console.error('Error deleting file from Google Cloud Storage:', error);\n throw new TRPCError({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'Failed to delete file from storage',\n });\n }\n}\n\n/**\n * Checks if an object exists in Google Cloud Storage\n * @param bucketName The name of the bucket (unused, uses default bucket)\n * @param objectPath The path of the object to check\n * @returns Promise<boolean> True if the object exists, false otherwise\n */\nexport async function objectExists(bucketName: string, objectPath: string): Promise<boolean> {\n try {\n const [exists] = await bucket.file(objectPath).exists();\n return exists;\n } catch (error) {\n console.error('Error checking if object exists in Google Cloud Storage:', error);\n throw new TRPCError({\n code: 'INTERNAL_SERVER_ERROR',\n message: 'Failed to check object existence',\n });\n }\n} "],"names":[],"mappings":";;AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,MAAM,CAAC,MAAM,EAAE,CAAC;AAChB,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB;IAC9C,WAAW,EAAE;QACX,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB;QACnD,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC;KACzE;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAyB,CAAC,CAAC;AAE5E,oDAAoD;AACpD,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAE5C,mFAAmF;AACnF,uEAAuE;AAEvE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB,EAAE,SAA2B,MAAM,EAAE,WAAoB;IAC1G,IAAI,CAAC;QACH,MAAM,OAAO,GAAQ;YACnB,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,qBAAqB;SAC5C,CAAC;QAEF,qDAAqD;QACrD,IAAI,MAAM,KAAK,OAAO,IAAI,WAAW,EAAE,CAAC;YACtC,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC;QACpC,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAChE,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;QAClD,MAAM,IAAI,SAAS,CAAC;YAClB,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EAAE,0BAA0B;SACpC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC;IACvC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,gDAAgD,EAAE,KAAK,CAAC,CAAC;QACvE,MAAM,IAAI,SAAS,CAAC;YAClB,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EAAE,oCAAoC;SAC9C,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAAkB,EAAE,UAAkB;IACvE,IAAI,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC;QACxD,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,0DAA0D,EAAE,KAAK,CAAC,CAAC;QACjF,MAAM,IAAI,SAAS,CAAC;YAClB,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EAAE,kCAAkC;SAC5C,CAAC,CAAC;IACL,CAAC;AACH,CAAC","debug_id":"9b454706-4b58-5463-84af-0b042762f2e8"}
@@ -1 +1 @@
1
- {"version":3,"file":"jsonConversion.d.ts","sourceRoot":"","sources":["../../src/lib/jsonConversion.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAsB,MAAM,iBAAiB,CAAA;AAEnE,wBAAsB,SAAS,CAAC,MAAM,EAAE,aAAa,EAAE,wCAouBtD"}
1
+ {"version":3,"file":"jsonConversion.d.ts","sourceRoot":"/","sources":["lib/jsonConversion.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAsB,MAAM,iBAAiB,CAAA;AAEnE,wBAAsB,SAAS,CAAC,MAAM,EAAE,aAAa,EAAE,wCAouBtD"}
@@ -1,3 +1,5 @@
1
+
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9dcef6bc-81ec-59b1-ba5e-2017ff5b9c66")}catch(e){}}();
1
3
  import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';
2
4
  import fontkit from '@pdf-lib/fontkit';
3
5
  import { readFileSync } from 'fs';
@@ -681,3 +683,5 @@ export async function createPdf(blocks) {
681
683
  throw error;
682
684
  }
683
685
  }
686
+ //# sourceMappingURL=jsonConversion.js.map
687
+ //# debugId=9dcef6bc-81ec-59b1-ba5e-2017ff5b9c66
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonConversion.js","sources":["lib/jsonConversion.ts"],"sourceRoot":"/","sourcesContent":["import { PDFDocument, PDFFont, RGB, StandardFonts, last, rgb } from 'pdf-lib'\nimport fontkit from '@pdf-lib/fontkit'\nimport { readFileSync } from 'fs'\nimport { join } from 'path'\nimport { writeFile } from 'fs'\nimport { DocumentBlock, FormatTypes, Fonts } from './jsonStyles.js'\n\nexport async function createPdf(blocks: DocumentBlock[]) {\n console.log('createPdf: Starting PDF creation with', blocks.length, 'blocks');\n try {\n const pdfDoc = await PDFDocument.create()\n console.log('createPdf: PDFDocument created successfully');\n \n // Register fontkit to enable custom font embedding\n pdfDoc.registerFontkit(fontkit)\n \n // Load Unicode-compatible fonts (Noto Sans)\n const fontDir = join(process.cwd(), 'src', 'lib')\n \n let notoSansRegular: PDFFont\n let notoSansBold: PDFFont\n let notoSansItalic: PDFFont\n let courierFont: PDFFont\n \n try {\n // Try to load custom Unicode fonts\n const regularFontBytes = readFileSync(join(fontDir, 'NotoSans-Regular.ttf'))\n const boldFontBytes = readFileSync(join(fontDir, 'NotoSans-Bold.ttf'))\n const italicFontBytes = readFileSync(join(fontDir, 'NotoSans-Italic.ttf'))\n \n notoSansRegular = await pdfDoc.embedFont(regularFontBytes)\n notoSansBold = await pdfDoc.embedFont(boldFontBytes)\n notoSansItalic = await pdfDoc.embedFont(italicFontBytes)\n courierFont = await pdfDoc.embedFont(StandardFonts.Courier) // Keep Courier for code blocks\n \n console.log('createPdf: Unicode fonts loaded successfully');\n } catch (fontError) {\n console.warn('createPdf: Failed to load custom fonts, falling back to standard fonts:', fontError);\n // Fallback to standard fonts if custom fonts fail\n notoSansRegular = await pdfDoc.embedFont(StandardFonts.Helvetica)\n notoSansBold = await pdfDoc.embedFont(StandardFonts.HelveticaBold)\n notoSansItalic = await pdfDoc.embedFont(StandardFonts.HelveticaOblique)\n courierFont = await pdfDoc.embedFont(StandardFonts.Courier)\n }\n\n const defaultFont = notoSansRegular\n const defaultParagraphSpacing = 10;\n const defaultLineHeight = 1.3\n const defaultFontSize = 12\n const defaultIndentWidth = 14\n const defaultPadding = 10\n\n const headingColor = rgb(0.1, 0.1, 0.1)\n const paragraphColor = rgb(0.15, 0.15, 0.15)\n\n const FONTS: Record<number, PDFFont> = {\n [Fonts.TIMES_ROMAN]: notoSansRegular, // Use Noto Sans instead of Times\n [Fonts.COURIER]: courierFont,\n [Fonts.HELVETICA]: notoSansRegular,\n [Fonts.HELVETICA_BOLD]: notoSansBold,\n [Fonts.HELVETICA_ITALIC]: notoSansItalic,\n [Fonts.HELVETICA_BOLD_ITALIC]: notoSansBold, // Use bold for now, could add bold-italic later\n }\n\n const STYLE_PRESETS: Record<number,\n { fontSize: number; lineHeight: number; paragraphSpacing?: number; font?: PDFFont; color?: RGB; background?: RGB }> =\n {\n [FormatTypes.HEADER_1]: { fontSize: 28, lineHeight: 1.35, font: notoSansBold, color: headingColor },\n [FormatTypes.HEADER_2]: { fontSize: 22, lineHeight: 1.35, font: notoSansBold, color: headingColor },\n [FormatTypes.HEADER_3]: { fontSize: 18, lineHeight: 1.35, font: notoSansBold, color: headingColor },\n [FormatTypes.HEADER_4]: { fontSize: 16, lineHeight: 1.3, font: notoSansBold, color: headingColor },\n [FormatTypes.HEADER_5]: { fontSize: 14, lineHeight: 1.3, font: notoSansBold, color: headingColor },\n [FormatTypes.HEADER_6]: { fontSize: 12, lineHeight: 1.3, font: notoSansBold, color: headingColor },\n [FormatTypes.QUOTE]: { fontSize: 14, lineHeight: 1.5, color: rgb(0.35, 0.35, 0.35) },\n [FormatTypes.CODE_BLOCK]: { fontSize: 12, lineHeight: 1.6, font: courierFont, color: rgb(0.1, 0.1, 0.1), background: rgb(0.95, 0.95, 0.95) },\n [FormatTypes.PARAGRAPH]: { fontSize: 12, lineHeight: 1.3, color: paragraphColor },\n [FormatTypes.BULLET]: { fontSize: 12, lineHeight: 1.3, color: paragraphColor },\n [FormatTypes.NUMBERED]: { fontSize: 12, lineHeight: 1.3, color: paragraphColor },\n [FormatTypes.TABLE]: { fontSize: 12, lineHeight: 1.3, color: paragraphColor },\n [FormatTypes.IMAGE]: { fontSize: 12, lineHeight: 1.3 },\n }\n\n const hexToRgb = (hex) => {\n if (hex.length == 7) {\n const r = parseInt(hex.slice(1, 3), 16) / 255.0;\n const g = parseInt(hex.slice(3, 5), 16) / 255.0;\n const b = parseInt(hex.slice(5, 7), 16) / 255.0;\n return rgb(r, g, b);\n } else if (hex.length == 4) {\n const r = parseInt(hex.slice(1, 2), 16) / 15.0;\n const g = parseInt(hex.slice(2, 3), 16) / 15.0;\n const b = parseInt(hex.slice(3, 4), 16) / 15.0;\n return rgb(r, g, b);\n } else { return rgb(0.0, 0.0, 0.0) };\n };\n\n const colorParse = (color) => {\n if (typeof color === 'string') {\n return hexToRgb(color)\n } else {\n return color\n }\n }\n\n // Minimal sanitization - only remove truly problematic invisible characters\n // With Unicode fonts, we can now keep most characters as-is\n const sanitizeText = (text: string): string => {\n return text\n // Only remove invisible/control characters that break PDF generation\n .replace(/\\uFEFF/g, '') // Remove BOM (Byte Order Mark)\n .replace(/\\u200B/g, '') // Remove zero-width space\n .replace(/\\u200C/g, '') // Remove zero-width non-joiner\n .replace(/\\u200D/g, '') // Remove zero-width joiner\n .replace(/\\uFFFD/g, '?') // Replace replacement character with ?\n // Keep ALL visible Unicode characters - Noto Sans supports them!\n }\n\n // Parse markdown and return styled text segments\n interface TextSegment {\n text: string;\n font: PDFFont;\n color: RGB;\n }\n\n const parseMarkdown = (text: string, baseFont: PDFFont, baseColor: RGB): TextSegment[] => {\n const segments: TextSegment[] = [];\n let currentIndex = 0;\n \n // Regex patterns for markdown\n const patterns = [\n { regex: /\\*\\*(.*?)\\*\\*/g, font: notoSansBold }, // **bold**\n { regex: /__(.*?)__/g, font: notoSansBold }, // __bold__\n { regex: /\\*(.*?)\\*/g, font: notoSansItalic }, // *italic*\n { regex: /_(.*?)_/g, font: notoSansItalic }, // _italic_\n { regex: /`(.*?)`/g, font: courierFont, color: rgb(0.2, 0.2, 0.2) }, // `code`\n ];\n\n // Find all markdown matches\n const matches: Array<{start: number, end: number, text: string, font: PDFFont, color?: RGB}> = [];\n \n for (const pattern of patterns) {\n let match;\n pattern.regex.lastIndex = 0; // Reset regex\n while ((match = pattern.regex.exec(text)) !== null) {\n matches.push({\n start: match.index,\n end: match.index + match[0].length,\n text: match[1], // Captured group (content without markdown syntax)\n font: pattern.font,\n color: pattern.color\n });\n }\n }\n\n // Sort matches by start position\n matches.sort((a, b) => a.start - b.start);\n\n // Remove overlapping matches (keep the first one)\n const filteredMatches: Array<{start: number, end: number, text: string, font: PDFFont, color?: RGB}> = [];\n for (const match of matches) {\n const hasOverlap = filteredMatches.some(existing => \n (match.start < existing.end && match.end > existing.start)\n );\n if (!hasOverlap) {\n filteredMatches.push(match);\n }\n }\n\n // Build segments\n for (const match of filteredMatches) {\n // Add text before this match\n if (match.start > currentIndex) {\n const beforeText = text.substring(currentIndex, match.start);\n if (beforeText) {\n segments.push({\n text: sanitizeText(beforeText),\n font: baseFont,\n color: baseColor\n });\n }\n }\n\n // Add the styled match\n segments.push({\n text: sanitizeText(match.text),\n font: match.font,\n color: match.color || baseColor\n });\n\n currentIndex = match.end;\n }\n\n // Add remaining text\n if (currentIndex < text.length) {\n const remainingText = text.substring(currentIndex);\n if (remainingText) {\n segments.push({\n text: sanitizeText(remainingText),\n font: baseFont,\n color: baseColor\n });\n }\n }\n\n // If no markdown was found, return the whole text as one segment\n if (segments.length === 0) {\n segments.push({\n text: sanitizeText(text),\n font: baseFont,\n color: baseColor\n });\n }\n\n return segments;\n }\n\n // Enhanced text wrapping that handles styled segments\n const wrapStyledText = (segments: TextSegment[], fontSize: number, maxWidth: number): Array<{segments: TextSegment[], width: number}> => {\n const lines: Array<{segments: TextSegment[], width: number}> = [];\n let currentLine: TextSegment[] = [];\n let currentWidth = 0;\n\n for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex++) {\n const segment = segments[segmentIndex];\n const words = segment.text.split(/\\s+/).filter(word => word.length > 0);\n \n for (let i = 0; i < words.length; i++) {\n const word = words[i];\n const wordWidth = segment.font.widthOfTextAtSize(word, fontSize);\n const spaceWidth = segment.font.widthOfTextAtSize(' ', fontSize);\n \n // Add space before word if:\n // 1. Not the first word in the line AND\n // 2. (Not the first word in the segment OR not the first segment)\n const needSpace = currentLine.length > 0 && (i > 0 || segmentIndex > 0);\n const totalWidth = wordWidth + (needSpace ? spaceWidth : 0);\n\n // Check if we need to wrap to new line\n if (currentWidth + totalWidth > maxWidth && currentLine.length > 0) {\n // Finish current line\n lines.push({ segments: [...currentLine], width: currentWidth });\n currentLine = [];\n currentWidth = 0;\n }\n\n // Add the word to current line\n if (needSpace && currentLine.length > 0) {\n // Try to merge with last segment if same font and color\n const lastSegment = currentLine[currentLine.length - 1];\n if (lastSegment.font === segment.font && lastSegment.color === segment.color) {\n lastSegment.text += ' ' + word;\n currentWidth += spaceWidth + wordWidth;\n } else {\n // Add space + word as new segment\n currentLine.push({ text: ' ' + word, font: segment.font, color: segment.color });\n currentWidth += spaceWidth + wordWidth;\n }\n } else {\n // Add word without space (first word in line or first word overall)\n currentLine.push({ text: word, font: segment.font, color: segment.color });\n currentWidth += wordWidth;\n }\n }\n }\n\n // Add final line if it has content\n if (currentLine.length > 0) {\n lines.push({ segments: currentLine, width: currentWidth });\n }\n\n return lines.length > 0 ? lines : [{ segments: [{ text: '', font: defaultFont, color: rgb(0, 0, 0) }], width: 0 }];\n }\n\n let page = pdfDoc.addPage()\n let { width, height } = page.getSize()\n const { marginTop, marginBottom, marginLeft, marginRight } = { marginTop: 50, marginBottom: 50, marginLeft: 50, marginRight: 50 }\n\n const maxTextWidth = () => width - marginLeft - marginRight\n\n const wrapText = (text: string, font: any, fontSize: number, maxWidth: number): string[] => {\n if (!text) return ['']\n const words = text.split(/\\s+/)\n const lines: string[] = []\n let current = ''\n\n const measure = (t: string) => font.widthOfTextAtSize(t, fontSize)\n\n const pushCurrent = () => {\n if (current.length > 0) {\n lines.push(current)\n current = ''\n }\n }\n\n for (let i = 0; i < words.length; i++) {\n const word = words[i]\n if (current.length === 0) {\n // If a single word is too long, hard-break it\n if (measure(word) > maxWidth) {\n let chunk = ''\n for (const ch of word) {\n const test = chunk + ch\n if (measure(test) > maxWidth && chunk.length > 0) {\n lines.push(chunk)\n chunk = ch\n } else {\n chunk = test\n }\n }\n current = chunk\n } else {\n current = word\n }\n } else {\n const test = current + ' ' + word\n if (measure(test) <= maxWidth) {\n current = test\n } else {\n pushCurrent()\n // start new line with this word; hard-break if needed\n if (measure(word) > maxWidth) {\n let chunk = ''\n for (const ch of word) {\n const t2 = chunk + ch\n if (measure(t2) > maxWidth && chunk.length > 0) {\n lines.push(chunk)\n chunk = ch\n } else {\n chunk = t2\n }\n }\n current = chunk\n } else {\n current = word\n }\n }\n }\n }\n pushCurrent()\n return lines\n }\n\n let y = height - marginTop\n let lastLineHeight = -1\n console.log('createPdf: Starting to process', blocks.length, 'blocks');\n for (let i = 0; i < blocks.length; i++) {\n const block = blocks[i];\n console.log(`createPdf: Processing block ${i + 1}/${blocks.length}, format: ${block.format}, content type: ${typeof block.content}`);\n try {\n const preset = STYLE_PRESETS[block.format] || { fontSize: defaultFontSize, lineHeight: defaultLineHeight }\n\n const userLineHeight = (block as any).metadata?.lineHeight\n\n const fontSize = (block as any).metadata?.fontSize || preset.fontSize\n const lineHeight = (userLineHeight ? fontSize * userLineHeight : fontSize * preset.lineHeight)\n const paragraphSpacing = (block as any).metadata?.paragraphSpacing || defaultParagraphSpacing\n const indentWidth = (block as any).metadata?.indentWidth || defaultIndentWidth\n\n const paddingX = (block as any).metadata?.paddingX || defaultPadding\n const paddingY = (block as any).metadata?.paddingY || defaultPadding\n\n const font = FONTS[(block as any).metadata?.font] || preset.font || defaultFont // Broken\n const color = colorParse((block as any).metadata?.color || preset.color || rgb(0.0, 0.0, 0.0))\n const background = colorParse((block as any).metadata?.background || preset.background || rgb(1.0, 1.0, 1.0))\n\n if (lastLineHeight >= 0) {\n y -= lineHeight - lastLineHeight\n } else {\n y -= fontSize\n }\n\n const ensureSpace = (needed: number) => {\n if (y - needed < marginBottom) {\n page = pdfDoc.addPage()\n ; ({ width, height } = page.getSize())\n y = height - marginTop - fontSize\n lastLineHeight = -1\n return true\n } else { return false }\n }\n\n const drawParagraph = (text: string) => {\n const segments = parseMarkdown(text, font, color);\n const lines = wrapStyledText(segments, fontSize, maxTextWidth());\n \n for (const line of lines) {\n ensureSpace(lineHeight);\n let currentX = marginLeft;\n \n for (const segment of line.segments) {\n if (segment.text.trim()) {\n page.drawText(segment.text, {\n x: currentX,\n y: y,\n size: fontSize,\n font: segment.font,\n color: segment.color,\n });\n currentX += segment.font.widthOfTextAtSize(segment.text, fontSize);\n }\n }\n y -= lineHeight;\n }\n }\n\n const drawHeading = (text: string, align?: 'left' | 'center' | 'right') => {\n const segments = parseMarkdown(text, font, color);\n const lines = wrapStyledText(segments, fontSize, maxTextWidth());\n \n for (const line of lines) {\n ensureSpace(lineHeight);\n let startX = marginLeft;\n \n if (align === 'center') {\n startX = marginLeft + (maxTextWidth() - line.width) / 2;\n } else if (align === 'right') {\n startX = marginLeft + maxTextWidth() - line.width;\n }\n \n let currentX = startX;\n for (const segment of line.segments) {\n if (segment.text.trim()) {\n page.drawText(segment.text, {\n x: currentX,\n y: y,\n size: fontSize,\n font: segment.font,\n color: segment.color,\n });\n currentX += segment.font.widthOfTextAtSize(segment.text, fontSize);\n }\n }\n y -= lineHeight;\n }\n }\n\n const drawBulletList = (items: string[]) => {\n const bulletIndent = indentWidth\n const gap = 8\n const contentWidth = maxTextWidth() - (bulletIndent + gap)\n for (const item of items) {\n // Clean up any bullet symbols that the AI might have added\n const cleanItem = item.replace(/^\\s*[•*-]\\s*/, '').trim();\n const segments = parseMarkdown(cleanItem, font, color);\n const lines = wrapStyledText(segments, fontSize, contentWidth);\n \n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const line = lines[lineIndex];\n ensureSpace(lineHeight);\n \n // Draw bullet only on first line\n if (lineIndex === 0) {\n page.drawText('•', {\n x: marginLeft + gap,\n y: y,\n size: fontSize,\n font: font,\n color: color,\n });\n }\n \n // Draw styled text\n let currentX = marginLeft + bulletIndent + gap;\n for (const segment of line.segments) {\n if (segment.text.trim()) {\n page.drawText(segment.text, {\n x: currentX,\n y: y,\n size: fontSize,\n font: segment.font,\n color: segment.color,\n });\n currentX += segment.font.widthOfTextAtSize(segment.text, fontSize);\n }\n }\n y -= lineHeight;\n }\n }\n }\n\n const drawNumberedList = (items: string[]) => {\n const numberIndent = indentWidth\n const gap = 8\n const contentWidth = maxTextWidth() - (numberIndent + gap)\n let index = 1\n for (const item of items) {\n // Clean up any numbers that the AI might have added\n const cleanItem = item.replace(/^\\s*\\d+\\.\\s*/, '').trim();\n const numLabel = `${index}.`\n const numWidth = font.widthOfTextAtSize(numLabel, fontSize)\n const segments = parseMarkdown(cleanItem, font, color);\n const lines = wrapStyledText(segments, fontSize, contentWidth);\n \n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const line = lines[lineIndex];\n ensureSpace(lineHeight);\n \n // Draw number only on first line\n if (lineIndex === 0) {\n page.drawText(numLabel, {\n x: marginLeft + gap,\n y: y,\n size: fontSize,\n font: font,\n color: color,\n });\n }\n \n // Draw styled text\n let currentX = marginLeft + Math.max(numberIndent, numWidth + 6) + gap;\n for (const segment of line.segments) {\n if (segment.text.trim()) {\n page.drawText(segment.text, {\n x: currentX,\n y: y,\n size: fontSize,\n font: segment.font,\n color: segment.color,\n });\n currentX += segment.font.widthOfTextAtSize(segment.text, fontSize);\n }\n }\n y -= lineHeight;\n }\n index++;\n }\n }\n\n const drawQuote = (text: string) => {\n const ruleWidth = 2\n const ruleGap = 8\n const contentX = marginLeft + ruleWidth + ruleGap\n const contentWidth = maxTextWidth() - (ruleWidth + ruleGap)\n const segments = parseMarkdown(text, font, color);\n const lines = wrapStyledText(segments, fontSize, contentWidth);\n const totalHeight = lines.length * lineHeight + fontSize\n var remainingHeight = totalHeight\n \n for (const line of lines) {\n let pageAdded = ensureSpace(lineHeight)\n if (pageAdded || remainingHeight == totalHeight) {\n let blockHeight = Math.floor(Math.min(remainingHeight, y - marginBottom) / lineHeight) * lineHeight\n page.drawRectangle({\n x: marginLeft,\n y: y + lineHeight,\n width: ruleWidth,\n height: -blockHeight - lineHeight + fontSize,\n color: color,\n })\n remainingHeight -= blockHeight + lineHeight - fontSize\n }\n \n // Draw styled text\n let currentX = contentX;\n for (const segment of line.segments) {\n if (segment.text.trim()) {\n page.drawText(segment.text, {\n x: currentX,\n y: y,\n size: fontSize,\n font: segment.font,\n color: segment.color,\n });\n currentX += segment.font.widthOfTextAtSize(segment.text, fontSize);\n }\n }\n y -= lineHeight;\n }\n y -= lineHeight - fontSize\n }\n\n const drawCodeBlock = (textLines: string[]) => {\n const codeFont = font\n \n // Detect indentation patterns\n const detectIndentation = (lines: string[]) => {\n let tabCount = 0\n let spaceCount = 0\n let minSpaces = Infinity\n \n for (const line of lines) {\n if (line.trim().length === 0) continue // Skip empty lines\n \n const leadingWhitespace = line.match(/^(\\s*)/)?.[1] || ''\n if (leadingWhitespace.includes('\\t')) {\n tabCount++\n } else if (leadingWhitespace.length > 0) {\n spaceCount++\n minSpaces = Math.min(minSpaces, leadingWhitespace.length)\n }\n }\n \n // Determine indentation strategy\n if (tabCount > spaceCount) {\n return { type: 'tab', width: indentWidth }\n } else if (spaceCount > 0) {\n // Use the most common space count, or default to 4\n const commonSpaces = minSpaces === Infinity ? 4 : minSpaces\n return { type: 'space', width: commonSpaces * (fontSize * 0.6) } // Approximate space width\n } else {\n return { type: 'space', width: fontSize * 2.4 } // Default 4 spaces\n }\n }\n \n const indentInfo = detectIndentation(textLines)\n \n // Process lines with indentation\n const processedLines: { text: string; indentLevel: number; originalLine: string }[] = []\n \n for (const line of textLines) {\n const leadingWhitespace = line.match(/^(\\s*)/)?.[1] || ''\n let indentLevel = 0\n \n if (indentInfo.type === 'tab') {\n indentLevel = leadingWhitespace.split('\\t').length - 1\n } else {\n // Count spaces, grouping by the detected space width\n const spaceWidth = indentInfo.width / (fontSize * 0.6) // Convert back to space count\n indentLevel = Math.floor(leadingWhitespace.length / spaceWidth)\n }\n \n processedLines.push({\n text: line.trim(),\n indentLevel,\n originalLine: line\n })\n }\n \n // Wrap each processed line separately to preserve line breaks and indentation\n const wrappedLines: { text: string; indentLevel: number; isContinuation: boolean }[] = []\n const contentW = maxTextWidth() - paddingX * 2\n \n for (const processedLine of processedLines) {\n if (processedLine.text.length === 0) {\n // Empty line - preserve as empty line\n wrappedLines.push({\n text: '',\n indentLevel: processedLine.indentLevel,\n isContinuation: false\n })\n } else {\n const parts = wrapText(processedLine.text, codeFont, fontSize, contentW)\n for (let i = 0; i < parts.length; i++) {\n wrappedLines.push({\n text: parts[i],\n indentLevel: processedLine.indentLevel,\n isContinuation: i > 0\n })\n }\n }\n }\n \n const totalHeight = wrappedLines.length * lineHeight + paddingY * 2\n var remainingHeight = totalHeight\n y -= paddingY\n \n for (const wrappedLine of wrappedLines) {\n let pageAdded = ensureSpace(lineHeight + paddingY)\n if (pageAdded || remainingHeight == totalHeight) {\n let blockHeight = Math.floor(Math.min(remainingHeight, y - marginBottom - paddingY) / lineHeight) * lineHeight\n page.drawRectangle({\n x: marginLeft,\n y: y + fontSize,\n width: maxTextWidth(),\n height: -blockHeight - paddingY * 2,\n color: background,\n })\n remainingHeight -= blockHeight\n y -= paddingY\n }\n \n // Calculate indentation offset\n const indentOffset = wrappedLine.indentLevel * indentInfo.width\n \n page.drawText(wrappedLine.text, {\n x: marginLeft + paddingX + indentOffset,\n y: y,\n size: fontSize,\n font: codeFont,\n color: color,\n })\n y -= lineHeight\n }\n y -= paddingY\n }\n\n // Render by block format\n switch (block.format) {\n case FormatTypes.HEADER_1:\n case FormatTypes.HEADER_2:\n case FormatTypes.HEADER_3:\n case FormatTypes.HEADER_4:\n case FormatTypes.HEADER_5:\n case FormatTypes.HEADER_6: {\n const align = (block as any).metadata?.align as 'left' | 'center' | 'right' | undefined\n drawHeading(String(block.content), align)\n break\n }\n case FormatTypes.BULLET: {\n const items = Array.isArray(block.content) ? block.content.map(String) : [String(block.content)]\n drawBulletList(items)\n break\n }\n case FormatTypes.NUMBERED: {\n const items = Array.isArray(block.content) ? block.content.map(String) : [String(block.content)]\n drawNumberedList(items)\n break\n }\n case FormatTypes.QUOTE: {\n drawQuote(String(block.content))\n break\n }\n case FormatTypes.CODE_BLOCK: {\n const lines = Array.isArray(block.content) ? block.content.map(String) : String(block.content).split('\\n')\n drawCodeBlock(lines)\n break\n }\n default: {\n if (typeof block.content === 'string') {\n drawParagraph(block.content)\n } else {\n for (const c of block.content) {\n drawParagraph(String(c))\n }\n }\n }\n }\n console.log(`createPdf: Successfully processed block ${i + 1}`);\n y -= paragraphSpacing\n lastLineHeight = lineHeight\n } catch (blockError) {\n console.error(`createPdf: Error processing block ${i + 1}:`, blockError);\n throw blockError;\n }\n }\n\n console.log('createPdf: About to save PDF document');\n const pdfBytes = await pdfDoc.save()\n console.log('createPdf: PDF saved successfully, bytes length:', pdfBytes.length);\n // writeFile('output.pdf', pdfBytes, () => {\n // console.log('PDF created successfully') // Still only saves file, no API yet\n // })\n return pdfBytes\n } catch (error) {\n console.error('createPdf: Error during PDF creation:', error);\n throw error;\n }\n}\n"],"names":[],"mappings":"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","debug_id":"9dcef6bc-81ec-59b1-ba5e-2017ff5b9c66"}
@@ -1 +1 @@
1
- {"version":3,"file":"jsonStyles.d.ts","sourceRoot":"","sources":["../../src/lib/jsonStyles.ts"],"names":[],"mappings":"AAGA,oBAAY,WAAW;IACnB,QAAQ,IAAA;IACR,QAAQ,IAAA;IACR,QAAQ,IAAA;IACR,QAAQ,IAAA;IACR,QAAQ,IAAA;IACR,QAAQ,IAAA;IACR,SAAS,IAAA;IACT,MAAM,IAAA;IACN,QAAQ,IAAA;IACR,KAAK,IAAA;IACL,KAAK,KAAA;IACL,UAAU,KAAA;IACV,KAAK,KAAA;CACR;AAGD,oBAAY,KAAK;IACb,WAAW,IAAA;IACX,OAAO,IAAA;IACP,SAAS,IAAA;IACT,cAAc,IAAA;IACd,gBAAgB,IAAA;IAChB,qBAAqB,IAAA;CACxB;AAID,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC"}
1
+ {"version":3,"file":"jsonStyles.d.ts","sourceRoot":"/","sources":["lib/jsonStyles.ts"],"names":[],"mappings":"AAGA,oBAAY,WAAW;IACnB,QAAQ,IAAA;IACR,QAAQ,IAAA;IACR,QAAQ,IAAA;IACR,QAAQ,IAAA;IACR,QAAQ,IAAA;IACR,QAAQ,IAAA;IACR,SAAS,IAAA;IACT,MAAM,IAAA;IACN,QAAQ,IAAA;IACR,KAAK,IAAA;IACL,KAAK,KAAA;IACL,UAAU,KAAA;IACV,KAAK,KAAA;CACR;AAGD,oBAAY,KAAK;IACb,WAAW,IAAA;IACX,OAAO,IAAA;IACP,SAAS,IAAA;IACT,cAAc,IAAA;IACd,gBAAgB,IAAA;IAChB,qBAAqB,IAAA;CACxB;AAID,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC"}
@@ -1,6 +1,8 @@
1
1
  // -----------------------------
2
2
  // Basic format enums and interfaces
3
3
  // -----------------------------
4
+
5
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="435981cf-b4a7-5529-bc50-65f51b5d66af")}catch(e){}}();
4
6
  export var FormatTypes;
5
7
  (function (FormatTypes) {
6
8
  FormatTypes[FormatTypes["HEADER_1"] = 0] = "HEADER_1";
@@ -26,3 +28,5 @@ export var Fonts;
26
28
  Fonts[Fonts["HELVETICA_ITALIC"] = 4] = "HELVETICA_ITALIC";
27
29
  Fonts[Fonts["HELVETICA_BOLD_ITALIC"] = 5] = "HELVETICA_BOLD_ITALIC";
28
30
  })(Fonts || (Fonts = {}));
31
+ //# sourceMappingURL=jsonStyles.js.map
32
+ //# debugId=435981cf-b4a7-5529-bc50-65f51b5d66af
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonStyles.js","sources":["lib/jsonStyles.ts"],"sourceRoot":"/","sourcesContent":["// -----------------------------\n// Basic format enums and interfaces\n// -----------------------------\nexport enum FormatTypes {\n HEADER_1,\n HEADER_2,\n HEADER_3,\n HEADER_4,\n HEADER_5,\n HEADER_6,\n PARAGRAPH,\n BULLET,\n NUMBERED,\n TABLE,\n IMAGE,\n CODE_BLOCK,\n QUOTE,\n}\n\n\nexport enum Fonts {\n TIMES_ROMAN,\n COURIER,\n HELVETICA,\n HELVETICA_BOLD,\n HELVETICA_ITALIC,\n HELVETICA_BOLD_ITALIC,\n}\n\n\n// Each content block in a document\nexport interface DocumentBlock {\n format: FormatTypes;\n content: string | string[]; // can be text, list items, etc. string as html / mrkdown\n metadata?: Record<string, any>; // optional extra formatting info (e.g. alignment)\n}\n"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,oCAAoC;AACpC,gCAAgC;;;AAChC,MAAM,CAAN,IAAY,WAcX;AAdD,WAAY,WAAW;IACnB,qDAAQ,CAAA;IACR,qDAAQ,CAAA;IACR,qDAAQ,CAAA;IACR,qDAAQ,CAAA;IACR,qDAAQ,CAAA;IACR,qDAAQ,CAAA;IACR,uDAAS,CAAA;IACT,iDAAM,CAAA;IACN,qDAAQ,CAAA;IACR,+CAAK,CAAA;IACL,gDAAK,CAAA;IACL,0DAAU,CAAA;IACV,gDAAK,CAAA;AACT,CAAC,EAdW,WAAW,KAAX,WAAW,QActB;AAGD,MAAM,CAAN,IAAY,KAOX;AAPD,WAAY,KAAK;IACb,+CAAW,CAAA;IACX,uCAAO,CAAA;IACP,2CAAS,CAAA;IACT,qDAAc,CAAA;IACd,yDAAgB,CAAA;IAChB,mEAAqB,CAAA;AACzB,CAAC,EAPW,KAAK,KAAL,KAAK,QAOhB","debug_id":"435981cf-b4a7-5529-bc50-65f51b5d66af"}
@@ -1 +1 @@
1
- {"version":3,"file":"notificationHandler.d.ts","sourceRoot":"","sources":["../../src/lib/notificationHandler.ts"],"names":[],"mappings":"AAEA,UAAU,gBAAgB;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAA;CAClB;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB;;;;;;;;GAS9E;AAED,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,gBAAgB,yDASzF;AAED,wBAAsB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,GAAE,OAAc;;;;;;;;GAM9D"}
1
+ {"version":3,"file":"notificationHandler.d.ts","sourceRoot":"/","sources":["lib/notificationHandler.ts"],"names":[],"mappings":"AAEA,UAAU,gBAAgB;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAA;CAClB;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB;;;;;;;;GAS9E;AAED,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,gBAAgB,yDASzF;AAED,wBAAsB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,GAAE,OAAc;;;;;;;;GAM9D"}
@@ -1,3 +1,5 @@
1
+
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="e0e01d37-e6fd-5751-a9d2-fece72c46422")}catch(e){}}();
1
3
  import { prisma } from "./prisma.js";
2
4
  export async function sendNotification(receiver, data) {
3
5
  const notification = await prisma.notification.create({
@@ -26,3 +28,5 @@ export async function markRead(id, read = true) {
26
28
  });
27
29
  return notification;
28
30
  }
31
+ //# sourceMappingURL=notificationHandler.js.map
32
+ //# debugId=e0e01d37-e6fd-5751-a9d2-fece72c46422
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notificationHandler.js","sources":["lib/notificationHandler.ts"],"sourceRoot":"/","sourcesContent":["import { prisma } from \"./prisma.js\";\n\ninterface notificationData {\n title: string,\n content: string\n}\n\nexport async function sendNotification(receiver: string, data: notificationData) {\n const notification = await prisma.notification.create({\n data: {\n receiverId: receiver,\n title: data.title,\n content: data.content,\n },\n });\n return notification;\n}\n\nexport async function sendNotifications(receiverIds: Array<string>, data: notificationData) {\n const notifications = await prisma.notification.createMany({\n data: receiverIds.map(receiverId => ({\n receiverId: receiverId,\n title: data.title,\n content: data.content,\n })),\n });\n return notifications;\n}\n\nexport async function markRead(id: string, read: boolean = true) {\n const notification = await prisma.notification.update({\n where: {id},\n data: {read: read},\n });\n return notification;\n}\n"],"names":[],"mappings":";;AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOrC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,QAAgB,EAAE,IAAsB;IAC3E,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC;QAClD,IAAI,EAAE;YACF,UAAU,EAAE,QAAQ;YACpB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;SACxB;KACJ,CAAC,CAAC;IACH,OAAO,YAAY,CAAC;AACxB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,WAA0B,EAAE,IAAsB;IACtF,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC;QACvD,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;YACjC,UAAU,EAAE,UAAU;YACtB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;SACxB,CAAC,CAAC;KACN,CAAC,CAAC;IACH,OAAO,aAAa,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,EAAU,EAAE,OAAgB,IAAI;IAC3D,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC;QAClD,KAAK,EAAE,EAAC,EAAE,EAAC;QACX,IAAI,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC;KACrB,CAAC,CAAC;IACH,OAAO,YAAY,CAAC;AACxB,CAAC","debug_id":"e0e01d37-e6fd-5751-a9d2-fece72c46422"}
@@ -1 +1 @@
1
- {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/lib/prisma.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,QAAA,MAAM,qBAAqB,sIAE1B,CAAC;AAGF,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;CAClE;AAED,eAAO,MAAM,MAAM,gIAA+C,CAAC"}
1
+ {"version":3,"file":"prisma.d.ts","sourceRoot":"/","sources":["lib/prisma.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,QAAA,MAAM,qBAAqB,sIAE1B,CAAC;AAGF,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;CAClE;AAED,eAAO,MAAM,MAAM,gIAA+C,CAAC"}
@@ -1,3 +1,5 @@
1
+
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="40f0a180-f102-51cd-9f26-c2f1717261f4")}catch(e){}}();
1
3
  import { PrismaClient } from '@prisma/client';
2
4
  const prismaClientSingleton = () => {
3
5
  return new PrismaClient();
@@ -6,3 +8,5 @@ export const prisma = globalThis.prisma ?? prismaClientSingleton();
6
8
  if (process.env.NODE_ENV !== 'production') {
7
9
  globalThis.prisma = prisma;
8
10
  }
11
+ //# sourceMappingURL=prisma.js.map
12
+ //# debugId=40f0a180-f102-51cd-9f26-c2f1717261f4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma.js","sources":["lib/prisma.ts"],"sourceRoot":"/","sourcesContent":["import { PrismaClient } from '@prisma/client';\n\nconst prismaClientSingleton = () => {\n return new PrismaClient();\n};\n\n// Prevent multiple instances of Prisma Client in development\ndeclare global {\n var prisma: undefined | ReturnType<typeof prismaClientSingleton>;\n}\n\nexport const prisma = globalThis.prisma ?? prismaClientSingleton();\n\nif (process.env.NODE_ENV !== 'production') {\n globalThis.prisma = prisma;\n}"],"names":[],"mappings":";;AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACjC,OAAO,IAAI,YAAY,EAAE,CAAC;AAC5B,CAAC,CAAC;AAOF,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,IAAI,qBAAqB,EAAE,CAAC;AAEnE,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;IAC1C,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC;AAC7B,CAAC","debug_id":"40f0a180-f102-51cd-9f26-c2f1717261f4"}
@@ -1 +1 @@
1
- {"version":3,"file":"pusher.d.ts","sourceRoot":"","sources":["../../src/lib/pusher.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,QAAA,MAAM,MAAM,QAMV,CAAC;AAEH,OAAO,EAAE,MAAM,EAAE,CAAC"}
1
+ {"version":3,"file":"pusher.d.ts","sourceRoot":"/","sources":["lib/pusher.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,QAAA,MAAM,MAAM,QAMV,CAAC;AAEH,OAAO,EAAE,MAAM,EAAE,CAAC"}
@@ -1,3 +1,5 @@
1
+
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="50344d98-9adc-5864-9b92-93b1727403ba")}catch(e){}}();
1
3
  import Pusher from 'pusher';
2
4
  const pusher = new Pusher({
3
5
  appId: process.env.PUSHER_APP_ID,
@@ -7,3 +9,5 @@ const pusher = new Pusher({
7
9
  useTLS: true,
8
10
  });
9
11
  export { pusher };
12
+ //# sourceMappingURL=pusher.js.map
13
+ //# debugId=50344d98-9adc-5864-9b92-93b1727403ba
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pusher.js","sources":["lib/pusher.ts"],"sourceRoot":"/","sourcesContent":["import Pusher from 'pusher';\n\nconst pusher = new Pusher({\n appId: process.env.PUSHER_APP_ID!,\n key: process.env.PUSHER_KEY!,\n secret: process.env.PUSHER_SECRET!,\n cluster: process.env.PUSHER_CLUSTER!,\n useTLS: true,\n});\n\nexport { pusher };\n"],"names":[],"mappings":";;AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,aAAc;IACjC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,UAAW;IAC5B,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAc;IAClC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,cAAe;IACpC,MAAM,EAAE,IAAI;CACb,CAAC,CAAC;AAEH,OAAO,EAAE,MAAM,EAAE,CAAC","debug_id":"50344d98-9adc-5864-9b92-93b1727403ba"}
@@ -1 +1 @@
1
- {"version":3,"file":"thumbnailGenerator.d.ts","sourceRoot":"","sources":["../../src/lib/thumbnailGenerator.ts"],"names":[],"mappings":"AAiDA;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BlG;AA4CD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA0BlG;AAED;;;;;;GAMG"}
1
+ {"version":3,"file":"thumbnailGenerator.d.ts","sourceRoot":"/","sources":["lib/thumbnailGenerator.ts"],"names":[],"mappings":"AAiDA;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BlG;AA4CD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA0BlG;AAED;;;;;;GAMG"}
@@ -1,3 +1,5 @@
1
+
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a93ef014-63a9-5a8d-815a-01d914751573")}catch(e){}}();
1
3
  import sharp from 'sharp';
2
4
  import { getSignedUrl } from './googleCloudStorage.js';
3
5
  // Thumbnail size configuration
@@ -156,3 +158,5 @@ export async function generateThumbnail(fileName, fileType) {
156
158
  */
157
159
  // DEPRECATED: This function is no longer used - thumbnails are generated during direct uploads
158
160
  // Thumbnail generation is now handled in the direct upload flow
161
+ //# sourceMappingURL=thumbnailGenerator.js.map
162
+ //# debugId=a93ef014-63a9-5a8d-815a-01d914751573