Refactor REST to different directory and register router

This commit is contained in:
Iain Sproat
2025-03-28 15:13:59 +00:00
parent d8ec2f12c4
commit c19c7892f4
2 changed files with 112 additions and 104 deletions
+4 -104
View File
@@ -1,10 +1,5 @@
import cron from 'node-cron'
import {
insertNewUploadAndNotifyFactory,
updateUploadAndNotifyFactory
} from '@/modules/fileuploads/services/management'
import request from 'request'
import { authMiddlewareCreator } from '@/modules/shared/middleware'
import { updateUploadAndNotifyFactory } from '@/modules/fileuploads/services/management'
import { moduleLogger } from '@/observability/logging'
import {
onFileImportProcessedFactory,
@@ -14,20 +9,13 @@ import {
import {
getAllPendingUploadsFactory,
getFileInfoFactory,
saveUploadFileFactory,
updateUploadFileFactory
} from '@/modules/fileuploads/repositories/fileUploads'
import { db } from '@/db/knex'
import { publish } from '@/modules/shared/utils/subscriptions'
import { SpeckleModule } from '@/modules/shared/helpers/typeHelper'
import { streamWritePermissionsPipelineFactory } from '@/modules/shared/authz'
import { getRolesFactory } from '@/modules/shared/repositories/roles'
import { getStreamBranchByNameFactory } from '@/modules/core/repositories/branches'
import { getStreamFactory } from '@/modules/core/repositories/streams'
import {
getPort,
getFileImportTimeLimitMinutes
} from '@/modules/shared/helpers/envHelper'
import { getFileImportTimeLimitMinutes } from '@/modules/shared/helpers/envHelper'
import {
getProjectDbClient,
getRegisteredDbClients
@@ -42,6 +30,7 @@ import {
import type { ScheduleExecution } from '@/modules/core/domain/scheduledTasks/operations'
import { manageFileImportExpiryFactory } from '@/modules/fileuploads/services/tasks'
import { TIME } from '@speckle/shared'
import { getRouter } from '@/modules/fileuploads/rest/routes'
let scheduledTasks: cron.ScheduledTask[] = []
@@ -92,96 +81,7 @@ export const init: SpeckleModule = {
moduleLogger.info('📄 Init FileUploads module')
}
app.post(
'/api/file/:fileType/:streamId/:branchName?',
async (req, res, next) => {
await authMiddlewareCreator(
streamWritePermissionsPipelineFactory({
getRoles: getRolesFactory({ db }),
getStream: getStreamFactory({ db })
})
)(req, res, next)
},
async (req, res) => {
const branchName = req.params.branchName || 'main'
req.log = req.log.child({
streamId: req.params.streamId,
userId: req.context.userId,
branchName
})
const projectDb = await getProjectDbClient({ projectId: req.params.streamId })
const insertNewUploadAndNotify = insertNewUploadAndNotifyFactory({
getStreamBranchByName: getStreamBranchByNameFactory({ db: projectDb }),
saveUploadFile: saveUploadFileFactory({ db: projectDb }),
publish
})
const saveFileUploads = async ({
userId,
streamId,
branchName,
uploadResults
}: {
userId: string
streamId: string
branchName: string
uploadResults: Array<{
blobId: string
fileName: string
fileSize: number
}>
}) => {
await Promise.all(
uploadResults.map(async (upload) => {
await insertNewUploadAndNotify({
fileId: upload.blobId,
streamId,
branchName,
userId,
fileName: upload.fileName,
fileType: upload.fileName.split('.').pop()!,
fileSize: upload.fileSize
})
})
)
}
//TODO refactor packages/server/modules/blobstorage/index.js to use the service pattern, and then refactor this to call the service directly from here without the http overhead
const pipedReq = request(
// we call this same server on localhost (IPv4) to upload the blob and do not make an external call
`http://127.0.0.1:${getPort()}/api/stream/${req.params.streamId}/blob`,
async (err, response, body) => {
if (err) {
res.log.error(err, 'Error while uploading blob.')
res.status(500).send(err.message)
return
}
if (response.statusCode === 201) {
const { uploadResults } = JSON.parse(body)
await saveFileUploads({
userId: req.context.userId!,
streamId: req.params.streamId,
branchName,
uploadResults
})
} else {
res.log.error(
{
statusCode: response.statusCode,
path: `http://127.0.0.1:${getPort()}/api/stream/${
req.params.streamId
}/blob`
},
'Error while uploading file.'
)
}
res.contentType('application/json')
res.status(response.statusCode).send(body)
}
)
req.pipe(pipedReq as unknown as NodeJS.WritableStream)
}
)
app.use(getRouter())
if (isInitial) {
const scheduleExecution = scheduleExecutionFactory({
@@ -0,0 +1,108 @@
import { getPort } from '@/modules/shared/helpers/envHelper'
import { Router } from 'express'
import { insertNewUploadAndNotifyFactory } from '@/modules/fileuploads/services/management'
import request from 'request'
import { authMiddlewareCreator } from '@/modules/shared/middleware'
import { saveUploadFileFactory } from '@/modules/fileuploads/repositories/fileUploads'
import { db } from '@/db/knex'
import { publish } from '@/modules/shared/utils/subscriptions'
import { streamWritePermissionsPipelineFactory } from '@/modules/shared/authz'
import { getRolesFactory } from '@/modules/shared/repositories/roles'
import { getStreamBranchByNameFactory } from '@/modules/core/repositories/branches'
import { getStreamFactory } from '@/modules/core/repositories/streams'
import { getProjectDbClient } from '@/modules/multiregion/utils/dbSelector'
export const getRouter = () => {
const app = Router()
app.post(
'/api/file/:fileType/:streamId/:branchName?',
async (req, res, next) => {
await authMiddlewareCreator(
streamWritePermissionsPipelineFactory({
getRoles: getRolesFactory({ db }),
getStream: getStreamFactory({ db })
})
)(req, res, next)
},
async (req, res) => {
const branchName = req.params.branchName || 'main'
req.log = req.log.child({
streamId: req.params.streamId,
userId: req.context.userId,
branchName
})
const projectDb = await getProjectDbClient({ projectId: req.params.streamId })
const insertNewUploadAndNotify = insertNewUploadAndNotifyFactory({
getStreamBranchByName: getStreamBranchByNameFactory({ db: projectDb }),
saveUploadFile: saveUploadFileFactory({ db: projectDb }),
publish
})
const saveFileUploads = async ({
userId,
streamId,
branchName,
uploadResults
}: {
userId: string
streamId: string
branchName: string
uploadResults: Array<{
blobId: string
fileName: string
fileSize: number
}>
}) => {
await Promise.all(
uploadResults.map(async (upload) => {
await insertNewUploadAndNotify({
fileId: upload.blobId,
streamId,
branchName,
userId,
fileName: upload.fileName,
fileType: upload.fileName.split('.').pop()!,
fileSize: upload.fileSize
})
})
)
}
//TODO refactor packages/server/modules/blobstorage/index.js to use the service pattern, and then refactor this to call the service directly from here without the http overhead
const pipedReq = request(
// we call this same server on localhost (IPv4) to upload the blob and do not make an external call
`http://127.0.0.1:${getPort()}/api/stream/${req.params.streamId}/blob`,
async (err, response, body) => {
if (err) {
res.log.error(err, 'Error while uploading blob.')
res.status(500).send(err.message)
return
}
if (response.statusCode === 201) {
const { uploadResults } = JSON.parse(body)
await saveFileUploads({
userId: req.context.userId!,
streamId: req.params.streamId,
branchName,
uploadResults
})
} else {
res.log.error(
{
statusCode: response.statusCode,
path: `http://127.0.0.1:${getPort()}/api/stream/${
req.params.streamId
}/blob`
},
'Error while uploading file.'
)
}
res.contentType('application/json')
res.status(response.statusCode).send(body)
}
)
req.pipe(pipedReq as unknown as NodeJS.WritableStream)
}
)
return app
}