projects.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. 'use strict'
  2. const Blob = require('overleaf-editor-core').Blob
  3. exports.paths = {
  4. '/projects': {
  5. post: {
  6. 'x-swagger-router-controller': 'projects',
  7. operationId: 'initializeProject',
  8. tags: ['Project'],
  9. description: 'Initialize project.',
  10. consumes: ['application/json'],
  11. parameters: [
  12. {
  13. name: 'body',
  14. in: 'body',
  15. schema: {
  16. type: 'object',
  17. properties: {
  18. projectId: { type: 'string' },
  19. },
  20. },
  21. },
  22. ],
  23. responses: {
  24. 200: {
  25. description: 'Initialized',
  26. schema: {
  27. $ref: '#/definitions/Project',
  28. },
  29. },
  30. },
  31. security: [
  32. {
  33. basic: [],
  34. },
  35. ],
  36. },
  37. },
  38. '/projects/blob-stats': {
  39. post: {
  40. 'x-swagger-router-controller': 'projects',
  41. operationId: 'getProjectBlobsStats',
  42. tags: ['Project'],
  43. description: 'Get Blob stats for projects.',
  44. consumes: ['application/json'],
  45. parameters: [
  46. {
  47. name: 'body',
  48. in: 'body',
  49. schema: {
  50. type: 'object',
  51. properties: {
  52. projectIds: {
  53. type: 'array',
  54. items: { type: 'string' },
  55. },
  56. },
  57. },
  58. },
  59. ],
  60. responses: {
  61. 200: {
  62. description: 'Initialized',
  63. schema: {
  64. type: 'array',
  65. items: {
  66. $ref: '#/definitions/ProjectBlobStats',
  67. },
  68. },
  69. },
  70. },
  71. security: [
  72. {
  73. basic: [],
  74. },
  75. ],
  76. },
  77. },
  78. '/projects/{project_id}/blob-stats': {
  79. post: {
  80. 'x-swagger-router-controller': 'projects',
  81. operationId: 'getBlobStats',
  82. tags: ['Project'],
  83. description: 'Get specific blob stats for a project.',
  84. consumes: ['application/json'],
  85. parameters: [
  86. {
  87. name: 'project_id',
  88. in: 'path',
  89. description: 'project id',
  90. required: true,
  91. type: 'string',
  92. },
  93. {
  94. name: 'body',
  95. in: 'body',
  96. required: true,
  97. schema: {
  98. type: 'object',
  99. properties: {
  100. blobHashes: {
  101. type: 'array',
  102. items: {
  103. type: 'string',
  104. },
  105. },
  106. },
  107. required: ['blobHashes'],
  108. },
  109. },
  110. ],
  111. responses: {
  112. 200: {
  113. description: 'Success',
  114. schema: {
  115. $ref: '#/definitions/ProjectBlobStats',
  116. },
  117. },
  118. },
  119. security: [
  120. {
  121. basic: [],
  122. },
  123. ],
  124. },
  125. },
  126. '/projects/{project_id}': {
  127. delete: {
  128. 'x-swagger-router-controller': 'projects',
  129. operationId: 'deleteProject',
  130. tags: ['Project'],
  131. description: "Delete a project's history",
  132. parameters: [
  133. {
  134. name: 'project_id',
  135. in: 'path',
  136. description: 'project id',
  137. required: true,
  138. type: 'string',
  139. },
  140. ],
  141. responses: {
  142. 204: {
  143. description: 'Success',
  144. },
  145. },
  146. security: [
  147. {
  148. basic: [],
  149. },
  150. ],
  151. },
  152. },
  153. '/projects/{project_id}/blobs/{hash}': {
  154. get: {
  155. 'x-swagger-router-controller': 'projects',
  156. operationId: 'getProjectBlob',
  157. tags: ['Project'],
  158. description: 'Fetch blob content by its project id and hash.',
  159. parameters: [
  160. {
  161. name: 'project_id',
  162. in: 'path',
  163. description: 'project id',
  164. required: true,
  165. type: 'string',
  166. },
  167. {
  168. name: 'hash',
  169. in: 'path',
  170. description: 'Hexadecimal SHA-1 hash',
  171. required: true,
  172. type: 'string',
  173. pattern: Blob.HEX_HASH_RX_STRING,
  174. },
  175. {
  176. name: 'range',
  177. in: 'header',
  178. description: 'HTTP Range header',
  179. required: false,
  180. type: 'string',
  181. },
  182. ],
  183. produces: ['application/octet-stream'],
  184. responses: {
  185. 200: {
  186. description: 'Success',
  187. schema: {
  188. type: 'file',
  189. },
  190. },
  191. 206: {
  192. description: 'Success',
  193. schema: {
  194. type: 'file',
  195. },
  196. },
  197. 404: {
  198. description: 'Not Found',
  199. schema: {
  200. $ref: '#/definitions/Error',
  201. },
  202. },
  203. },
  204. security: [{ jwt: [] }, { token: [] }],
  205. },
  206. head: {
  207. 'x-swagger-router-controller': 'projects',
  208. operationId: 'headProjectBlob',
  209. tags: ['Project'],
  210. description: 'Fetch blob content-length by its project id and hash.',
  211. parameters: [
  212. {
  213. name: 'project_id',
  214. in: 'path',
  215. description: 'project id',
  216. required: true,
  217. type: 'string',
  218. },
  219. {
  220. name: 'hash',
  221. in: 'path',
  222. description: 'Hexadecimal SHA-1 hash',
  223. required: true,
  224. type: 'string',
  225. pattern: Blob.HEX_HASH_RX_STRING,
  226. },
  227. ],
  228. produces: ['application/octet-stream'],
  229. responses: {
  230. 200: {
  231. description: 'Success',
  232. schema: {
  233. type: 'file',
  234. },
  235. },
  236. 404: {
  237. description: 'Not Found',
  238. schema: {
  239. $ref: '#/definitions/Error',
  240. },
  241. },
  242. },
  243. security: [{ jwt: [] }, { token: [] }],
  244. },
  245. put: {
  246. 'x-swagger-router-controller': 'projects',
  247. operationId: 'createProjectBlob',
  248. tags: ['Project'],
  249. description:
  250. 'Create blob to be used in a file addition operation when importing a' +
  251. ' snapshot or changes',
  252. parameters: [
  253. {
  254. name: 'project_id',
  255. in: 'path',
  256. description: 'project id',
  257. required: true,
  258. type: 'string',
  259. },
  260. {
  261. name: 'hash',
  262. in: 'path',
  263. description: 'Hexadecimal SHA-1 hash',
  264. required: true,
  265. type: 'string',
  266. pattern: Blob.HEX_HASH_RX_STRING,
  267. },
  268. ],
  269. responses: {
  270. 201: {
  271. description: 'Created',
  272. },
  273. },
  274. },
  275. post: {
  276. 'x-swagger-router-controller': 'projects',
  277. operationId: 'copyProjectBlob',
  278. tags: ['Project'],
  279. description:
  280. 'Copies a blob from a source project to a target project when duplicating a project',
  281. parameters: [
  282. {
  283. name: 'project_id',
  284. in: 'path',
  285. description: 'target project id',
  286. required: true,
  287. type: 'string',
  288. },
  289. {
  290. name: 'hash',
  291. in: 'path',
  292. description: 'Hexadecimal SHA-1 hash',
  293. required: true,
  294. type: 'string',
  295. pattern: Blob.HEX_HASH_RX_STRING,
  296. },
  297. {
  298. name: 'copyFrom',
  299. in: 'query',
  300. description: 'source project id',
  301. required: true,
  302. type: 'string',
  303. },
  304. ],
  305. responses: {
  306. 201: {
  307. description: 'Created',
  308. },
  309. },
  310. },
  311. },
  312. '/projects/{project_id}/latest/content': {
  313. get: {
  314. 'x-swagger-router-controller': 'projects',
  315. operationId: 'getLatestContent',
  316. tags: ['Project'],
  317. description:
  318. 'Get full content of the latest version. Text file ' +
  319. 'content is included, but binary files are just linked by hash.',
  320. parameters: [
  321. {
  322. name: 'project_id',
  323. in: 'path',
  324. description: 'project id',
  325. required: true,
  326. type: 'string',
  327. },
  328. ],
  329. responses: {
  330. 200: {
  331. description: 'Success',
  332. schema: {
  333. $ref: '#/definitions/Snapshot',
  334. },
  335. },
  336. 404: {
  337. description: 'Not Found',
  338. schema: {
  339. $ref: '#/definitions/Error',
  340. },
  341. },
  342. },
  343. },
  344. },
  345. '/projects/{project_id}/latest/hashed_content': {
  346. get: {
  347. 'x-swagger-router-controller': 'projects',
  348. operationId: 'getLatestHashedContent',
  349. tags: ['Project'],
  350. description:
  351. 'Get a snapshot of a project at the latest version ' +
  352. 'with the hashes for the contents each file',
  353. parameters: [
  354. {
  355. name: 'project_id',
  356. in: 'path',
  357. description: 'project id',
  358. required: true,
  359. type: 'string',
  360. },
  361. ],
  362. responses: {
  363. 200: {
  364. description: 'Success',
  365. schema: {
  366. $ref: '#/definitions/Snapshot',
  367. },
  368. },
  369. 404: {
  370. description: 'Not Found',
  371. schema: {
  372. $ref: '#/definitions/Error',
  373. },
  374. },
  375. },
  376. security: [
  377. {
  378. basic: [],
  379. },
  380. ],
  381. },
  382. },
  383. '/projects/{project_id}/latest/history': {
  384. get: {
  385. 'x-swagger-router-controller': 'projects',
  386. operationId: 'getLatestHistory',
  387. tags: ['Project'],
  388. description:
  389. 'Get the latest sequence of changes.' +
  390. ' TODO probably want a configurable depth.',
  391. parameters: [
  392. {
  393. name: 'project_id',
  394. in: 'path',
  395. description: 'project id',
  396. required: true,
  397. type: 'string',
  398. },
  399. ],
  400. responses: {
  401. 200: {
  402. description: 'Success',
  403. schema: {
  404. $ref: '#/definitions/ChunkResponse',
  405. },
  406. },
  407. 404: {
  408. description: 'Not Found',
  409. schema: {
  410. $ref: '#/definitions/Error',
  411. },
  412. },
  413. },
  414. },
  415. },
  416. '/projects/{project_id}/latest/history/raw': {
  417. get: {
  418. 'x-swagger-router-controller': 'projects',
  419. operationId: 'getLatestHistoryRaw',
  420. tags: ['Project'],
  421. description: 'Get the metadata of latest sequence of changes.',
  422. parameters: [
  423. {
  424. name: 'project_id',
  425. in: 'path',
  426. description: 'project id',
  427. required: true,
  428. type: 'string',
  429. },
  430. {
  431. name: 'readOnly',
  432. in: 'query',
  433. description: 'use read only database connection',
  434. required: false,
  435. type: 'boolean',
  436. },
  437. ],
  438. responses: {
  439. 200: {
  440. description: 'Success',
  441. schema: {
  442. $ref: '#/definitions/ChunkResponseRaw',
  443. },
  444. },
  445. 404: {
  446. description: 'Not Found',
  447. schema: {
  448. $ref: '#/definitions/Error',
  449. },
  450. },
  451. },
  452. },
  453. },
  454. '/projects/{project_id}/latest/persistedHistory': {
  455. get: {
  456. 'x-swagger-router-controller': 'projects',
  457. operationId: 'getLatestPersistedHistory',
  458. tags: ['Project'],
  459. description: 'Get the latest sequence of changes.',
  460. parameters: [
  461. {
  462. name: 'project_id',
  463. in: 'path',
  464. description: 'project id',
  465. required: true,
  466. type: 'string',
  467. },
  468. ],
  469. responses: {
  470. 200: {
  471. description: 'Success',
  472. schema: {
  473. $ref: '#/definitions/ChunkResponse',
  474. },
  475. },
  476. 404: {
  477. description: 'Not Found',
  478. schema: {
  479. $ref: '#/definitions/Error',
  480. },
  481. },
  482. },
  483. },
  484. },
  485. '/projects/{project_id}/versions/{version}/history': {
  486. get: {
  487. 'x-swagger-router-controller': 'projects',
  488. operationId: 'getHistory',
  489. tags: ['Project'],
  490. description:
  491. 'Get the sequence of changes that includes the given version.',
  492. parameters: [
  493. {
  494. name: 'project_id',
  495. in: 'path',
  496. description: 'project id',
  497. required: true,
  498. type: 'string',
  499. },
  500. {
  501. name: 'version',
  502. in: 'path',
  503. description: 'numeric version',
  504. required: true,
  505. type: 'number',
  506. },
  507. ],
  508. responses: {
  509. 200: {
  510. description: 'Success',
  511. schema: {
  512. $ref: '#/definitions/ChunkResponse',
  513. },
  514. },
  515. 404: {
  516. description: 'Not Found',
  517. schema: {
  518. $ref: '#/definitions/Error',
  519. },
  520. },
  521. },
  522. },
  523. },
  524. '/projects/{project_id}/versions/{version}/content': {
  525. get: {
  526. 'x-swagger-router-controller': 'projects',
  527. operationId: 'getContentAtVersion',
  528. tags: ['Project'],
  529. description: 'Get full content at the given version',
  530. parameters: [
  531. {
  532. name: 'project_id',
  533. in: 'path',
  534. description: 'project id',
  535. required: true,
  536. type: 'string',
  537. },
  538. {
  539. name: 'version',
  540. in: 'path',
  541. description: 'numeric version',
  542. required: true,
  543. type: 'number',
  544. },
  545. ],
  546. responses: {
  547. 200: {
  548. description: 'Success',
  549. schema: {
  550. $ref: '#/definitions/Snapshot',
  551. },
  552. },
  553. 404: {
  554. description: 'Not Found',
  555. schema: {
  556. $ref: '#/definitions/Error',
  557. },
  558. },
  559. },
  560. },
  561. },
  562. '/projects/{project_id}/timestamp/{timestamp}/history': {
  563. get: {
  564. 'x-swagger-router-controller': 'projects',
  565. operationId: 'getHistoryBefore',
  566. tags: ['Project'],
  567. description:
  568. 'Get the sequence of changes. ' + ' before the given timestamp',
  569. parameters: [
  570. {
  571. name: 'project_id',
  572. in: 'path',
  573. description: 'project id',
  574. required: true,
  575. type: 'string',
  576. },
  577. {
  578. name: 'timestamp',
  579. in: 'path',
  580. description: 'timestamp',
  581. required: true,
  582. type: 'string',
  583. format: 'date-time',
  584. },
  585. ],
  586. responses: {
  587. 200: {
  588. description: 'Success',
  589. schema: {
  590. $ref: '#/definitions/ChunkResponse',
  591. },
  592. },
  593. 404: {
  594. description: 'Not Found',
  595. schema: {
  596. $ref: '#/definitions/Error',
  597. },
  598. },
  599. },
  600. },
  601. },
  602. '/projects/{project_id}/version/{version}/zip': {
  603. get: {
  604. 'x-swagger-router-controller': 'projects',
  605. operationId: 'getZip',
  606. tags: ['Project'],
  607. description: 'Download zip with project content',
  608. parameters: [
  609. {
  610. name: 'project_id',
  611. in: 'path',
  612. description: 'project id',
  613. required: true,
  614. type: 'string',
  615. },
  616. {
  617. name: 'version',
  618. in: 'path',
  619. description: 'numeric version',
  620. required: true,
  621. type: 'number',
  622. },
  623. ],
  624. produces: ['application/octet-stream'],
  625. responses: {
  626. 200: {
  627. description: 'success',
  628. },
  629. 404: {
  630. description: 'not found',
  631. },
  632. },
  633. security: [
  634. {
  635. token: [],
  636. },
  637. ],
  638. },
  639. post: {
  640. 'x-swagger-router-controller': 'projects',
  641. operationId: 'createZip',
  642. tags: ['Project'],
  643. description:
  644. 'Create a zip file with project content. Returns a link to be polled.',
  645. parameters: [
  646. {
  647. name: 'project_id',
  648. in: 'path',
  649. description: 'project id',
  650. required: true,
  651. type: 'string',
  652. },
  653. {
  654. name: 'version',
  655. in: 'path',
  656. description: 'numeric version',
  657. required: true,
  658. type: 'number',
  659. },
  660. ],
  661. responses: {
  662. 200: {
  663. description: 'success',
  664. schema: {
  665. $ref: '#/definitions/ZipInfo',
  666. },
  667. },
  668. 404: {
  669. description: 'not found',
  670. },
  671. },
  672. security: [
  673. {
  674. basic: [],
  675. },
  676. ],
  677. },
  678. },
  679. }