schema.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. 'use strict'
  2. const { z, zz } = require('@overleaf/validation-tools')
  3. const Blob = require('overleaf-editor-core').Blob
  4. const hexHashPattern = new RegExp(Blob.HEX_HASH_RX_STRING)
  5. const fileSchema = z
  6. .object({
  7. hash: z.string().optional(),
  8. byteLength: z.number().int().nullable().optional(),
  9. stringLength: z.number().int().nullable().optional(),
  10. metadata: z.object({}).passthrough().optional(),
  11. })
  12. .passthrough()
  13. const snapshotSchema = z.object({
  14. files: z.record(z.string(), fileSchema),
  15. })
  16. const v2DocVersionsSchema = z.object({
  17. pathname: z.string().optional(),
  18. v: z.number().int().optional(),
  19. })
  20. const operationSchema = z
  21. .object({
  22. pathname: z.string().optional(),
  23. newPathname: z.string().optional(),
  24. blob: z
  25. .object({
  26. hash: z.string(),
  27. })
  28. .optional(),
  29. textOperation: z.array(z.any()).optional(),
  30. file: fileSchema.optional(),
  31. contentHash: z.string().optional(),
  32. })
  33. .passthrough()
  34. const originSchema = z
  35. .object({
  36. kind: z.string().optional(),
  37. })
  38. .passthrough()
  39. const changeSchema = z
  40. .object({
  41. timestamp: z.string(),
  42. operations: z.array(operationSchema),
  43. authors: z.array(z.number().int().nullable()).optional(),
  44. v2Authors: z.array(z.string().nullable()).optional(),
  45. origin: originSchema.optional(),
  46. projectVersion: z.string().optional(),
  47. v2DocVersions: z.record(z.string(), v2DocVersionsSchema).optional(),
  48. })
  49. .passthrough()
  50. const schemas = {
  51. projectId: z.object({
  52. params: z
  53. .object({
  54. project_id: z.string().optional(),
  55. })
  56. .optional(),
  57. }),
  58. initializeProject: z.object({
  59. body: z
  60. .object({
  61. projectId: z.string().optional(),
  62. })
  63. .optional(),
  64. }),
  65. cloneProject: z.object({
  66. body: z.object({
  67. targetProjectId: z.string(),
  68. }),
  69. params: z.object({
  70. project_id: z.string(),
  71. }),
  72. }),
  73. getProjectBlobsStats: z.object({
  74. body: z.object({
  75. projectIds: z.array(z.string()),
  76. }),
  77. }),
  78. getBlobStats: z.object({
  79. params: z.object({
  80. project_id: z.string(),
  81. }),
  82. body: z.object({
  83. blobHashes: z.array(z.string()),
  84. }),
  85. }),
  86. deleteProject: z.object({
  87. params: z.object({
  88. project_id: z.string(),
  89. }),
  90. body: z.any().optional(),
  91. }),
  92. getProjectBlob: z.object({
  93. params: z.object({
  94. project_id: z.string(),
  95. hash: z.string().regex(hexHashPattern),
  96. }),
  97. headers: z.object({
  98. range: z.string().optional(),
  99. }),
  100. }),
  101. headProjectBlob: z.object({
  102. params: z.object({
  103. project_id: z.string(),
  104. hash: z.string().regex(hexHashPattern),
  105. }),
  106. }),
  107. createProjectBlob: z.object({
  108. params: z.object({
  109. project_id: z.string(),
  110. hash: z.string().regex(hexHashPattern),
  111. }),
  112. body: z.any().optional(),
  113. }),
  114. copyProjectBlob: z.object({
  115. params: z.object({
  116. project_id: z.string(),
  117. hash: z.string().regex(hexHashPattern),
  118. }),
  119. query: z.object({
  120. copyFrom: z.string(),
  121. }),
  122. body: z.any().optional(),
  123. }),
  124. getLatestContent: z.object({
  125. params: z.object({
  126. project_id: z.string(),
  127. }),
  128. }),
  129. getLatestHashedContent: z.object({
  130. params: z.object({
  131. project_id: z.string(),
  132. }),
  133. }),
  134. getLatestHistory: z.object({
  135. params: z.object({
  136. project_id: z.string(),
  137. }),
  138. }),
  139. getLatestHistoryRaw: z.object({
  140. params: z.object({
  141. project_id: z.string(),
  142. }),
  143. query: z.object({
  144. readOnly: z.coerce.boolean().optional(),
  145. }),
  146. }),
  147. getLatestPersistedHistory: z.object({
  148. params: z.object({
  149. project_id: z.string(),
  150. }),
  151. }),
  152. getHistory: z.object({
  153. params: z.object({
  154. project_id: z.string(),
  155. version: z.coerce.number(),
  156. }),
  157. }),
  158. getContentAtVersion: z.object({
  159. params: z.object({
  160. project_id: z.string(),
  161. version: z.coerce.number(),
  162. }),
  163. }),
  164. getHistoryBefore: z.object({
  165. params: z.object({
  166. project_id: z.string(),
  167. timestamp: zz.datetime(),
  168. }),
  169. }),
  170. getZip: z.object({
  171. params: z.object({
  172. project_id: z.string(),
  173. version: z.coerce.number(),
  174. }),
  175. }),
  176. createZip: z.object({
  177. params: z.object({
  178. project_id: z.string(),
  179. version: z.coerce.number(),
  180. }),
  181. body: z.any().optional(),
  182. }),
  183. getChanges: z.object({
  184. params: z.object({
  185. project_id: z.string(),
  186. }),
  187. query: z.object({
  188. since: z.coerce.number().optional(),
  189. }),
  190. }),
  191. importSnapshot: z.object({
  192. params: z.object({
  193. project_id: z.string(),
  194. }),
  195. body: snapshotSchema,
  196. }),
  197. importChanges: z.object({
  198. params: z.object({
  199. project_id: z.string(),
  200. }),
  201. query: z.object({
  202. end_version: z.coerce.number(),
  203. return_snapshot: z.enum(['hashed', 'none']).optional(),
  204. }),
  205. body: z.array(changeSchema),
  206. }),
  207. flushChanges: z.object({
  208. params: z.object({
  209. project_id: z.string(),
  210. }),
  211. body: z.any().optional(),
  212. }),
  213. expireProject: z.object({
  214. params: z.object({
  215. project_id: z.string(),
  216. }),
  217. body: z.any().optional(),
  218. }),
  219. }
  220. module.exports = schemas