mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
[web] inline trivial mongo queries when creating project from template (#30601)
GitOrigin-RevId: 7aefee892d491b1ec191d07bf1871317b897dec8
This commit is contained in:
@@ -221,6 +221,7 @@ async function setRootDoc(projectId, newRootDocID) {
|
||||
'invalid file extension for root doc'
|
||||
)
|
||||
}
|
||||
return newRootDocID
|
||||
}
|
||||
|
||||
async function unsetRootDoc(projectId) {
|
||||
|
||||
@@ -9,22 +9,35 @@ const safeCompilers = ['xelatex', 'pdflatex', 'latex', 'lualatex']
|
||||
const { ReturnDocument } = mongodb
|
||||
|
||||
const ProjectOptionsHandler = {
|
||||
async setCompiler(projectId, compiler) {
|
||||
if (!compiler) {
|
||||
return
|
||||
}
|
||||
/**
|
||||
* @param {string} compiler
|
||||
* @return {string}
|
||||
*/
|
||||
normalizeCompiler(compiler) {
|
||||
compiler = compiler.toLowerCase()
|
||||
if (!safeCompilers.includes(compiler)) {
|
||||
throw new Error(`invalid compiler: ${compiler}`)
|
||||
}
|
||||
return compiler
|
||||
},
|
||||
|
||||
async setCompiler(projectId, compiler) {
|
||||
if (!compiler) {
|
||||
return
|
||||
}
|
||||
compiler = ProjectOptionsHandler.normalizeCompiler(compiler)
|
||||
const conditions = { _id: projectId }
|
||||
const update = { compiler }
|
||||
return Project.updateOne(conditions, update, {})
|
||||
},
|
||||
|
||||
async setImageName(projectId, imageName) {
|
||||
/**
|
||||
* @param {string} imageName
|
||||
* @return {string | undefined}
|
||||
*/
|
||||
normalizeImageName(imageName) {
|
||||
if (!imageName || !Array.isArray(settings.allowedImageNames)) {
|
||||
return
|
||||
return undefined
|
||||
}
|
||||
imageName = imageName.toLowerCase()
|
||||
const isAllowed = settings.allowedImageNames.find(
|
||||
@@ -33,8 +46,16 @@ const ProjectOptionsHandler = {
|
||||
if (!isAllowed) {
|
||||
throw new Error(`invalid imageName: ${imageName}`)
|
||||
}
|
||||
return settings.imageRoot + '/' + imageName
|
||||
},
|
||||
|
||||
async setImageName(projectId, imageName) {
|
||||
imageName = ProjectOptionsHandler.normalizeImageName(imageName)
|
||||
if (!imageName) {
|
||||
return
|
||||
}
|
||||
const conditions = { _id: projectId }
|
||||
const update = { imageName: settings.imageRoot + '/' + imageName }
|
||||
const update = { imageName }
|
||||
return Project.updateOne(conditions, update, {})
|
||||
},
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Project } from '../../models/Project.mjs'
|
||||
import ProjectDetailsHandler from '../Project/ProjectDetailsHandler.mjs'
|
||||
import ProjectOptionsHandlerModule from '../Project/ProjectOptionsHandler.mjs'
|
||||
import ProjectRootDocManagerModule from '../Project/ProjectRootDocManager.mjs'
|
||||
@@ -31,6 +30,11 @@ const TemplatesManager = {
|
||||
userId,
|
||||
imageName
|
||||
) {
|
||||
compiler = ProjectOptionsHandler.normalizeCompiler(compiler || 'pdflatex')
|
||||
imageName = ProjectOptionsHandler.normalizeImageName(
|
||||
imageName || 'wl_texlive:2018.1'
|
||||
)
|
||||
|
||||
const zipUrl = `${settings.apis.v1.url}/api/v1/overleaf/templates/${templateVersionId}`
|
||||
const zipReq = await fetchStreamWithResponse(zipUrl, {
|
||||
basicAuth: {
|
||||
@@ -47,7 +51,11 @@ const TemplatesManager = {
|
||||
const attributes = {
|
||||
fromV1TemplateId: templateId,
|
||||
fromV1TemplateVersionId: templateVersionId,
|
||||
compiler,
|
||||
imageName,
|
||||
}
|
||||
if (brandVariationId) attributes.brandVariationId = brandVariationId
|
||||
|
||||
await pipeline(zipReq.stream, writeStream)
|
||||
|
||||
if (zipReq.response.status !== 200) {
|
||||
@@ -76,16 +84,7 @@ const TemplatesManager = {
|
||||
)
|
||||
})
|
||||
|
||||
await TemplatesManager._setCompiler(project._id, compiler)
|
||||
await TemplatesManager._setImage(project._id, imageName)
|
||||
await TemplatesManager._setMainFile(project._id, mainFile)
|
||||
await TemplatesManager._setBrandVariationId(project._id, brandVariationId)
|
||||
|
||||
const update = {
|
||||
fromV1TemplateId: templateId,
|
||||
fromV1TemplateVersionId: templateVersionId,
|
||||
}
|
||||
await Project.updateOne({ _id: project._id }, update, {})
|
||||
await TemplatesManager._setMainFile(project, mainFile)
|
||||
|
||||
await prepareClsiCacheInBackground
|
||||
|
||||
@@ -95,33 +94,15 @@ const TemplatesManager = {
|
||||
}
|
||||
},
|
||||
|
||||
async _setCompiler(projectId, compiler) {
|
||||
if (compiler == null) {
|
||||
return
|
||||
}
|
||||
await ProjectOptionsHandler.setCompiler(projectId, compiler)
|
||||
},
|
||||
|
||||
async _setImage(projectId, imageName) {
|
||||
if (!imageName) {
|
||||
imageName = 'wl_texlive:2018.1'
|
||||
}
|
||||
|
||||
await ProjectOptionsHandler.setImageName(projectId, imageName)
|
||||
},
|
||||
|
||||
async _setMainFile(projectId, mainFile) {
|
||||
async _setMainFile(project, mainFile) {
|
||||
if (mainFile == null) {
|
||||
return
|
||||
}
|
||||
await ProjectRootDocManager.setRootDocFromName(projectId, mainFile)
|
||||
},
|
||||
|
||||
async _setBrandVariationId(projectId, brandVariationId) {
|
||||
if (brandVariationId == null) {
|
||||
return
|
||||
}
|
||||
await ProjectOptionsHandler.setBrandVariationId(projectId, brandVariationId)
|
||||
const rootDocId = await ProjectRootDocManager.setRootDocFromName(
|
||||
project._id,
|
||||
mainFile
|
||||
)
|
||||
if (rootDocId) project.rootDoc_id = rootDocId
|
||||
},
|
||||
|
||||
async fetchFromV1(templateId) {
|
||||
|
||||
@@ -87,7 +87,11 @@ async function createProjectFromZipArchiveWithName(
|
||||
|
||||
try {
|
||||
await _initializeProjectWithZipContents(ownerId, project, contentsPath)
|
||||
await ProjectRootDocManager.promises.setRootDocAutomatically(project._id)
|
||||
const rootDocId =
|
||||
await ProjectRootDocManager.promises.setRootDocAutomatically(
|
||||
project._id
|
||||
)
|
||||
if (rootDocId) project.rootDoc_id = rootDocId
|
||||
} catch (err) {
|
||||
// no need to wait for the cleanup here
|
||||
ProjectDeleter.promises
|
||||
|
||||
@@ -47,6 +47,8 @@ describe('TemplatesManager', function () {
|
||||
setCompiler: sinon.stub().resolves(),
|
||||
setImageName: sinon.stub().resolves(),
|
||||
setBrandVariationId: sinon.stub().resolves(),
|
||||
normalizeCompiler: sinon.stub().returnsArg(0),
|
||||
normalizeImageName: sinon.stub().returnsArg(0),
|
||||
},
|
||||
}
|
||||
ctx.ProjectRootDocManager = {
|
||||
@@ -182,6 +184,9 @@ describe('TemplatesManager', function () {
|
||||
{
|
||||
fromV1TemplateId: ctx.templateId,
|
||||
fromV1TemplateVersionId: ctx.templateVersionId,
|
||||
compiler: ctx.compiler,
|
||||
imageName: ctx.imageName,
|
||||
brandVariationId: ctx.brandVariationId,
|
||||
}
|
||||
)
|
||||
})
|
||||
@@ -190,33 +195,11 @@ describe('TemplatesManager', function () {
|
||||
ctx.fs.promises.unlink.should.have.been.calledWith(ctx.dumpPath)
|
||||
})
|
||||
|
||||
it('should set project options when passed', function (ctx) {
|
||||
ctx.ProjectOptionsHandler.promises.setCompiler.should.have.been.calledWithMatch(
|
||||
ctx.project_id,
|
||||
ctx.compiler
|
||||
)
|
||||
ctx.ProjectOptionsHandler.promises.setImageName.should.have.been.calledWithMatch(
|
||||
ctx.project_id,
|
||||
ctx.imageName
|
||||
)
|
||||
it('should set project rootDoc when passed', function (ctx) {
|
||||
ctx.ProjectRootDocManager.promises.setRootDocFromName.should.have.been.calledWithMatch(
|
||||
ctx.project_id,
|
||||
ctx.mainFile
|
||||
)
|
||||
ctx.ProjectOptionsHandler.promises.setBrandVariationId.should.have.been.calledWithMatch(
|
||||
ctx.project_id,
|
||||
ctx.brandVariationId
|
||||
)
|
||||
})
|
||||
|
||||
it('should update project', function (ctx) {
|
||||
ctx.Project.updateOne.should.have.been.calledWithMatch(
|
||||
{ _id: ctx.project_id },
|
||||
{
|
||||
fromV1TemplateId: ctx.templateId,
|
||||
fromV1TemplateVersionId: ctx.templateVersionId,
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -234,20 +217,24 @@ describe('TemplatesManager', function () {
|
||||
)
|
||||
})
|
||||
|
||||
it('should not set missing project options', function (ctx) {
|
||||
ctx.ProjectOptionsHandler.promises.setCompiler.called.should.equal(
|
||||
false
|
||||
it('should create project', function (ctx) {
|
||||
ctx.ProjectUploadManager.promises.createProjectFromZipArchiveWithName.should.have.been.calledWithMatch(
|
||||
ctx.user_id,
|
||||
ctx.templateName,
|
||||
ctx.dumpPath,
|
||||
{
|
||||
fromV1TemplateId: ctx.templateId,
|
||||
fromV1TemplateVersionId: ctx.templateVersionId,
|
||||
compiler: 'pdflatex',
|
||||
imageName: 'wl_texlive:2018.1',
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('should not set missing project options', function (ctx) {
|
||||
ctx.ProjectRootDocManager.promises.setRootDocFromName.called.should.equal(
|
||||
false
|
||||
)
|
||||
ctx.ProjectOptionsHandler.promises.setBrandVariationId.called.should.equal(
|
||||
false
|
||||
)
|
||||
ctx.ProjectOptionsHandler.promises.setImageName.should.have.been.calledWithMatch(
|
||||
ctx.project_id,
|
||||
'wl_texlive:2018.1'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user