schema.js 4.8 KB

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