@crowi/api 2.0.0-alpha.1 → 2.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (403) hide show
  1. package/dist/hono/handlers/activation.d.ts +3 -3
  2. package/dist/hono/handlers/admin/users.d.ts +118 -0
  3. package/dist/hono/handlers/admin/users.js +28 -0
  4. package/dist/hono/handlers/admin/users.js.map +1 -1
  5. package/dist/hono/handlers/app.d.ts +1 -0
  6. package/dist/hono/handlers/app.js +11 -0
  7. package/dist/hono/handlers/app.js.map +1 -1
  8. package/dist/hono/handlers/attachment-stream.js +23 -0
  9. package/dist/hono/handlers/attachment-stream.js.map +1 -1
  10. package/dist/hono/handlers/draft.js +10 -0
  11. package/dist/hono/handlers/draft.js.map +1 -1
  12. package/dist/hono/handlers/emailChange.d.ts +4 -4
  13. package/dist/hono/handlers/inviteAccept.d.ts +6 -6
  14. package/dist/hono/handlers/page.d.ts +251 -0
  15. package/dist/hono/handlers/page.js +123 -6
  16. package/dist/hono/handlers/page.js.map +1 -1
  17. package/dist/hono/handlers/passwordReset.d.ts +5 -5
  18. package/dist/hono/handlers/tokenAuth.d.ts +7 -7
  19. package/dist/mcp/result.d.ts +42 -16
  20. package/dist/mcp/result.js +56 -10
  21. package/dist/mcp/result.js.map +1 -1
  22. package/dist/mcp/tools/page.js +21 -1
  23. package/dist/mcp/tools/page.js.map +1 -1
  24. package/dist/mcp/tools/search.d.ts +12 -0
  25. package/dist/mcp/tools/search.js +21 -5
  26. package/dist/mcp/tools/search.js.map +1 -1
  27. package/dist/migration/helpers.d.ts +13 -0
  28. package/dist/migration/helpers.js +29 -0
  29. package/dist/migration/helpers.js.map +1 -0
  30. package/dist/migration/migrations/files-url-to-attachments.d.ts +35 -0
  31. package/dist/migration/migrations/files-url-to-attachments.js +291 -0
  32. package/dist/migration/migrations/files-url-to-attachments.js.map +1 -0
  33. package/dist/migration/migrations/index.js +4 -0
  34. package/dist/migration/migrations/index.js.map +1 -1
  35. package/dist/migration/migrations/published-current-revision.d.ts +47 -0
  36. package/dist/migration/migrations/published-current-revision.js +90 -0
  37. package/dist/migration/migrations/published-current-revision.js.map +1 -0
  38. package/dist/migration/migrations/wikilink-format.d.ts +0 -11
  39. package/dist/migration/migrations/wikilink-format.js +5 -156
  40. package/dist/migration/migrations/wikilink-format.js.map +1 -1
  41. package/dist/migration/migrations/wikilink-html-recover.d.ts +116 -0
  42. package/dist/migration/migrations/wikilink-html-recover.js +314 -0
  43. package/dist/migration/migrations/wikilink-html-recover.js.map +1 -0
  44. package/dist/models/page.d.ts +3 -0
  45. package/dist/models/page.js +31 -0
  46. package/dist/models/page.js.map +1 -1
  47. package/dist/models/user.d.ts +1 -0
  48. package/dist/models/user.js +40 -21
  49. package/dist/models/user.js.map +1 -1
  50. package/dist/renderer/core/headings.d.ts +12 -1
  51. package/dist/renderer/core/headings.js +48 -8
  52. package/dist/renderer/core/headings.js.map +1 -1
  53. package/dist/renderer/pipeline.d.ts +6 -0
  54. package/dist/renderer/pipeline.js.map +1 -1
  55. package/dist/util/page-response.js +19 -2
  56. package/dist/util/page-response.js.map +1 -1
  57. package/package.json +12 -6
  58. package/views/mail/layout.mjml +7 -5
  59. package/dist/common/functions/path2name.d.ts +0 -1
  60. package/dist/common/functions/path2name.js +0 -22
  61. package/dist/common/functions/path2name.js.map +0 -1
  62. package/dist/common/functions/renderIcon.d.ts +0 -1
  63. package/dist/common/functions/renderIcon.js +0 -9
  64. package/dist/common/functions/renderIcon.js.map +0 -1
  65. package/dist/controllers/admin.d.ts +0 -3
  66. package/dist/controllers/admin.js +0 -474
  67. package/dist/controllers/admin.js.map +0 -1
  68. package/dist/controllers/attachment.d.ts +0 -4
  69. package/dist/controllers/attachment.js +0 -200
  70. package/dist/controllers/attachment.js.map +0 -1
  71. package/dist/controllers/backlink.d.ts +0 -3
  72. package/dist/controllers/backlink.js +0 -42
  73. package/dist/controllers/backlink.js.map +0 -1
  74. package/dist/controllers/bookmark.d.ts +0 -3
  75. package/dist/controllers/bookmark.js +0 -100
  76. package/dist/controllers/bookmark.js.map +0 -1
  77. package/dist/controllers/comment.d.ts +0 -3
  78. package/dist/controllers/comment.js +0 -111
  79. package/dist/controllers/comment.js.map +0 -1
  80. package/dist/controllers/index.d.ts +0 -25
  81. package/dist/controllers/index.js +0 -44
  82. package/dist/controllers/index.js.map +0 -1
  83. package/dist/controllers/installer.d.ts +0 -3
  84. package/dist/controllers/installer.js +0 -48
  85. package/dist/controllers/installer.js.map +0 -1
  86. package/dist/controllers/login.d.ts +0 -4
  87. package/dist/controllers/login.js +0 -438
  88. package/dist/controllers/login.js.map +0 -1
  89. package/dist/controllers/logout.d.ts +0 -5
  90. package/dist/controllers/logout.js +0 -11
  91. package/dist/controllers/logout.js.map +0 -1
  92. package/dist/controllers/me.d.ts +0 -4
  93. package/dist/controllers/me.js +0 -369
  94. package/dist/controllers/me.js.map +0 -1
  95. package/dist/controllers/notification.d.ts +0 -3
  96. package/dist/controllers/notification.js +0 -88
  97. package/dist/controllers/notification.js.map +0 -1
  98. package/dist/controllers/page.d.ts +0 -3
  99. package/dist/controllers/page.js +0 -881
  100. package/dist/controllers/page.js.map +0 -1
  101. package/dist/controllers/revision.d.ts +0 -3
  102. package/dist/controllers/revision.js +0 -91
  103. package/dist/controllers/revision.js.map +0 -1
  104. package/dist/controllers/search.d.ts +0 -3
  105. package/dist/controllers/search.js +0 -93
  106. package/dist/controllers/search.js.map +0 -1
  107. package/dist/controllers/share.d.ts +0 -3
  108. package/dist/controllers/share.js +0 -207
  109. package/dist/controllers/share.js.map +0 -1
  110. package/dist/controllers/shareAccess.d.ts +0 -3
  111. package/dist/controllers/shareAccess.js +0 -28
  112. package/dist/controllers/shareAccess.js.map +0 -1
  113. package/dist/controllers/slack.d.ts +0 -3
  114. package/dist/controllers/slack.js +0 -87
  115. package/dist/controllers/slack.js.map +0 -1
  116. package/dist/controllers/tokenAuth.d.ts +0 -10
  117. package/dist/controllers/tokenAuth.js +0 -292
  118. package/dist/controllers/tokenAuth.js.map +0 -1
  119. package/dist/controllers/user.d.ts +0 -3
  120. package/dist/controllers/user.js +0 -67
  121. package/dist/controllers/user.js.map +0 -1
  122. package/dist/controllers/version.d.ts +0 -4
  123. package/dist/controllers/version.js +0 -19
  124. package/dist/controllers/version.js.map +0 -1
  125. package/dist/crowi/express-init.d.ts +0 -4
  126. package/dist/crowi/express-init.js +0 -101
  127. package/dist/crowi/express-init.js.map +0 -1
  128. package/dist/form/admin/app.d.ts +0 -2
  129. package/dist/form/admin/app.js +0 -9
  130. package/dist/form/admin/app.js.map +0 -1
  131. package/dist/form/admin/auth.d.ts +0 -2
  132. package/dist/form/admin/auth.js +0 -9
  133. package/dist/form/admin/auth.js.map +0 -1
  134. package/dist/form/admin/aws.d.ts +0 -2
  135. package/dist/form/admin/aws.js +0 -13
  136. package/dist/form/admin/aws.js.map +0 -1
  137. package/dist/form/admin/github.d.ts +0 -2
  138. package/dist/form/admin/github.js +0 -15
  139. package/dist/form/admin/github.js.map +0 -1
  140. package/dist/form/admin/google.d.ts +0 -2
  141. package/dist/form/admin/google.js +0 -13
  142. package/dist/form/admin/google.js.map +0 -1
  143. package/dist/form/admin/mail.d.ts +0 -2
  144. package/dist/form/admin/mail.js +0 -13
  145. package/dist/form/admin/mail.js.map +0 -1
  146. package/dist/form/admin/sec.d.ts +0 -2
  147. package/dist/form/admin/sec.js +0 -10
  148. package/dist/form/admin/sec.js.map +0 -1
  149. package/dist/form/admin/slackSetting.d.ts +0 -2
  150. package/dist/form/admin/slackSetting.js +0 -13
  151. package/dist/form/admin/slackSetting.js.map +0 -1
  152. package/dist/form/admin/userEdit.d.ts +0 -2
  153. package/dist/form/admin/userEdit.js +0 -9
  154. package/dist/form/admin/userEdit.js.map +0 -1
  155. package/dist/form/admin/userInvite.d.ts +0 -2
  156. package/dist/form/admin/userInvite.js +0 -9
  157. package/dist/form/admin/userInvite.js.map +0 -1
  158. package/dist/form/comment.d.ts +0 -2
  159. package/dist/form/comment.js +0 -9
  160. package/dist/form/comment.js.map +0 -1
  161. package/dist/form/index.d.ts +0 -25
  162. package/dist/form/index.js +0 -48
  163. package/dist/form/index.js.map +0 -1
  164. package/dist/form/invited.d.ts +0 -2
  165. package/dist/form/invited.js +0 -13
  166. package/dist/form/invited.js.map +0 -1
  167. package/dist/form/login.d.ts +0 -2
  168. package/dist/form/login.js +0 -11
  169. package/dist/form/login.js.map +0 -1
  170. package/dist/form/me/apiToken.d.ts +0 -2
  171. package/dist/form/me/apiToken.js +0 -9
  172. package/dist/form/me/apiToken.js.map +0 -1
  173. package/dist/form/me/password.d.ts +0 -2
  174. package/dist/form/me/password.js +0 -11
  175. package/dist/form/me/password.js.map +0 -1
  176. package/dist/form/me/user.d.ts +0 -2
  177. package/dist/form/me/user.js +0 -9
  178. package/dist/form/me/user.js.map +0 -1
  179. package/dist/form/register.d.ts +0 -2
  180. package/dist/form/register.js +0 -13
  181. package/dist/form/register.js.map +0 -1
  182. package/dist/form/revision.d.ts +0 -2
  183. package/dist/form/revision.js +0 -13
  184. package/dist/form/revision.js.map +0 -1
  185. package/dist/hono/handlers/admin/share.d.ts +0 -106
  186. package/dist/hono/handlers/admin/share.js +0 -55
  187. package/dist/hono/handlers/admin/share.js.map +0 -1
  188. package/dist/middlewares/accessTokenParser.d.ts +0 -4
  189. package/dist/middlewares/accessTokenParser.js +0 -29
  190. package/dist/middlewares/accessTokenParser.js.map +0 -1
  191. package/dist/middlewares/adminRequired.d.ts +0 -10
  192. package/dist/middlewares/adminRequired.js +0 -35
  193. package/dist/middlewares/adminRequired.js.map +0 -1
  194. package/dist/middlewares/applicationInstalled.d.ts +0 -3
  195. package/dist/middlewares/applicationInstalled.js +0 -20
  196. package/dist/middlewares/applicationInstalled.js.map +0 -1
  197. package/dist/middlewares/applicationNotInstalled.d.ts +0 -3
  198. package/dist/middlewares/applicationNotInstalled.js +0 -13
  199. package/dist/middlewares/applicationNotInstalled.js.map +0 -1
  200. package/dist/middlewares/basicAuth.d.ts +0 -4
  201. package/dist/middlewares/basicAuth.js +0 -23
  202. package/dist/middlewares/basicAuth.js.map +0 -1
  203. package/dist/middlewares/csrfVerify.d.ts +0 -4
  204. package/dist/middlewares/csrfVerify.js +0 -24
  205. package/dist/middlewares/csrfVerify.js.map +0 -1
  206. package/dist/middlewares/encodeSpace.d.ts +0 -3
  207. package/dist/middlewares/encodeSpace.js +0 -14
  208. package/dist/middlewares/encodeSpace.js.map +0 -1
  209. package/dist/middlewares/fileAccessRightOrLoginRequired.d.ts +0 -4
  210. package/dist/middlewares/fileAccessRightOrLoginRequired.js +0 -29
  211. package/dist/middlewares/fileAccessRightOrLoginRequired.js.map +0 -1
  212. package/dist/middlewares/index.d.ts +0 -16
  213. package/dist/middlewares/index.js +0 -30
  214. package/dist/middlewares/index.js.map +0 -1
  215. package/dist/middlewares/jwtAdminRequired.d.ts +0 -8
  216. package/dist/middlewares/jwtAdminRequired.js +0 -35
  217. package/dist/middlewares/jwtAdminRequired.js.map +0 -1
  218. package/dist/middlewares/jwtAuth.d.ts +0 -4
  219. package/dist/middlewares/jwtAuth.js +0 -104
  220. package/dist/middlewares/jwtAuth.js.map +0 -1
  221. package/dist/middlewares/loginChecker.d.ts +0 -4
  222. package/dist/middlewares/loginChecker.js +0 -32
  223. package/dist/middlewares/loginChecker.js.map +0 -1
  224. package/dist/middlewares/loginRequired.d.ts +0 -4
  225. package/dist/middlewares/loginRequired.js +0 -88
  226. package/dist/middlewares/loginRequired.js.map +0 -1
  227. package/dist/routes/admin.d.ts +0 -4
  228. package/dist/routes/admin.js +0 -17
  229. package/dist/routes/admin.js.map +0 -1
  230. package/dist/routes/api/admin.d.ts +0 -4
  231. package/dist/routes/api/admin.js +0 -37
  232. package/dist/routes/api/admin.js.map +0 -1
  233. package/dist/routes/api/attachment.d.ts +0 -4
  234. package/dist/routes/api/attachment.js +0 -19
  235. package/dist/routes/api/attachment.js.map +0 -1
  236. package/dist/routes/api/bookmark.d.ts +0 -4
  237. package/dist/routes/api/bookmark.js +0 -15
  238. package/dist/routes/api/bookmark.js.map +0 -1
  239. package/dist/routes/api/comment.d.ts +0 -4
  240. package/dist/routes/api/comment.js +0 -14
  241. package/dist/routes/api/comment.js.map +0 -1
  242. package/dist/routes/api/index.d.ts +0 -4
  243. package/dist/routes/api/index.js +0 -36
  244. package/dist/routes/api/index.js.map +0 -1
  245. package/dist/routes/api/like.d.ts +0 -4
  246. package/dist/routes/api/like.js +0 -13
  247. package/dist/routes/api/like.js.map +0 -1
  248. package/dist/routes/api/notification.d.ts +0 -4
  249. package/dist/routes/api/notification.js +0 -15
  250. package/dist/routes/api/notification.js.map +0 -1
  251. package/dist/routes/api/page.d.ts +0 -4
  252. package/dist/routes/api/page.js +0 -24
  253. package/dist/routes/api/page.js.map +0 -1
  254. package/dist/routes/api/revision.d.ts +0 -4
  255. package/dist/routes/api/revision.js +0 -14
  256. package/dist/routes/api/revision.js.map +0 -1
  257. package/dist/routes/api/share.d.ts +0 -4
  258. package/dist/routes/api/share.js +0 -16
  259. package/dist/routes/api/share.js.map +0 -1
  260. package/dist/routes/api/version.d.ts +0 -4
  261. package/dist/routes/api/version.js +0 -10
  262. package/dist/routes/api/version.js.map +0 -1
  263. package/dist/routes/index.d.ts +0 -4
  264. package/dist/routes/index.js +0 -71
  265. package/dist/routes/index.js.map +0 -1
  266. package/dist/routes/login.d.ts +0 -4
  267. package/dist/routes/login.js +0 -18
  268. package/dist/routes/login.js.map +0 -1
  269. package/dist/routes/me.d.ts +0 -4
  270. package/dist/routes/me.js +0 -24
  271. package/dist/routes/me.js.map +0 -1
  272. package/dist/routes/ts-rest/admin/app.d.ts +0 -4
  273. package/dist/routes/ts-rest/admin/app.js +0 -67
  274. package/dist/routes/ts-rest/admin/app.js.map +0 -1
  275. package/dist/routes/ts-rest/admin/auth.d.ts +0 -4
  276. package/dist/routes/ts-rest/admin/auth.js +0 -95
  277. package/dist/routes/ts-rest/admin/auth.js.map +0 -1
  278. package/dist/routes/ts-rest/admin/index.d.ts +0 -10
  279. package/dist/routes/ts-rest/admin/index.js +0 -35
  280. package/dist/routes/ts-rest/admin/index.js.map +0 -1
  281. package/dist/routes/ts-rest/admin/mail.d.ts +0 -4
  282. package/dist/routes/ts-rest/admin/mail.js +0 -156
  283. package/dist/routes/ts-rest/admin/mail.js.map +0 -1
  284. package/dist/routes/ts-rest/admin/plugins.d.ts +0 -4
  285. package/dist/routes/ts-rest/admin/plugins.js +0 -317
  286. package/dist/routes/ts-rest/admin/plugins.js.map +0 -1
  287. package/dist/routes/ts-rest/admin/search.d.ts +0 -4
  288. package/dist/routes/ts-rest/admin/search.js +0 -67
  289. package/dist/routes/ts-rest/admin/search.js.map +0 -1
  290. package/dist/routes/ts-rest/admin/security.d.ts +0 -4
  291. package/dist/routes/ts-rest/admin/security.js +0 -114
  292. package/dist/routes/ts-rest/admin/security.js.map +0 -1
  293. package/dist/routes/ts-rest/admin/share.d.ts +0 -4
  294. package/dist/routes/ts-rest/admin/share.js +0 -69
  295. package/dist/routes/ts-rest/admin/share.js.map +0 -1
  296. package/dist/routes/ts-rest/admin/storage.d.ts +0 -4
  297. package/dist/routes/ts-rest/admin/storage.js +0 -59
  298. package/dist/routes/ts-rest/admin/storage.js.map +0 -1
  299. package/dist/routes/ts-rest/admin/users.d.ts +0 -4
  300. package/dist/routes/ts-rest/admin/users.js +0 -215
  301. package/dist/routes/ts-rest/admin/users.js.map +0 -1
  302. package/dist/routes/ts-rest/adminCrypto.d.ts +0 -4
  303. package/dist/routes/ts-rest/adminCrypto.js +0 -111
  304. package/dist/routes/ts-rest/adminCrypto.js.map +0 -1
  305. package/dist/routes/ts-rest/app.d.ts +0 -4
  306. package/dist/routes/ts-rest/app.js +0 -23
  307. package/dist/routes/ts-rest/app.js.map +0 -1
  308. package/dist/routes/ts-rest/attachment.d.ts +0 -4
  309. package/dist/routes/ts-rest/attachment.js +0 -830
  310. package/dist/routes/ts-rest/attachment.js.map +0 -1
  311. package/dist/routes/ts-rest/auth.d.ts +0 -4
  312. package/dist/routes/ts-rest/auth.js +0 -70
  313. package/dist/routes/ts-rest/auth.js.map +0 -1
  314. package/dist/routes/ts-rest/autocomplete.d.ts +0 -30
  315. package/dist/routes/ts-rest/autocomplete.js +0 -189
  316. package/dist/routes/ts-rest/autocomplete.js.map +0 -1
  317. package/dist/routes/ts-rest/backlink.d.ts +0 -4
  318. package/dist/routes/ts-rest/backlink.js +0 -106
  319. package/dist/routes/ts-rest/backlink.js.map +0 -1
  320. package/dist/routes/ts-rest/bookmark.d.ts +0 -4
  321. package/dist/routes/ts-rest/bookmark.js +0 -189
  322. package/dist/routes/ts-rest/bookmark.js.map +0 -1
  323. package/dist/routes/ts-rest/comment.d.ts +0 -4
  324. package/dist/routes/ts-rest/comment.js +0 -217
  325. package/dist/routes/ts-rest/comment.js.map +0 -1
  326. package/dist/routes/ts-rest/draft.d.ts +0 -22
  327. package/dist/routes/ts-rest/draft.js +0 -200
  328. package/dist/routes/ts-rest/draft.js.map +0 -1
  329. package/dist/routes/ts-rest/index.d.ts +0 -4
  330. package/dist/routes/ts-rest/index.js +0 -103
  331. package/dist/routes/ts-rest/index.js.map +0 -1
  332. package/dist/routes/ts-rest/installer.d.ts +0 -4
  333. package/dist/routes/ts-rest/installer.js +0 -77
  334. package/dist/routes/ts-rest/installer.js.map +0 -1
  335. package/dist/routes/ts-rest/me.d.ts +0 -4
  336. package/dist/routes/ts-rest/me.js +0 -410
  337. package/dist/routes/ts-rest/me.js.map +0 -1
  338. package/dist/routes/ts-rest/notification.d.ts +0 -4
  339. package/dist/routes/ts-rest/notification.js +0 -241
  340. package/dist/routes/ts-rest/notification.js.map +0 -1
  341. package/dist/routes/ts-rest/page-collab.d.ts +0 -29
  342. package/dist/routes/ts-rest/page-collab.js +0 -90
  343. package/dist/routes/ts-rest/page-collab.js.map +0 -1
  344. package/dist/routes/ts-rest/page-preview.d.ts +0 -26
  345. package/dist/routes/ts-rest/page-preview.js +0 -80
  346. package/dist/routes/ts-rest/page-preview.js.map +0 -1
  347. package/dist/routes/ts-rest/page.d.ts +0 -4
  348. package/dist/routes/ts-rest/page.js +0 -676
  349. package/dist/routes/ts-rest/page.js.map +0 -1
  350. package/dist/routes/ts-rest/presence.d.ts +0 -30
  351. package/dist/routes/ts-rest/presence.js +0 -155
  352. package/dist/routes/ts-rest/presence.js.map +0 -1
  353. package/dist/routes/ts-rest/revision.d.ts +0 -4
  354. package/dist/routes/ts-rest/revision.js +0 -240
  355. package/dist/routes/ts-rest/revision.js.map +0 -1
  356. package/dist/routes/ts-rest/search.d.ts +0 -4
  357. package/dist/routes/ts-rest/search.js +0 -121
  358. package/dist/routes/ts-rest/search.js.map +0 -1
  359. package/dist/routes/ts-rest/tokenAuth.d.ts +0 -4
  360. package/dist/routes/ts-rest/tokenAuth.js +0 -94
  361. package/dist/routes/ts-rest/tokenAuth.js.map +0 -1
  362. package/dist/routes/ts-rest/user.d.ts +0 -4
  363. package/dist/routes/ts-rest/user.js +0 -307
  364. package/dist/routes/ts-rest/user.js.map +0 -1
  365. package/dist/types/express.d.ts +0 -34
  366. package/dist/types/express.js +0 -50
  367. package/dist/types/express.js.map +0 -1
  368. package/dist/util/accessTokenParser.d.ts +0 -1
  369. package/dist/util/accessTokenParser.js +0 -34
  370. package/dist/util/accessTokenParser.js.map +0 -1
  371. package/dist/util/apiPaginate.d.ts +0 -11
  372. package/dist/util/apiPaginate.js +0 -33
  373. package/dist/util/apiPaginate.js.map +0 -1
  374. package/dist/util/apiResponse.d.ts +0 -9
  375. package/dist/util/apiResponse.js +0 -23
  376. package/dist/util/apiResponse.js.map +0 -1
  377. package/dist/util/auth.d.ts +0 -11
  378. package/dist/util/auth.js +0 -48
  379. package/dist/util/auth.js.map +0 -1
  380. package/dist/util/aws-config-migration.d.ts +0 -11
  381. package/dist/util/aws-config-migration.js +0 -68
  382. package/dist/util/aws-config-migration.js.map +0 -1
  383. package/dist/util/formUtil.d.ts +0 -2
  384. package/dist/util/formUtil.js +0 -15
  385. package/dist/util/formUtil.js.map +0 -1
  386. package/dist/util/githubAuth.d.ts +0 -2
  387. package/dist/util/githubAuth.js +0 -82
  388. package/dist/util/githubAuth.js.map +0 -1
  389. package/dist/util/googleAuth.d.ts +0 -2
  390. package/dist/util/googleAuth.js +0 -85
  391. package/dist/util/googleAuth.js.map +0 -1
  392. package/dist/util/mailer.d.ts +0 -7
  393. package/dist/util/mailer.js +0 -98
  394. package/dist/util/mailer.js.map +0 -1
  395. package/dist/util/page-status-migration.d.ts +0 -23
  396. package/dist/util/page-status-migration.js +0 -48
  397. package/dist/util/page-status-migration.js.map +0 -1
  398. package/dist/util/ssr.d.ts +0 -3
  399. package/dist/util/ssr.js +0 -9
  400. package/dist/util/ssr.js.map +0 -1
  401. package/dist/util/view.d.ts +0 -10
  402. package/dist/util/view.js +0 -99
  403. package/dist/util/view.js.map +0 -1
@@ -1,676 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const express_1 = require("@ts-rest/express");
7
- const api_contract_1 = require("@crowi/api-contract");
8
- const express_2 = require("express");
9
- const page_1 = require("../../models/page");
10
- const ts_rest_helpers_1 = require("../../util/ts-rest-helpers");
11
- const page_response_1 = require("../../util/page-response");
12
- const debug_1 = __importDefault(require("debug"));
13
- const debug = (0, debug_1.default)('crowi:routes:ts-rest:page');
14
- const VALID_GRANTS = Object.values(api_contract_1.PageGrantEnum);
15
- const invalidGrantResponse = () => ({
16
- status: 400,
17
- body: {
18
- error: {
19
- code: 'INVALID_GRANT',
20
- message: 'grant must be one of 1 (public), 2 (restricted), 3 (specified), 4 (owner)',
21
- },
22
- },
23
- });
24
- exports.default = (crowi, _app) => {
25
- const s = (0, express_1.initServer)();
26
- const router = (0, express_2.Router)();
27
- const Page = crowi.model('Page');
28
- const User = crowi.model('User');
29
- const Watcher = crowi.model('Watcher');
30
- // seenUsersCount stays at the raw ID-array length (matching legacy
31
- // populatePageData) so inactive users dropped by findUsersByIds' status
32
- // filter do not deflate the count. `limit` only caps the returned
33
- // `seenUsers` list; the count always reflects the full set.
34
- const buildSeenUsersResponse = async (seenUserIds, limit) => {
35
- const ids = seenUserIds.filter((id) => id != null);
36
- const seenUsersCount = ids.length;
37
- if (ids.length === 0) {
38
- return { seenUsers: [], seenUsersCount };
39
- }
40
- const idsToFetch = limit !== undefined ? ids.slice(0, limit) : ids;
41
- const populated = (await User.findUsersByIds(idsToFetch));
42
- return {
43
- seenUsers: populated.map(ts_rest_helpers_1.toUserPublic),
44
- seenUsersCount,
45
- };
46
- };
47
- const pageRouter = s.router(api_contract_1.apiContract.page, {
48
- /**
49
- * GET /api/v2/pages
50
- * Get page data by path or page_id
51
- * - Supports optional revision_id for historical revisions
52
- * - Requires authentication (loginRequired middleware applied at router level)
53
- * - Checks page permissions (grant)
54
- */
55
- getPage: async ({ query, req }) => {
56
- const user = req.user;
57
- const { path, page_id, revision_id } = query;
58
- debug('getPage called with:', { path, page_id, revision_id, userId: user._id });
59
- // Validate that at least one of path or page_id is provided
60
- if (!path && !page_id) {
61
- return {
62
- status: 404,
63
- body: {
64
- error: {
65
- code: 'PAGE_NOT_FOUND',
66
- message: 'Page not found',
67
- },
68
- },
69
- };
70
- }
71
- try {
72
- let page = null;
73
- // Priority: page_id parameter takes precedence over path
74
- // This matches the original controller logic (lines 651-657)
75
- if (page_id) {
76
- debug('Finding page by page_id:', page_id);
77
- page = await Page.findPageByIdAndGrantedUser(page_id, user);
78
- }
79
- else if (path) {
80
- debug('Finding page by path:', path);
81
- page = await Page.findPage(path, user, revision_id || null);
82
- }
83
- // Ensure page was found
84
- if (!page) {
85
- return {
86
- status: 404,
87
- body: {
88
- error: {
89
- code: 'PAGE_NOT_FOUND',
90
- message: 'Page not found',
91
- },
92
- },
93
- };
94
- }
95
- // Check if page has redirect
96
- if (page.redirectTo) {
97
- debug('Page has redirect to:', page.redirectTo);
98
- // For now, return the page with redirectTo field
99
- // Client can handle the redirect
100
- // TODO: Consider if we should follow the redirect automatically
101
- }
102
- const pageResponse = (0, page_response_1.pageToResponse)(page, { withMeta: true, withRenderedAst: true });
103
- // On-the-fly fallback for legacy revisions: one pipeline run
104
- // produces both meta + renderedAst, so use the combined helper
105
- // to avoid running parse+transform+shiki twice. Stored values
106
- // win on merge (anchor ids match page-content's stamper).
107
- if (pageResponse.revision && (0, page_response_1.isPopulatedRevision)(page.revision)) {
108
- const { meta, renderedAst } = await (0, page_response_1.computeRevisionRenderArtifactsAsync)(crowi, page.revision.meta, page.revision.renderedAst, page.revision.body, page.revision.rendererVersion, page._id?.toString());
109
- pageResponse.revision.meta = meta;
110
- pageResponse.revision.renderedAst = renderedAst;
111
- }
112
- // Fire-and-forget recently-viewed touch. Hiccups on the Redis
113
- // side mustn't break the page read.
114
- crowi.lru.add(user._id.toString(), page._id.toString())?.catch?.((err) => {
115
- debug('lru.add failed (non-fatal):', err);
116
- });
117
- return {
118
- status: 200,
119
- body: {
120
- page: pageResponse,
121
- },
122
- };
123
- }
124
- catch (err) {
125
- const error = err;
126
- debug('Error fetching page:', error.message);
127
- // Handle specific error types
128
- if (error.message === 'Page not found' || error.name === 'Crowi:Page:NotFound') {
129
- return {
130
- status: 404,
131
- body: {
132
- error: {
133
- code: 'PAGE_NOT_FOUND',
134
- message: 'Page not found',
135
- },
136
- },
137
- };
138
- }
139
- if (error.message === 'Page is not granted for the user') {
140
- return {
141
- status: 403,
142
- body: {
143
- error: {
144
- code: 'PAGE_NOT_GRANTED',
145
- message: 'Page is not granted for the user',
146
- },
147
- },
148
- };
149
- }
150
- // Generic error fallback
151
- debug('Unexpected error:', error);
152
- return {
153
- status: 404,
154
- body: {
155
- error: {
156
- code: 'PAGE_NOT_FOUND',
157
- message: 'Page not found',
158
- },
159
- },
160
- };
161
- }
162
- },
163
- /**
164
- * GET /api/v2/pages/list
165
- * List pages by path or user
166
- * - Supports pagination with limit and offset
167
- * - Returns pages with populated creator and lastUpdateUser
168
- */
169
- listPages: async ({ query, req }) => {
170
- const user = req.user;
171
- const { path, user: userParam, limit = 50, offset = 0, include_deleted = false } = query;
172
- // Force-enable include_deleted for /trash and /trash/<sub> requests so the
173
- // legacy deletedPageListShow semantics are preserved even when the client
174
- // omits the query flag (matches old controllers/page.ts behavior).
175
- const isTrashPath = !!path && (path === '/trash' || path.startsWith('/trash/'));
176
- const includeDeletedPage = include_deleted || isTrashPath;
177
- debug('listPages called with:', { path, user: userParam, limit, offset, includeDeletedPage, userId: user._id });
178
- try {
179
- let pages = [];
180
- let portalPage = null;
181
- if (userParam) {
182
- // List pages by creator
183
- debug('Finding pages by creator:', userParam);
184
- const targetUser = await crowi.model('User').findById(userParam);
185
- if (!targetUser) {
186
- return {
187
- status: 200,
188
- body: {
189
- pages: [],
190
- pager: {
191
- prev: null,
192
- next: null,
193
- offset: 0,
194
- },
195
- portalPage: null,
196
- },
197
- };
198
- }
199
- // findListByCreator doesn't populate creator/lastUpdateUser, so we need to do it manually
200
- const rawPages = await Page.findListByCreator(targetUser, { limit, offset }, user);
201
- pages = (await Page.populate(rawPages, [{ path: 'creator' }, { path: 'lastUpdateUser' }]));
202
- }
203
- else if (path && path !== '/') {
204
- // List pages by path. /trash subtrees skip findPortalPage to mirror the
205
- // legacy deletedPageListShow which always rendered with page=null.
206
- debug('Finding pages by path:', path);
207
- debug('Query params:', { limit, offset, path, userParam, includeDeletedPage });
208
- const portalPagePromise = isTrashPath ? Promise.resolve(null) : Page.findPortalPage(path, user);
209
- const listPromise = Page.findListByStartWith(path, user, { limit, offset, includeDeletedPage });
210
- const [rawPortalPage, rawPages] = await Promise.all([portalPagePromise, listPromise]);
211
- // findListByStartWith doesn't populate creator/lastUpdateUser, so we need to do it manually
212
- [portalPage, pages] = (await Promise.all([
213
- rawPortalPage ? Page.populate(rawPortalPage, [{ path: 'creator' }, { path: 'lastUpdateUser' }]) : null,
214
- Page.populate(rawPages, [{ path: 'creator' }, { path: 'lastUpdateUser' }]),
215
- ]));
216
- debug('Found pages:', pages.length);
217
- debug('Found portal page:', !!portalPage);
218
- }
219
- else {
220
- // List all pages the user can access (including path='/')
221
- debug('Finding all accessible pages', { path });
222
- const conditions = {
223
- redirectTo: null,
224
- $or: (0, page_1.visiblePageStatusOr)(user._id),
225
- grant: { $in: [1, 2] }, // PUBLIC or RESTRICTED
226
- };
227
- // If path='/', also get portal page
228
- if (path === '/') {
229
- [portalPage, pages] = await Promise.all([
230
- Page.findPortalPage(path, user),
231
- Page.find(conditions)
232
- .sort({ updatedAt: -1 })
233
- .skip(offset)
234
- .limit(limit)
235
- .populate({ path: 'revision', populate: { path: 'author' } })
236
- .populate('creator')
237
- .populate('lastUpdateUser')
238
- .exec(),
239
- ]);
240
- }
241
- else {
242
- pages = await Page.find(conditions)
243
- .sort({ updatedAt: -1 })
244
- .skip(offset)
245
- .limit(limit)
246
- .populate({ path: 'revision', populate: { path: 'author' } })
247
- .populate('creator')
248
- .populate('lastUpdateUser')
249
- .exec();
250
- }
251
- }
252
- // Convert pages to response format
253
- const pageResponses = pages.map((page) => (0, page_response_1.pageToResponse)(page));
254
- const portalPageResponse = portalPage ? (0, page_response_1.pageToResponse)(portalPage) : null;
255
- // Calculate pagination
256
- const prev = offset > 0 ? Math.max(0, offset - limit) : null;
257
- const next = pages.length === limit ? offset + limit : null;
258
- return {
259
- status: 200,
260
- body: {
261
- pages: pageResponses,
262
- pager: {
263
- prev,
264
- next,
265
- offset,
266
- },
267
- portalPage: portalPageResponse,
268
- },
269
- };
270
- }
271
- catch (err) {
272
- const error = err;
273
- debug('Error listing pages:', error.message);
274
- // Return empty list on error
275
- return {
276
- status: 200,
277
- body: {
278
- pages: [],
279
- pager: {
280
- prev: null,
281
- next: null,
282
- offset: 0,
283
- },
284
- portalPage: null,
285
- },
286
- };
287
- }
288
- },
289
- createPage: async ({ body: requestBody, req }) => {
290
- const user = req.user;
291
- const { path, body, grant } = requestBody;
292
- debug('createPage called with:', { path, grant, userId: user._id });
293
- if (grant !== undefined && !VALID_GRANTS.includes(grant)) {
294
- return invalidGrantResponse();
295
- }
296
- try {
297
- const existing = await Page.findPage(path, user, null, /* ignoreNotFound */ true);
298
- if (existing !== null) {
299
- return {
300
- status: 400,
301
- body: { error: { code: 'PAGE_EXISTS', message: 'Page exists' } },
302
- };
303
- }
304
- const createOptions = grant !== undefined ? { grant } : {};
305
- const created = (await Page.createPage(path, body, user, createOptions));
306
- if (!created) {
307
- throw new Error('Failed to create page.');
308
- }
309
- const populated = await Page.populatePageData(created, null);
310
- return { status: 200, body: { page: (0, page_response_1.pageToResponse)(populated) } };
311
- }
312
- catch (err) {
313
- const error = err;
314
- debug('Error creating page:', error.message);
315
- if (error.message === 'Cannot create non existent user page.') {
316
- return {
317
- status: 400,
318
- body: { error: { code: 'NON_EXISTENT_USER_PAGE', message: error.message } },
319
- };
320
- }
321
- // Both 'existed path' and 'not granted' map to PAGE_EXISTS: the latter
322
- // can occur as a race when a stricter-grant page is created between
323
- // findPage and createPage, and we should not leak that distinction.
324
- if (error.message === 'Cannot create new page to existed path' || error.message === 'Page is not granted for the user') {
325
- return {
326
- status: 400,
327
- body: { error: { code: 'PAGE_EXISTS', message: 'Page exists' } },
328
- };
329
- }
330
- return {
331
- status: 400,
332
- body: { error: { code: 'PAGE_CREATE_FAILED', message: error.message || 'Failed to create page' } },
333
- };
334
- }
335
- },
336
- updatePage: async ({ body: requestBody, req }) => {
337
- const user = req.user;
338
- const { page_id, body, revision_id, grant } = requestBody;
339
- debug('updatePage called with:', { page_id, revision_id, grant, userId: user._id });
340
- if (grant !== undefined && !VALID_GRANTS.includes(grant)) {
341
- return invalidGrantResponse();
342
- }
343
- try {
344
- const pageData = (await Page.findPageByIdAndGrantedUser(page_id, user));
345
- if (!pageData) {
346
- return ts_rest_helpers_1.pageNotFoundResponse;
347
- }
348
- if (revision_id && !pageData.isUpdatable(revision_id)) {
349
- return {
350
- status: 409,
351
- body: { error: { code: 'PAGE_REVISION_ERROR', message: 'Revision error.' } },
352
- };
353
- }
354
- const grantOption = { grant: grant ?? pageData.grant };
355
- const updated = (await Page.updatePage(pageData, body, user, grantOption));
356
- const populated = await Page.populatePageData(updated, null);
357
- return { status: 200, body: { page: (0, page_response_1.pageToResponse)(populated) } };
358
- }
359
- catch (err) {
360
- const error = err;
361
- debug('Error updating page:', error.message);
362
- if (error.message === 'Page not found' || error.message === 'Page is not granted for the user') {
363
- return ts_rest_helpers_1.pageNotFoundResponse;
364
- }
365
- return {
366
- status: 400,
367
- body: { error: { code: 'PAGE_UPDATE_FAILED', message: error.message || 'Failed to update page' } },
368
- };
369
- }
370
- },
371
- /**
372
- * PUT /api/v2/pages/grant
373
- *
374
- * Grant-only update. Mutates `page.grant` / `grantedUsers` via
375
- * Page.updateGrant — no revision is pushed, so changing a page's
376
- * visibility never lands a no-op entry in the page history.
377
- * Authorization mirrors updatePage (findPageByIdAndGrantedUser).
378
- */
379
- setPageGrant: async ({ body: requestBody, req }) => {
380
- const user = req.user;
381
- const { page_id, grant } = requestBody;
382
- debug('setPageGrant called with:', { page_id, grant, userId: user._id });
383
- if (!VALID_GRANTS.includes(grant)) {
384
- return invalidGrantResponse();
385
- }
386
- try {
387
- const pageData = (await Page.findPageByIdAndGrantedUser(page_id, user));
388
- if (!pageData) {
389
- return ts_rest_helpers_1.pageNotFoundResponse;
390
- }
391
- const updated = (await Page.updateGrant(pageData, grant, user));
392
- const populated = await Page.populatePageData(updated, null);
393
- return { status: 200, body: { page: (0, page_response_1.pageToResponse)(populated) } };
394
- }
395
- catch (err) {
396
- const error = err;
397
- debug('Error updating page grant:', error.message);
398
- if (error.message === 'Page not found' || error.message === 'Page is not granted for the user') {
399
- return ts_rest_helpers_1.pageNotFoundResponse;
400
- }
401
- return {
402
- status: 400,
403
- body: { error: { code: 'PAGE_GRANT_UPDATE_FAILED', message: error.message || 'Failed to update page grant' } },
404
- };
405
- }
406
- },
407
- // Idempotent: Page.seen uses addToSet so re-posting from the same user
408
- // does not inflate seenUsers / seenUsersCount.
409
- seenPage: async ({ body: requestBody, req }) => {
410
- const user = req.user;
411
- const { page_id } = requestBody;
412
- debug('seenPage called with:', { page_id, userId: user._id });
413
- const loaded = await (0, ts_rest_helpers_1.loadGrantedPage)(Page, page_id, user);
414
- if ('error' in loaded)
415
- return loaded.error;
416
- const updated = (await loaded.page.seen(user));
417
- return { status: 200, body: await buildSeenUsersResponse(updated.seenUsers) };
418
- },
419
- getSeenUsers: async ({ query, req }) => {
420
- const user = req.user;
421
- const { page_id, limit } = query;
422
- debug('getSeenUsers called with:', { page_id, limit, userId: user._id });
423
- const loaded = await (0, ts_rest_helpers_1.loadGrantedPage)(Page, page_id, user);
424
- if ('error' in loaded)
425
- return loaded.error;
426
- return { status: 200, body: await buildSeenUsersResponse(loaded.page.seenUsers, limit) };
427
- },
428
- /**
429
- * POST /api/v2/pages/like
430
- * Add the current user to the page's `liker` list.
431
- * - Idempotent: liking an already-liked page returns the page unchanged.
432
- * - Returns 404 (not 200 with no-op) when the page does not exist or
433
- * the caller has no grant, matching the rest of the page contract
434
- * (cf. updatePage / renamePage). The legacy /_api/likes.add returned
435
- * ApiResponse.success() on errors, but that path was effectively
436
- * unreachable in the legacy UI; see openQuestions in the task plan.
437
- */
438
- likePage: async ({ body: requestBody, req }) => {
439
- const user = req.user;
440
- const { page_id } = requestBody;
441
- debug('likePage called with:', { page_id, userId: user._id });
442
- const loaded = await (0, ts_rest_helpers_1.loadGrantedPage)(Page, page_id, user);
443
- if ('error' in loaded)
444
- return loaded.error;
445
- // pageData.like is a no-op when the user already liked the page. Always
446
- // re-populate so the response shape stays stable either way.
447
- await loaded.page.like(user);
448
- const populated = await Page.populatePageData(loaded.page, null);
449
- return { status: 200, body: { page: (0, page_response_1.pageToResponse)(populated) } };
450
- },
451
- /**
452
- * POST /api/v2/pages/unlike
453
- * Remove the current user from the page's `liker` list.
454
- * - Idempotent: unliking a not-liked page returns the page unchanged.
455
- * - Returns 404 for not-found / not-granted, mirroring likePage.
456
- */
457
- unlikePage: async ({ body: requestBody, req }) => {
458
- const user = req.user;
459
- const { page_id } = requestBody;
460
- debug('unlikePage called with:', { page_id, userId: user._id });
461
- const loaded = await (0, ts_rest_helpers_1.loadGrantedPage)(Page, page_id, user);
462
- if ('error' in loaded)
463
- return loaded.error;
464
- // unlike is a no-op when the user had not liked the page. Always
465
- // re-populate so the response shape stays stable either way.
466
- await loaded.page.unlike(user);
467
- const populated = await Page.populatePageData(loaded.page, null);
468
- return { status: 200, body: { page: (0, page_response_1.pageToResponse)(populated) } };
469
- },
470
- /**
471
- * Resolution order matches legacy controllers/page.ts api.watchStatus:
472
- * 1. If a Watcher record exists for (user, page), use watcher.isWatching().
473
- * 2. Otherwise derive a default from page.getNotificationTargetUsers()
474
- * (creator + comment authors + revision authors). The user is
475
- * "watching by default" iff their id appears in that list.
476
- */
477
- getWatchStatus: async ({ query, req }) => {
478
- const user = req.user;
479
- const { page_id } = query;
480
- debug('getWatchStatus called with:', { page_id, userId: user._id });
481
- const loaded = await (0, ts_rest_helpers_1.loadGrantedPage)(Page, page_id, user);
482
- if ('error' in loaded)
483
- return loaded.error;
484
- const watcher = await Watcher.findByUserIdAndTargetId(user._id, loaded.page._id);
485
- if (watcher) {
486
- return { status: 200, body: { watching: watcher.isWatching() } };
487
- }
488
- // Default: include user when they appear in the page's notification
489
- // target users (creator + comment authors + revision authors).
490
- const targetUsers = await loaded.page.getNotificationTargetUsers();
491
- const userIdStr = user._id.toString();
492
- const watching = targetUsers.some((id) => id.toString() === userIdStr);
493
- return { status: 200, body: { watching } };
494
- },
495
- /**
496
- * - watching=true -> status=WATCH
497
- * - watching=false -> status=IGNORE
498
- *
499
- * This 2-state API cannot remove the Watcher (i.e. revert to the
500
- * default-derived behaviour). If a 3-state UI is needed later, the
501
- * contract will be extended.
502
- */
503
- setWatchStatus: async ({ body: requestBody, req }) => {
504
- const user = req.user;
505
- const { page_id, watching } = requestBody;
506
- debug('setWatchStatus called with:', { page_id, watching, userId: user._id });
507
- const loaded = await (0, ts_rest_helpers_1.loadGrantedPage)(Page, page_id, user);
508
- if ('error' in loaded)
509
- return loaded.error;
510
- const status = watching ? Watcher.STATUS_WATCH : Watcher.STATUS_IGNORE;
511
- await Watcher.watchByPageId(user._id, loaded.page._id, status);
512
- return { status: 200, body: { watching } };
513
- },
514
- deletePage: async ({ body: requestBody, req }) => {
515
- const user = req.user;
516
- const { page_id, revision_id, completely } = requestBody;
517
- debug('deletePage called with:', { page_id, revision_id, completely, userId: user._id });
518
- try {
519
- const pageData = (await Page.findPageByIdAndGrantedUser(page_id, user));
520
- if (!pageData) {
521
- return ts_rest_helpers_1.pageNotFoundResponse;
522
- }
523
- // Hard delete bypasses revision check (matches old controllers/page.ts api.remove).
524
- if (completely === true) {
525
- await Page.completelyDeletePage(pageData, user);
526
- // After completelyDeletePage the document is gone from Mongo; we still
527
- // return the in-memory pageData so the client knows what was deleted.
528
- return { status: 200, body: { page: (0, page_response_1.pageToResponse)(pageData) } };
529
- }
530
- if (revision_id && !pageData.isUpdatable(revision_id)) {
531
- return {
532
- status: 409,
533
- body: { error: { code: 'PAGE_REVISION_ERROR', message: 'Revision error.' } },
534
- };
535
- }
536
- // Page.deletePage mutates pageData (status -> deleted, path -> /trash/<path>)
537
- // and internally calls Page.rename which returns the *redirect* page (a quirk
538
- // of the old model). We re-populate the mutated pageData so the response
539
- // reflects the soft-deleted page itself, which is what callers actually want.
540
- await Page.deletePage(pageData, user);
541
- const populated = await Page.populatePageData(pageData, null);
542
- return { status: 200, body: { page: (0, page_response_1.pageToResponse)(populated) } };
543
- }
544
- catch (err) {
545
- const error = err;
546
- debug('Error deleting page:', error.message);
547
- if (error.message === 'Page not found' || error.message === 'Page is not granted for the user') {
548
- return ts_rest_helpers_1.pageNotFoundResponse;
549
- }
550
- return {
551
- status: 400,
552
- body: { error: { code: 'PAGE_DELETE_FAILED', message: error.message || 'Failed to delete page' } },
553
- };
554
- }
555
- },
556
- revertDeletedPage: async ({ body: requestBody, req }) => {
557
- const user = req.user;
558
- const { page_id } = requestBody;
559
- debug('revertDeletedPage called with:', { page_id, userId: user._id });
560
- try {
561
- const pageData = (await Page.findPageByIdAndGrantedUser(page_id, user));
562
- if (!pageData) {
563
- return ts_rest_helpers_1.pageNotFoundResponse;
564
- }
565
- // Page.revertDeletedPage mutates pageData (path -> non-trash, status -> published)
566
- // and removes the redirect stub at the original /trash path. The function returns
567
- // pageData itself, but we re-populate to ensure creator/lastUpdateUser/revision are
568
- // resolved for the response.
569
- await Page.revertDeletedPage(pageData, user);
570
- const populated = await Page.populatePageData(pageData, null);
571
- return { status: 200, body: { page: (0, page_response_1.pageToResponse)(populated) } };
572
- }
573
- catch (err) {
574
- const error = err;
575
- debug('Error reverting deleted page:', error.message);
576
- if (error.message === 'Page not found' || error.message === 'Page is not granted for the user') {
577
- return ts_rest_helpers_1.pageNotFoundResponse;
578
- }
579
- return {
580
- status: 400,
581
- body: { error: { code: 'PAGE_REVERT_FAILED', message: error.message || 'Failed to revert deleted page' } },
582
- };
583
- }
584
- },
585
- renamePage: async ({ body: requestBody, req }) => {
586
- const user = req.user;
587
- const { page_id, new_path, revision_id, create_redirect } = requestBody;
588
- debug('renamePage called with:', { page_id, new_path, revision_id, create_redirect, userId: user._id });
589
- // Normalize the destination path and validate the name first so we can
590
- // reject obviously bad inputs without touching the DB.
591
- const newPagePath = Page.normalizePath(new_path);
592
- const newPageIsPortal = newPagePath.endsWith('/');
593
- if (!Page.isCreatableName(newPagePath)) {
594
- return {
595
- status: 400,
596
- body: {
597
- error: {
598
- code: 'PAGE_INVALID_NAME',
599
- message: `Cannot rename to this page name (${newPagePath})`,
600
- },
601
- },
602
- };
603
- }
604
- try {
605
- // Authorization: same pattern as updatePage. Hide existence from
606
- // callers without grant by returning 404.
607
- const pageData = (await Page.findPageByIdAndGrantedUser(page_id, user));
608
- if (!pageData) {
609
- return ts_rest_helpers_1.pageNotFoundResponse;
610
- }
611
- if (revision_id && !pageData.isUpdatable(revision_id)) {
612
- return {
613
- status: 409,
614
- body: { error: { code: 'PAGE_REVISION_ERROR', message: 'Revision error.' } },
615
- };
616
- }
617
- // Detect collision at the destination path. If the existing page is a
618
- // redirect that the user is allowed to remove, unlink it first;
619
- // otherwise refuse the rename. This mirrors controllers/page.ts.
620
- const existingAtNewPath = await Page.findOne({ path: newPagePath });
621
- if (existingAtNewPath) {
622
- if (existingAtNewPath.isUnlinkable(user)) {
623
- try {
624
- await existingAtNewPath.unlink(user);
625
- }
626
- catch (err) {
627
- const error = err;
628
- return {
629
- status: 400,
630
- body: {
631
- error: {
632
- code: 'PAGE_RENAME_FAILED',
633
- message: error.message || 'Failed to unlink redirect page at destination',
634
- },
635
- },
636
- };
637
- }
638
- }
639
- else {
640
- return {
641
- status: 400,
642
- body: {
643
- error: {
644
- code: 'PAGE_EXISTS',
645
- message: `Cannot rename to this page name (${newPagePath}). Page exists.`,
646
- },
647
- },
648
- };
649
- }
650
- }
651
- // Old controller: `(!newPageIsPortal && createRedirect) || 0` — portal
652
- // paths (ending in '/') never get a redirect page even if requested.
653
- const options = {
654
- createRedirectPage: !newPageIsPortal && Boolean(create_redirect),
655
- };
656
- await Page.rename(pageData, newPagePath, user, options);
657
- const populated = await Page.populatePageData(pageData, null);
658
- return { status: 200, body: { page: (0, page_response_1.pageToResponse)(populated) } };
659
- }
660
- catch (err) {
661
- const error = err;
662
- debug('Error renaming page:', error.message);
663
- if (error.message === 'Page not found' || error.message === 'Page is not granted for the user') {
664
- return ts_rest_helpers_1.pageNotFoundResponse;
665
- }
666
- return {
667
- status: 400,
668
- body: { error: { code: 'PAGE_RENAME_FAILED', message: error.message || 'Failed to rename page' } },
669
- };
670
- }
671
- },
672
- });
673
- (0, express_1.createExpressEndpoints)(api_contract_1.apiContract.page, pageRouter, router);
674
- return router;
675
- };
676
- //# sourceMappingURL=page.js.map