@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
@@ -172,6 +172,7 @@ export declare const registerPageRoutes: <E extends OpenAPIHono<CrowiHonoBinding
172
172
  include_deleted?: unknown;
173
173
  sort?: "path" | "createdAt" | "updatedAt" | undefined;
174
174
  order?: "asc" | "desc" | undefined;
175
+ revision_id?: string | undefined;
175
176
  };
176
177
  };
177
178
  output: {
@@ -193,6 +194,7 @@ export declare const registerPageRoutes: <E extends OpenAPIHono<CrowiHonoBinding
193
194
  include_deleted?: unknown;
194
195
  sort?: "path" | "createdAt" | "updatedAt" | undefined;
195
196
  order?: "asc" | "desc" | undefined;
197
+ revision_id?: string | undefined;
196
198
  };
197
199
  };
198
200
  output: {
@@ -389,6 +391,100 @@ export declare const registerPageRoutes: <E extends OpenAPIHono<CrowiHonoBinding
389
391
  likerCount?: number | undefined;
390
392
  seenUsersCount?: number | undefined;
391
393
  } | null | undefined;
394
+ contentPage?: {
395
+ _id: string;
396
+ path: string;
397
+ commentCount: number;
398
+ createdAt: string;
399
+ revision?: string | {
400
+ _id: string;
401
+ path: string;
402
+ body: string;
403
+ format: string;
404
+ createdAt: string;
405
+ author?: {
406
+ _id: string;
407
+ username: string;
408
+ name: string;
409
+ email: string;
410
+ createdAt: string;
411
+ id?: string | undefined;
412
+ image?: string | null | undefined;
413
+ } | null | undefined;
414
+ meta?: {
415
+ toc?: {
416
+ level: number;
417
+ text: string;
418
+ anchorId: string;
419
+ }[] | undefined;
420
+ wikiLinks?: {
421
+ raw: string;
422
+ target: string;
423
+ displayText?: string | undefined;
424
+ }[] | undefined;
425
+ mentions?: {
426
+ username: string;
427
+ }[] | undefined;
428
+ codeBlockLanguages?: string[] | undefined;
429
+ } | undefined;
430
+ renderedAst?: import("hono/utils/types").JSONValue | undefined;
431
+ rendererVersion?: string | undefined;
432
+ parentRevisionId?: string | null | undefined;
433
+ type?: "snapshot" | "incremental" | undefined;
434
+ savedBy?: string | {
435
+ _id: string;
436
+ username: string;
437
+ name: string;
438
+ email: string;
439
+ createdAt: string;
440
+ id?: string | undefined;
441
+ image?: string | null | undefined;
442
+ } | null | undefined;
443
+ contributors?: (string | {
444
+ _id: string;
445
+ username: string;
446
+ name: string;
447
+ email: string;
448
+ createdAt: string;
449
+ id?: string | undefined;
450
+ image?: string | null | undefined;
451
+ })[] | undefined;
452
+ message?: string | undefined;
453
+ editVia?: "web" | "oauth" | "pat" | undefined;
454
+ } | undefined;
455
+ redirectTo?: string | null | undefined;
456
+ status?: "published" | "wip" | "deleted" | "deprecated" | "draft" | null | undefined;
457
+ grant?: number | undefined;
458
+ grantedUsers?: string[] | undefined;
459
+ creator?: string | {
460
+ _id: string;
461
+ username: string;
462
+ name: string;
463
+ email: string;
464
+ createdAt: string;
465
+ id?: string | undefined;
466
+ image?: string | null | undefined;
467
+ } | null | undefined;
468
+ lastUpdateUser?: string | {
469
+ _id: string;
470
+ username: string;
471
+ name: string;
472
+ email: string;
473
+ createdAt: string;
474
+ id?: string | undefined;
475
+ image?: string | null | undefined;
476
+ } | null | undefined;
477
+ liker?: string[] | undefined;
478
+ extended?: {
479
+ [x: string]: any;
480
+ } | undefined;
481
+ updatedAt?: string | undefined;
482
+ currentRevision?: string | null | undefined;
483
+ yjsCheckpointAt?: string | null | undefined;
484
+ latestRevision?: string | undefined;
485
+ likerCount?: number | undefined;
486
+ seenUsersCount?: number | undefined;
487
+ } | null | undefined;
392
488
  };
393
489
  outputFormat: "json";
394
490
  status: 200;
@@ -1800,6 +1896,161 @@ export declare const registerPageRoutes: <E extends OpenAPIHono<CrowiHonoBinding
1800
1896
  status: 200;
1801
1897
  };
1802
1898
  };
1899
+ } & {
1900
+ "/pages/revert-to-revision": {
1901
+ $post: {
1902
+ input: {
1903
+ json: {
1904
+ page_id: string;
1905
+ revision_id: string;
1906
+ };
1907
+ };
1908
+ output: {
1909
+ error: {
1910
+ code: "PAGE_NOT_FOUND";
1911
+ message: "Page not found";
1912
+ };
1913
+ };
1914
+ outputFormat: "json";
1915
+ status: 404;
1916
+ } | {
1917
+ input: {
1918
+ json: {
1919
+ page_id: string;
1920
+ revision_id: string;
1921
+ };
1922
+ };
1923
+ output: {
1924
+ error: {
1925
+ code: string;
1926
+ message: string;
1927
+ };
1928
+ };
1929
+ outputFormat: "json";
1930
+ status: 400;
1931
+ } | {
1932
+ input: {
1933
+ json: {
1934
+ page_id: string;
1935
+ revision_id: string;
1936
+ };
1937
+ };
1938
+ output: {
1939
+ error: {
1940
+ code: "AUTHENTICATION_REQUIRED";
1941
+ message: "Authentication is required";
1942
+ redirectTo?: string | undefined;
1943
+ };
1944
+ };
1945
+ outputFormat: "json";
1946
+ status: 401;
1947
+ } | {
1948
+ input: {
1949
+ json: {
1950
+ page_id: string;
1951
+ revision_id: string;
1952
+ };
1953
+ };
1954
+ output: {
1955
+ page: {
1956
+ _id: string;
1957
+ path: string;
1958
+ commentCount: number;
1959
+ createdAt: string;
1960
+ revision?: string | {
1961
+ _id: string;
1962
+ path: string;
1963
+ body: string;
1964
+ format: string;
1965
+ createdAt: string;
1966
+ author?: {
1967
+ _id: string;
1968
+ username: string;
1969
+ name: string;
1970
+ email: string;
1971
+ createdAt: string;
1972
+ id?: string | undefined;
1973
+ image?: string | null | undefined;
1974
+ } | null | undefined;
1975
+ meta?: {
1976
+ toc?: {
1977
+ level: number;
1978
+ text: string;
1979
+ anchorId: string;
1980
+ }[] | undefined;
1981
+ wikiLinks?: {
1982
+ raw: string;
1983
+ target: string;
1984
+ displayText?: string | undefined;
1985
+ }[] | undefined;
1986
+ mentions?: {
1987
+ username: string;
1988
+ }[] | undefined;
1989
+ codeBlockLanguages?: string[] | undefined;
1990
+ } | undefined;
1991
+ renderedAst?: import("hono/utils/types").JSONValue | undefined;
1992
+ rendererVersion?: string | undefined;
1993
+ parentRevisionId?: string | null | undefined;
1994
+ type?: "snapshot" | "incremental" | undefined;
1995
+ savedBy?: string | {
1996
+ _id: string;
1997
+ username: string;
1998
+ name: string;
1999
+ email: string;
2000
+ createdAt: string;
2001
+ id?: string | undefined;
2002
+ image?: string | null | undefined;
2003
+ } | null | undefined;
2004
+ contributors?: (string | {
2005
+ _id: string;
2006
+ username: string;
2007
+ name: string;
2008
+ email: string;
2009
+ createdAt: string;
2010
+ id?: string | undefined;
2011
+ image?: string | null | undefined;
2012
+ })[] | undefined;
2013
+ message?: string | undefined;
2014
+ editVia?: "web" | "oauth" | "pat" | undefined;
2015
+ } | undefined;
2016
+ redirectTo?: string | null | undefined;
2017
+ status?: "published" | "wip" | "deleted" | "deprecated" | "draft" | null | undefined;
2018
+ grant?: number | undefined;
2019
+ grantedUsers?: string[] | undefined;
2020
+ creator?: string | {
2021
+ _id: string;
2022
+ username: string;
2023
+ name: string;
2024
+ email: string;
2025
+ createdAt: string;
2026
+ id?: string | undefined;
2027
+ image?: string | null | undefined;
2028
+ } | null | undefined;
2029
+ lastUpdateUser?: string | {
2030
+ _id: string;
2031
+ username: string;
2032
+ name: string;
2033
+ email: string;
2034
+ createdAt: string;
2035
+ id?: string | undefined;
2036
+ image?: string | null | undefined;
2037
+ } | null | undefined;
2038
+ liker?: string[] | undefined;
2039
+ extended?: {
2040
+ [x: string]: any;
2041
+ } | undefined;
2042
+ updatedAt?: string | undefined;
2043
+ currentRevision?: string | null | undefined;
2044
+ yjsCheckpointAt?: string | null | undefined;
2045
+ latestRevision?: string | undefined;
2046
+ likerCount?: number | undefined;
2047
+ seenUsersCount?: number | undefined;
2048
+ };
2049
+ };
2050
+ outputFormat: "json";
2051
+ status: 200;
2052
+ };
2053
+ };
1803
2054
  } & {
1804
2055
  "/pages/rename": {
1805
2056
  $post: {
@@ -28,6 +28,7 @@ exports.registerPageRoutes = void 0;
28
28
  */
29
29
  const api_contract_1 = require("@crowi/api-contract");
30
30
  const debug_1 = __importDefault(require("debug"));
31
+ const mongoose_1 = require("mongoose");
31
32
  const page_1 = require("../../models/page");
32
33
  const page_response_1 = require("../../util/page-response");
33
34
  const ts_rest_helpers_1 = require("../../util/ts-rest-helpers");
@@ -53,6 +54,9 @@ const pageBadRequestBody = (code, message) => ({
53
54
  const pageRevisionConflictBody = () => ({
54
55
  error: { code: 'PAGE_REVISION_ERROR', message: 'Revision error.' },
55
56
  });
57
+ // §6 — shared 400 body for the `/x` ↔ `/x/` twin-creation guard, used by both
58
+ // the create and rename paths so the message stays identical.
59
+ const pageTwinExistsBody = (twinPath) => pageBadRequestBody('PAGE_TWIN_EXISTS', `A page with the opposite trailing slash already exists at ${twinPath}. Portalize it instead.`);
56
60
  // Structured 400 body shared by both subtree-rename paths (page_id-based and
57
61
  // path-based). `partial: true` marks a mid-execution best-effort failure.
58
62
  const renameTreeFailedBody = (message, conflicts, partial) => ({
@@ -64,6 +68,7 @@ const toConflicts = (errorsByPath) => Object.entries(errorsByPath)
64
68
  .map(([path, reasons]) => ({ path, reasons }));
65
69
  const registerPageRoutes = (app, crowi) => {
66
70
  const Page = crowi.model('Page');
71
+ const Revision = crowi.model('Revision');
67
72
  const User = crowi.model('User');
68
73
  const Watcher = crowi.model('Watcher');
69
74
  // RFC-0010 — per-route scope guards (web sessions hold all scopes, so
@@ -88,6 +93,7 @@ const registerPageRoutes = (app, crowi) => {
88
93
  (0, require_scope_1.applyScope)(app, api_contract_1.setWatchStatusRoute, 'pages:write');
89
94
  (0, require_scope_1.applyScope)(app, api_contract_1.deletePageRoute, 'pages:write');
90
95
  (0, require_scope_1.applyScope)(app, api_contract_1.revertDeletedPageRoute, 'pages:write');
96
+ (0, require_scope_1.applyScope)(app, api_contract_1.revertToRevisionRoute, 'pages:write');
91
97
  (0, require_scope_1.applyScope)(app, api_contract_1.renamePageRoute, 'pages:write');
92
98
  (0, require_scope_1.applyScope)(app, api_contract_1.renameSubtreeRoute, 'pages:write');
93
99
  /**
@@ -165,7 +171,7 @@ const registerPageRoutes = (app, crowi) => {
165
171
  // --------------------------------------------------------------
166
172
  .openapi(api_contract_1.listPagesRoute, async (c) => {
167
173
  const user = c.get('user');
168
- const { path, user: userParam, limit, offset, include_deleted, sort, order } = c.req.valid('query');
174
+ const { path, user: userParam, limit, offset, include_deleted, sort, order, revision_id } = c.req.valid('query');
169
175
  // Mongoose sort direction: 1 ascending, -1 descending.
170
176
  const sortDir = order === 'asc' ? 1 : -1;
171
177
  // Force-enable include_deleted for /trash and /trash/<sub> requests so
@@ -177,6 +183,12 @@ const registerPageRoutes = (app, crowi) => {
177
183
  try {
178
184
  let pages = [];
179
185
  let portalPage = null;
186
+ // §4 — when listing a portal path (`/foo/`) that has no portal
187
+ // document of its own, surface the content page sitting at the
188
+ // stripped path (`/foo`) so the list view can offer "portalize
189
+ // this page" instead of "Create Portal". Mutually exclusive with
190
+ // `portalPage`. Only ever set in the path branch below.
191
+ let contentPage = null;
180
192
  if (userParam) {
181
193
  // List pages by creator.
182
194
  const targetUser = await User.findById(userParam);
@@ -197,13 +209,27 @@ const registerPageRoutes = (app, crowi) => {
197
209
  // List pages by path. /trash subtrees skip findPortalPage to
198
210
  // mirror the legacy deletedPageListShow which always rendered
199
211
  // with page=null.
200
- const portalPagePromise = isTrashPath ? Promise.resolve(null) : Page.findPortalPage(path, user);
212
+ const portalPagePromise = isTrashPath ? Promise.resolve(null) : Page.findPortalPage(path, user, revision_id || null);
201
213
  const listPromise = Page.findListByStartWith(path, user, { limit, offset, includeDeletedPage, sort, desc: sortDir });
202
214
  const [rawPortalPage, rawPages] = await Promise.all([portalPagePromise, listPromise]);
203
215
  [portalPage, pages] = (await Promise.all([
204
216
  rawPortalPage ? Page.populate(rawPortalPage, [{ path: 'creator' }, { path: 'lastUpdateUser' }]) : null,
205
217
  Page.populate(rawPages, [{ path: 'creator' }, { path: 'lastUpdateUser' }]),
206
218
  ]));
219
+ // §4 — a portal path (`/foo/`) with no portal document but a
220
+ // content page at the stripped path (`/foo`): resolve that
221
+ // content page (grant/draft-respecting; not-found → null) so the
222
+ // client can offer to portalize it. Skipped for /trash and when
223
+ // a real portal already exists (the two are exclusive).
224
+ if (!isTrashPath && !portalPage && path.endsWith('/')) {
225
+ const strippedPath = path.replace(/\/+$/, '');
226
+ if (strippedPath !== '') {
227
+ const rawContentPage = await Page.findPortalPage(strippedPath, user, null);
228
+ contentPage = rawContentPage
229
+ ? (await Page.populate(rawContentPage, [{ path: 'creator' }, { path: 'lastUpdateUser' }]))
230
+ : null;
231
+ }
232
+ }
207
233
  }
208
234
  else {
209
235
  // List all pages the user can access (including path='/').
@@ -238,7 +264,7 @@ const registerPageRoutes = (app, crowi) => {
238
264
  };
239
265
  if (path === '/') {
240
266
  [portalPage, pages] = await Promise.all([
241
- Page.findPortalPage(path, user),
267
+ Page.findPortalPage(path, user, revision_id || null),
242
268
  Page.find(conditions)
243
269
  .sort({ [sort]: sortDir })
244
270
  .skip(offset)
@@ -271,6 +297,15 @@ const registerPageRoutes = (app, crowi) => {
271
297
  const portalId = String(portalPage._id);
272
298
  pages = pages.filter((page) => String(page._id) !== portalId);
273
299
  }
300
+ // §4 — the content page surfaced separately as `contentPage` is
301
+ // also matched by `findListByStartWith` (the un-slashed twin of
302
+ // the portal path), so drop it from the child rows for the same
303
+ // reason as `portalPage`: it is rendered as the portalize banner,
304
+ // not as a child.
305
+ if (contentPage) {
306
+ const contentId = String(contentPage._id);
307
+ pages = pages.filter((page) => String(page._id) !== contentId);
308
+ }
274
309
  const pageResponses = pages.map((page) => (0, page_response_1.pageToResponse)(page));
275
310
  // The portal document is rendered as a full page (PageContent)
276
311
  // by the web client, so — unlike the list rows — it needs
@@ -285,12 +320,17 @@ const registerPageRoutes = (app, crowi) => {
285
320
  portalPageResponse.revision.meta = meta;
286
321
  portalPageResponse.revision.renderedAst = renderedAst;
287
322
  }
323
+ // §4 — content page emitted lean (no renderedAst): the client uses
324
+ // it only to drive the portalize banner (id / path / revision id),
325
+ // never to render the page body.
326
+ const contentPageResponse = contentPage ? (0, page_response_1.pageToResponse)(contentPage) : null;
288
327
  const prev = offset > 0 ? Math.max(0, offset - limit) : null;
289
328
  const next = pages.length === limit ? offset + limit : null;
290
329
  return c.json({
291
330
  pages: pageResponses,
292
331
  pager: { prev, next, offset },
293
332
  portalPage: portalPageResponse,
333
+ contentPage: contentPageResponse,
294
334
  }, 200);
295
335
  }
296
336
  catch (err) {
@@ -301,6 +341,7 @@ const registerPageRoutes = (app, crowi) => {
301
341
  pages: [],
302
342
  pager: { prev: null, next: null, offset: 0 },
303
343
  portalPage: null,
344
+ contentPage: null,
304
345
  }, 200);
305
346
  }
306
347
  })
@@ -337,6 +378,15 @@ const registerPageRoutes = (app, crowi) => {
337
378
  if (existing !== null) {
338
379
  return c.json(pageBadRequestBody('PAGE_EXISTS', 'Page exists'), 400);
339
380
  }
381
+ // §6 — block the `/x` ↔ `/x/` double-state: refuse to create a
382
+ // page whose trailing-slash twin already exists as a real page.
383
+ // Use `normalizePath` so the twin check sees the same path the
384
+ // creation will use.
385
+ const normalizedCreatePath = Page.normalizePath(path);
386
+ const twin = await Page.findExistingTwin(normalizedCreatePath);
387
+ if (twin) {
388
+ return c.json(pageTwinExistsBody(twin.path), 400);
389
+ }
340
390
  // RFC-0010 — record the edit channel (web / oauth / pat) so the
341
391
  // history view can flag API-token edits.
342
392
  const createOptions = { editVia: c.get('authContext').kind };
@@ -599,6 +649,59 @@ const registerPageRoutes = (app, crowi) => {
599
649
  }
600
650
  return c.json(pageBadRequestBody('PAGE_REVERT_FAILED', error.message || 'Failed to revert deleted page'), 400);
601
651
  }
652
+ })
653
+ // --------------------------------------------------------------
654
+ // POST /pages/revert-to-revision — revertToRevision
655
+ //
656
+ // Restore the page's body to one of its PAST revisions by stacking
657
+ // that body as a NEW revision on top of the current latest. This is
658
+ // non-destructive: the whole history is preserved, and the revert is
659
+ // always applied on top of the server-side latest (no optimistic-lock
660
+ // 409 — if someone else updated the page since the caller opened the
661
+ // old version, the revert lands on top of that newer revision rather
662
+ // than conflicting). Page.updatePage handles prepareRevision →
663
+ // pushRevision → pageEvent.emit('update', …, true), so notify / collab
664
+ // fan-out comes for free.
665
+ // --------------------------------------------------------------
666
+ .openapi(api_contract_1.revertToRevisionRoute, async (c) => {
667
+ const user = c.get('user');
668
+ const { page_id, revision_id } = c.req.valid('json');
669
+ debug('revertToRevision called with:', { page_id, revision_id, userId: user._id });
670
+ if (!(0, ts_rest_helpers_1.isValidObjectId)(revision_id)) {
671
+ return c.json(pageBadRequestBody('PAGE_REVERT_TO_REVISION_FAILED', 'Invalid revision id'), 400);
672
+ }
673
+ try {
674
+ // Grant + draft visibility checks (collapse to 404 — same leak-
675
+ // guard as updatePage so a non-granted caller can't probe page
676
+ // existence).
677
+ const pageData = (await Page.findPageByIdAndGrantedUser(page_id, user));
678
+ if (!pageData) {
679
+ return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
680
+ }
681
+ // The revision to revert TO. Must belong to this page (same path)
682
+ // so a caller cannot graft another page's body onto this one.
683
+ const oldRevision = await Revision.findRevision(new mongoose_1.Types.ObjectId(revision_id));
684
+ if (!oldRevision || oldRevision.path !== pageData.path) {
685
+ return c.json(pageBadRequestBody('PAGE_REVERT_TO_REVISION_FAILED', 'Revision does not belong to this page'), 400);
686
+ }
687
+ // Stack the old body as a new revision on top of the latest. The
688
+ // base is pageData.revision (the server-side latest), set inside
689
+ // prepareRevision — the client never supplies one. No `grant` option
690
+ // is passed: updatePage defaults to `pageData.grant`, which keeps
691
+ // the grant-update branch skipped (visibility is preserved).
692
+ const updateOptions = { editVia: c.get('authContext').kind };
693
+ const updated = (await Page.updatePage(pageData, oldRevision.body, user, updateOptions));
694
+ const populated = await Page.populatePageData(updated, null);
695
+ return c.json({ page: (0, page_response_1.pageToResponse)(populated) }, 200);
696
+ }
697
+ catch (err) {
698
+ const error = err;
699
+ debug('Error reverting page to revision:', error.message);
700
+ if (error.message === 'Page not found' || error.message === 'Page is not granted for the user') {
701
+ return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
702
+ }
703
+ return c.json(pageBadRequestBody('PAGE_REVERT_TO_REVISION_FAILED', error.message || 'Failed to revert page to revision'), 400);
704
+ }
602
705
  })
603
706
  // --------------------------------------------------------------
604
707
  // POST /pages/rename — renamePage
@@ -686,6 +789,14 @@ const registerPageRoutes = (app, crowi) => {
686
789
  // ------------------------------------------------------------
687
790
  // Single-page rename (default / back-compat).
688
791
  // ------------------------------------------------------------
792
+ // §6 — block the `/x` ↔ `/x/` double-state: refuse to move onto a
793
+ // path whose trailing-slash twin already exists as a real page.
794
+ // The source page itself is excluded, so portalizing `/x` → `/x/`
795
+ // (where the twin `/x` IS the page being moved) is allowed.
796
+ const twinAtNewPath = await Page.findExistingTwin(newPagePath, { excludeId: pageData._id });
797
+ if (twinAtNewPath) {
798
+ return c.json(pageTwinExistsBody(twinAtNewPath.path), 400);
799
+ }
689
800
  // Collision at the destination path — unlink an existing
690
801
  // redirect when the caller has permission, otherwise refuse.
691
802
  const existingAtNewPath = await Page.findOne({ path: newPagePath });
@@ -703,10 +814,16 @@ const registerPageRoutes = (app, crowi) => {
703
814
  return c.json(pageBadRequestBody('PAGE_EXISTS', `Cannot rename to this page name (${newPagePath}). Page exists.`), 400);
704
815
  }
705
816
  }
706
- // Legacy controller: portal paths (ending in '/') never get a
707
- // redirect page even if requested.
817
+ // Honour `create_redirect` regardless of the destination's
818
+ // portal-ness. Portalizing `/x` `/x/` leaves a redirect at the
819
+ // old content path so existing links / bookmarks to `/x` keep
820
+ // resolving (to the new portal) — the same behaviour every other
821
+ // rename already has (RenameDialog always requests a redirect). The
822
+ // redirect stub has `redirectTo` set, so `findExistingTwin` (which
823
+ // filters `redirectTo: null`) does not treat it as a `/x` ↔ `/x/`
824
+ // twin, and it is hidden from listings (also `redirectTo: null`).
708
825
  const options = {
709
- createRedirectPage: !newPageIsPortal && Boolean(create_redirect),
826
+ createRedirectPage: Boolean(create_redirect),
710
827
  };
711
828
  await Page.rename(pageData, newPagePath, user, options);
712
829
  const populated = await Page.populatePageData(pageData, null);