fix_malformed_filetree.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. const { ObjectId } = require('mongodb')
  2. const { db, waitForDb } = require('../app/src/infrastructure/mongodb')
  3. async function main() {
  4. const { projectId, mongoPath } = parseArgs()
  5. await waitForDb()
  6. const pathSegments = mongoPath.split('.')
  7. const lastPathSegment = pathSegments[pathSegments.length - 1]
  8. let modifiedCount
  9. if (mongoPath === 'rootFolder.0') {
  10. modifiedCount = await fixRootFolder(projectId)
  11. } else if (endsWithNumber(mongoPath)) {
  12. modifiedCount = await removeNullFolders(projectId, parentPath(mongoPath))
  13. } else if (['docs', 'folders', 'fileRefs'].includes(lastPathSegment)) {
  14. modifiedCount = await ensureElementIsArray(projectId, mongoPath)
  15. } else {
  16. console.error(`Unexpected mongo path: ${mongoPath}`)
  17. process.exit(1)
  18. }
  19. console.log(`${modifiedCount} project(s) modified`)
  20. process.exit(0)
  21. }
  22. function parseArgs() {
  23. const args = process.argv.slice(2)
  24. if (args.length !== 2) {
  25. console.error('Usage: fix_malformed_filetree.js PROJECT_ID MONGO_PATH')
  26. process.exit(1)
  27. }
  28. const [projectId, mongoPath] = args
  29. return { projectId: ObjectId(projectId), mongoPath }
  30. }
  31. function endsWithNumber(path) {
  32. return /\.\d+$/.test(path)
  33. }
  34. function parentPath(path) {
  35. return path.slice(0, path.lastIndexOf('.'))
  36. }
  37. /**
  38. * If the root folder structure is missing, set it up
  39. */
  40. async function fixRootFolder(projectId) {
  41. const result = await db.projects.updateOne(
  42. { _id: projectId, rootFolder: [] },
  43. {
  44. $set: {
  45. rootFolder: [
  46. {
  47. _id: ObjectId(),
  48. name: 'rootFolder',
  49. folders: [],
  50. docs: [],
  51. fileRefs: [],
  52. },
  53. ],
  54. },
  55. }
  56. )
  57. return result.modifiedCount
  58. }
  59. /**
  60. * Remove all null entries from the given folders array
  61. */
  62. async function removeNullFolders(projectId, foldersPath) {
  63. const result = await db.projects.updateOne(
  64. { _id: projectId, [foldersPath]: { $exists: true } },
  65. { $pull: { [foldersPath]: null } }
  66. )
  67. return result.modifiedCount
  68. }
  69. /**
  70. * If the element at the given path is not an array, set it to an empty array
  71. */
  72. async function ensureElementIsArray(projectId, path) {
  73. const result = await db.projects.updateOne(
  74. { _id: projectId, [path]: { $not: { $type: 'array' } } },
  75. { $set: { [path]: [] } }
  76. )
  77. return result.modifiedCount
  78. }
  79. main()
  80. .then(() => {
  81. process.exit(0)
  82. })
  83. .catch(err => {
  84. console.error(err)
  85. process.exit(1)
  86. })