@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.
- package/dist/hono/handlers/activation.d.ts +3 -3
- package/dist/hono/handlers/admin/users.d.ts +118 -0
- package/dist/hono/handlers/admin/users.js +28 -0
- package/dist/hono/handlers/admin/users.js.map +1 -1
- package/dist/hono/handlers/app.d.ts +1 -0
- package/dist/hono/handlers/app.js +11 -0
- package/dist/hono/handlers/app.js.map +1 -1
- package/dist/hono/handlers/attachment-stream.js +23 -0
- package/dist/hono/handlers/attachment-stream.js.map +1 -1
- package/dist/hono/handlers/draft.js +10 -0
- package/dist/hono/handlers/draft.js.map +1 -1
- package/dist/hono/handlers/emailChange.d.ts +4 -4
- package/dist/hono/handlers/inviteAccept.d.ts +6 -6
- package/dist/hono/handlers/page.d.ts +251 -0
- package/dist/hono/handlers/page.js +123 -6
- package/dist/hono/handlers/page.js.map +1 -1
- package/dist/hono/handlers/passwordReset.d.ts +5 -5
- package/dist/hono/handlers/tokenAuth.d.ts +7 -7
- package/dist/mcp/result.d.ts +42 -16
- package/dist/mcp/result.js +56 -10
- package/dist/mcp/result.js.map +1 -1
- package/dist/mcp/tools/page.js +21 -1
- package/dist/mcp/tools/page.js.map +1 -1
- package/dist/mcp/tools/search.d.ts +12 -0
- package/dist/mcp/tools/search.js +21 -5
- package/dist/mcp/tools/search.js.map +1 -1
- package/dist/migration/helpers.d.ts +13 -0
- package/dist/migration/helpers.js +29 -0
- package/dist/migration/helpers.js.map +1 -0
- package/dist/migration/migrations/files-url-to-attachments.d.ts +35 -0
- package/dist/migration/migrations/files-url-to-attachments.js +291 -0
- package/dist/migration/migrations/files-url-to-attachments.js.map +1 -0
- package/dist/migration/migrations/index.js +4 -0
- package/dist/migration/migrations/index.js.map +1 -1
- package/dist/migration/migrations/published-current-revision.d.ts +47 -0
- package/dist/migration/migrations/published-current-revision.js +90 -0
- package/dist/migration/migrations/published-current-revision.js.map +1 -0
- package/dist/migration/migrations/wikilink-format.d.ts +0 -11
- package/dist/migration/migrations/wikilink-format.js +5 -156
- package/dist/migration/migrations/wikilink-format.js.map +1 -1
- package/dist/migration/migrations/wikilink-html-recover.d.ts +116 -0
- package/dist/migration/migrations/wikilink-html-recover.js +314 -0
- package/dist/migration/migrations/wikilink-html-recover.js.map +1 -0
- package/dist/models/page.d.ts +3 -0
- package/dist/models/page.js +31 -0
- package/dist/models/page.js.map +1 -1
- package/dist/models/user.d.ts +1 -0
- package/dist/models/user.js +40 -21
- package/dist/models/user.js.map +1 -1
- package/dist/renderer/core/headings.d.ts +12 -1
- package/dist/renderer/core/headings.js +48 -8
- package/dist/renderer/core/headings.js.map +1 -1
- package/dist/renderer/pipeline.d.ts +6 -0
- package/dist/renderer/pipeline.js.map +1 -1
- package/dist/util/page-response.js +19 -2
- package/dist/util/page-response.js.map +1 -1
- package/package.json +12 -6
- package/views/mail/layout.mjml +7 -5
- package/dist/common/functions/path2name.d.ts +0 -1
- package/dist/common/functions/path2name.js +0 -22
- package/dist/common/functions/path2name.js.map +0 -1
- package/dist/common/functions/renderIcon.d.ts +0 -1
- package/dist/common/functions/renderIcon.js +0 -9
- package/dist/common/functions/renderIcon.js.map +0 -1
- package/dist/controllers/admin.d.ts +0 -3
- package/dist/controllers/admin.js +0 -474
- package/dist/controllers/admin.js.map +0 -1
- package/dist/controllers/attachment.d.ts +0 -4
- package/dist/controllers/attachment.js +0 -200
- package/dist/controllers/attachment.js.map +0 -1
- package/dist/controllers/backlink.d.ts +0 -3
- package/dist/controllers/backlink.js +0 -42
- package/dist/controllers/backlink.js.map +0 -1
- package/dist/controllers/bookmark.d.ts +0 -3
- package/dist/controllers/bookmark.js +0 -100
- package/dist/controllers/bookmark.js.map +0 -1
- package/dist/controllers/comment.d.ts +0 -3
- package/dist/controllers/comment.js +0 -111
- package/dist/controllers/comment.js.map +0 -1
- package/dist/controllers/index.d.ts +0 -25
- package/dist/controllers/index.js +0 -44
- package/dist/controllers/index.js.map +0 -1
- package/dist/controllers/installer.d.ts +0 -3
- package/dist/controllers/installer.js +0 -48
- package/dist/controllers/installer.js.map +0 -1
- package/dist/controllers/login.d.ts +0 -4
- package/dist/controllers/login.js +0 -438
- package/dist/controllers/login.js.map +0 -1
- package/dist/controllers/logout.d.ts +0 -5
- package/dist/controllers/logout.js +0 -11
- package/dist/controllers/logout.js.map +0 -1
- package/dist/controllers/me.d.ts +0 -4
- package/dist/controllers/me.js +0 -369
- package/dist/controllers/me.js.map +0 -1
- package/dist/controllers/notification.d.ts +0 -3
- package/dist/controllers/notification.js +0 -88
- package/dist/controllers/notification.js.map +0 -1
- package/dist/controllers/page.d.ts +0 -3
- package/dist/controllers/page.js +0 -881
- package/dist/controllers/page.js.map +0 -1
- package/dist/controllers/revision.d.ts +0 -3
- package/dist/controllers/revision.js +0 -91
- package/dist/controllers/revision.js.map +0 -1
- package/dist/controllers/search.d.ts +0 -3
- package/dist/controllers/search.js +0 -93
- package/dist/controllers/search.js.map +0 -1
- package/dist/controllers/share.d.ts +0 -3
- package/dist/controllers/share.js +0 -207
- package/dist/controllers/share.js.map +0 -1
- package/dist/controllers/shareAccess.d.ts +0 -3
- package/dist/controllers/shareAccess.js +0 -28
- package/dist/controllers/shareAccess.js.map +0 -1
- package/dist/controllers/slack.d.ts +0 -3
- package/dist/controllers/slack.js +0 -87
- package/dist/controllers/slack.js.map +0 -1
- package/dist/controllers/tokenAuth.d.ts +0 -10
- package/dist/controllers/tokenAuth.js +0 -292
- package/dist/controllers/tokenAuth.js.map +0 -1
- package/dist/controllers/user.d.ts +0 -3
- package/dist/controllers/user.js +0 -67
- package/dist/controllers/user.js.map +0 -1
- package/dist/controllers/version.d.ts +0 -4
- package/dist/controllers/version.js +0 -19
- package/dist/controllers/version.js.map +0 -1
- package/dist/crowi/express-init.d.ts +0 -4
- package/dist/crowi/express-init.js +0 -101
- package/dist/crowi/express-init.js.map +0 -1
- package/dist/form/admin/app.d.ts +0 -2
- package/dist/form/admin/app.js +0 -9
- package/dist/form/admin/app.js.map +0 -1
- package/dist/form/admin/auth.d.ts +0 -2
- package/dist/form/admin/auth.js +0 -9
- package/dist/form/admin/auth.js.map +0 -1
- package/dist/form/admin/aws.d.ts +0 -2
- package/dist/form/admin/aws.js +0 -13
- package/dist/form/admin/aws.js.map +0 -1
- package/dist/form/admin/github.d.ts +0 -2
- package/dist/form/admin/github.js +0 -15
- package/dist/form/admin/github.js.map +0 -1
- package/dist/form/admin/google.d.ts +0 -2
- package/dist/form/admin/google.js +0 -13
- package/dist/form/admin/google.js.map +0 -1
- package/dist/form/admin/mail.d.ts +0 -2
- package/dist/form/admin/mail.js +0 -13
- package/dist/form/admin/mail.js.map +0 -1
- package/dist/form/admin/sec.d.ts +0 -2
- package/dist/form/admin/sec.js +0 -10
- package/dist/form/admin/sec.js.map +0 -1
- package/dist/form/admin/slackSetting.d.ts +0 -2
- package/dist/form/admin/slackSetting.js +0 -13
- package/dist/form/admin/slackSetting.js.map +0 -1
- package/dist/form/admin/userEdit.d.ts +0 -2
- package/dist/form/admin/userEdit.js +0 -9
- package/dist/form/admin/userEdit.js.map +0 -1
- package/dist/form/admin/userInvite.d.ts +0 -2
- package/dist/form/admin/userInvite.js +0 -9
- package/dist/form/admin/userInvite.js.map +0 -1
- package/dist/form/comment.d.ts +0 -2
- package/dist/form/comment.js +0 -9
- package/dist/form/comment.js.map +0 -1
- package/dist/form/index.d.ts +0 -25
- package/dist/form/index.js +0 -48
- package/dist/form/index.js.map +0 -1
- package/dist/form/invited.d.ts +0 -2
- package/dist/form/invited.js +0 -13
- package/dist/form/invited.js.map +0 -1
- package/dist/form/login.d.ts +0 -2
- package/dist/form/login.js +0 -11
- package/dist/form/login.js.map +0 -1
- package/dist/form/me/apiToken.d.ts +0 -2
- package/dist/form/me/apiToken.js +0 -9
- package/dist/form/me/apiToken.js.map +0 -1
- package/dist/form/me/password.d.ts +0 -2
- package/dist/form/me/password.js +0 -11
- package/dist/form/me/password.js.map +0 -1
- package/dist/form/me/user.d.ts +0 -2
- package/dist/form/me/user.js +0 -9
- package/dist/form/me/user.js.map +0 -1
- package/dist/form/register.d.ts +0 -2
- package/dist/form/register.js +0 -13
- package/dist/form/register.js.map +0 -1
- package/dist/form/revision.d.ts +0 -2
- package/dist/form/revision.js +0 -13
- package/dist/form/revision.js.map +0 -1
- package/dist/hono/handlers/admin/share.d.ts +0 -106
- package/dist/hono/handlers/admin/share.js +0 -55
- package/dist/hono/handlers/admin/share.js.map +0 -1
- package/dist/middlewares/accessTokenParser.d.ts +0 -4
- package/dist/middlewares/accessTokenParser.js +0 -29
- package/dist/middlewares/accessTokenParser.js.map +0 -1
- package/dist/middlewares/adminRequired.d.ts +0 -10
- package/dist/middlewares/adminRequired.js +0 -35
- package/dist/middlewares/adminRequired.js.map +0 -1
- package/dist/middlewares/applicationInstalled.d.ts +0 -3
- package/dist/middlewares/applicationInstalled.js +0 -20
- package/dist/middlewares/applicationInstalled.js.map +0 -1
- package/dist/middlewares/applicationNotInstalled.d.ts +0 -3
- package/dist/middlewares/applicationNotInstalled.js +0 -13
- package/dist/middlewares/applicationNotInstalled.js.map +0 -1
- package/dist/middlewares/basicAuth.d.ts +0 -4
- package/dist/middlewares/basicAuth.js +0 -23
- package/dist/middlewares/basicAuth.js.map +0 -1
- package/dist/middlewares/csrfVerify.d.ts +0 -4
- package/dist/middlewares/csrfVerify.js +0 -24
- package/dist/middlewares/csrfVerify.js.map +0 -1
- package/dist/middlewares/encodeSpace.d.ts +0 -3
- package/dist/middlewares/encodeSpace.js +0 -14
- package/dist/middlewares/encodeSpace.js.map +0 -1
- package/dist/middlewares/fileAccessRightOrLoginRequired.d.ts +0 -4
- package/dist/middlewares/fileAccessRightOrLoginRequired.js +0 -29
- package/dist/middlewares/fileAccessRightOrLoginRequired.js.map +0 -1
- package/dist/middlewares/index.d.ts +0 -16
- package/dist/middlewares/index.js +0 -30
- package/dist/middlewares/index.js.map +0 -1
- package/dist/middlewares/jwtAdminRequired.d.ts +0 -8
- package/dist/middlewares/jwtAdminRequired.js +0 -35
- package/dist/middlewares/jwtAdminRequired.js.map +0 -1
- package/dist/middlewares/jwtAuth.d.ts +0 -4
- package/dist/middlewares/jwtAuth.js +0 -104
- package/dist/middlewares/jwtAuth.js.map +0 -1
- package/dist/middlewares/loginChecker.d.ts +0 -4
- package/dist/middlewares/loginChecker.js +0 -32
- package/dist/middlewares/loginChecker.js.map +0 -1
- package/dist/middlewares/loginRequired.d.ts +0 -4
- package/dist/middlewares/loginRequired.js +0 -88
- package/dist/middlewares/loginRequired.js.map +0 -1
- package/dist/routes/admin.d.ts +0 -4
- package/dist/routes/admin.js +0 -17
- package/dist/routes/admin.js.map +0 -1
- package/dist/routes/api/admin.d.ts +0 -4
- package/dist/routes/api/admin.js +0 -37
- package/dist/routes/api/admin.js.map +0 -1
- package/dist/routes/api/attachment.d.ts +0 -4
- package/dist/routes/api/attachment.js +0 -19
- package/dist/routes/api/attachment.js.map +0 -1
- package/dist/routes/api/bookmark.d.ts +0 -4
- package/dist/routes/api/bookmark.js +0 -15
- package/dist/routes/api/bookmark.js.map +0 -1
- package/dist/routes/api/comment.d.ts +0 -4
- package/dist/routes/api/comment.js +0 -14
- package/dist/routes/api/comment.js.map +0 -1
- package/dist/routes/api/index.d.ts +0 -4
- package/dist/routes/api/index.js +0 -36
- package/dist/routes/api/index.js.map +0 -1
- package/dist/routes/api/like.d.ts +0 -4
- package/dist/routes/api/like.js +0 -13
- package/dist/routes/api/like.js.map +0 -1
- package/dist/routes/api/notification.d.ts +0 -4
- package/dist/routes/api/notification.js +0 -15
- package/dist/routes/api/notification.js.map +0 -1
- package/dist/routes/api/page.d.ts +0 -4
- package/dist/routes/api/page.js +0 -24
- package/dist/routes/api/page.js.map +0 -1
- package/dist/routes/api/revision.d.ts +0 -4
- package/dist/routes/api/revision.js +0 -14
- package/dist/routes/api/revision.js.map +0 -1
- package/dist/routes/api/share.d.ts +0 -4
- package/dist/routes/api/share.js +0 -16
- package/dist/routes/api/share.js.map +0 -1
- package/dist/routes/api/version.d.ts +0 -4
- package/dist/routes/api/version.js +0 -10
- package/dist/routes/api/version.js.map +0 -1
- package/dist/routes/index.d.ts +0 -4
- package/dist/routes/index.js +0 -71
- package/dist/routes/index.js.map +0 -1
- package/dist/routes/login.d.ts +0 -4
- package/dist/routes/login.js +0 -18
- package/dist/routes/login.js.map +0 -1
- package/dist/routes/me.d.ts +0 -4
- package/dist/routes/me.js +0 -24
- package/dist/routes/me.js.map +0 -1
- package/dist/routes/ts-rest/admin/app.d.ts +0 -4
- package/dist/routes/ts-rest/admin/app.js +0 -67
- package/dist/routes/ts-rest/admin/app.js.map +0 -1
- package/dist/routes/ts-rest/admin/auth.d.ts +0 -4
- package/dist/routes/ts-rest/admin/auth.js +0 -95
- package/dist/routes/ts-rest/admin/auth.js.map +0 -1
- package/dist/routes/ts-rest/admin/index.d.ts +0 -10
- package/dist/routes/ts-rest/admin/index.js +0 -35
- package/dist/routes/ts-rest/admin/index.js.map +0 -1
- package/dist/routes/ts-rest/admin/mail.d.ts +0 -4
- package/dist/routes/ts-rest/admin/mail.js +0 -156
- package/dist/routes/ts-rest/admin/mail.js.map +0 -1
- package/dist/routes/ts-rest/admin/plugins.d.ts +0 -4
- package/dist/routes/ts-rest/admin/plugins.js +0 -317
- package/dist/routes/ts-rest/admin/plugins.js.map +0 -1
- package/dist/routes/ts-rest/admin/search.d.ts +0 -4
- package/dist/routes/ts-rest/admin/search.js +0 -67
- package/dist/routes/ts-rest/admin/search.js.map +0 -1
- package/dist/routes/ts-rest/admin/security.d.ts +0 -4
- package/dist/routes/ts-rest/admin/security.js +0 -114
- package/dist/routes/ts-rest/admin/security.js.map +0 -1
- package/dist/routes/ts-rest/admin/share.d.ts +0 -4
- package/dist/routes/ts-rest/admin/share.js +0 -69
- package/dist/routes/ts-rest/admin/share.js.map +0 -1
- package/dist/routes/ts-rest/admin/storage.d.ts +0 -4
- package/dist/routes/ts-rest/admin/storage.js +0 -59
- package/dist/routes/ts-rest/admin/storage.js.map +0 -1
- package/dist/routes/ts-rest/admin/users.d.ts +0 -4
- package/dist/routes/ts-rest/admin/users.js +0 -215
- package/dist/routes/ts-rest/admin/users.js.map +0 -1
- package/dist/routes/ts-rest/adminCrypto.d.ts +0 -4
- package/dist/routes/ts-rest/adminCrypto.js +0 -111
- package/dist/routes/ts-rest/adminCrypto.js.map +0 -1
- package/dist/routes/ts-rest/app.d.ts +0 -4
- package/dist/routes/ts-rest/app.js +0 -23
- package/dist/routes/ts-rest/app.js.map +0 -1
- package/dist/routes/ts-rest/attachment.d.ts +0 -4
- package/dist/routes/ts-rest/attachment.js +0 -830
- package/dist/routes/ts-rest/attachment.js.map +0 -1
- package/dist/routes/ts-rest/auth.d.ts +0 -4
- package/dist/routes/ts-rest/auth.js +0 -70
- package/dist/routes/ts-rest/auth.js.map +0 -1
- package/dist/routes/ts-rest/autocomplete.d.ts +0 -30
- package/dist/routes/ts-rest/autocomplete.js +0 -189
- package/dist/routes/ts-rest/autocomplete.js.map +0 -1
- package/dist/routes/ts-rest/backlink.d.ts +0 -4
- package/dist/routes/ts-rest/backlink.js +0 -106
- package/dist/routes/ts-rest/backlink.js.map +0 -1
- package/dist/routes/ts-rest/bookmark.d.ts +0 -4
- package/dist/routes/ts-rest/bookmark.js +0 -189
- package/dist/routes/ts-rest/bookmark.js.map +0 -1
- package/dist/routes/ts-rest/comment.d.ts +0 -4
- package/dist/routes/ts-rest/comment.js +0 -217
- package/dist/routes/ts-rest/comment.js.map +0 -1
- package/dist/routes/ts-rest/draft.d.ts +0 -22
- package/dist/routes/ts-rest/draft.js +0 -200
- package/dist/routes/ts-rest/draft.js.map +0 -1
- package/dist/routes/ts-rest/index.d.ts +0 -4
- package/dist/routes/ts-rest/index.js +0 -103
- package/dist/routes/ts-rest/index.js.map +0 -1
- package/dist/routes/ts-rest/installer.d.ts +0 -4
- package/dist/routes/ts-rest/installer.js +0 -77
- package/dist/routes/ts-rest/installer.js.map +0 -1
- package/dist/routes/ts-rest/me.d.ts +0 -4
- package/dist/routes/ts-rest/me.js +0 -410
- package/dist/routes/ts-rest/me.js.map +0 -1
- package/dist/routes/ts-rest/notification.d.ts +0 -4
- package/dist/routes/ts-rest/notification.js +0 -241
- package/dist/routes/ts-rest/notification.js.map +0 -1
- package/dist/routes/ts-rest/page-collab.d.ts +0 -29
- package/dist/routes/ts-rest/page-collab.js +0 -90
- package/dist/routes/ts-rest/page-collab.js.map +0 -1
- package/dist/routes/ts-rest/page-preview.d.ts +0 -26
- package/dist/routes/ts-rest/page-preview.js +0 -80
- package/dist/routes/ts-rest/page-preview.js.map +0 -1
- package/dist/routes/ts-rest/page.d.ts +0 -4
- package/dist/routes/ts-rest/page.js +0 -676
- package/dist/routes/ts-rest/page.js.map +0 -1
- package/dist/routes/ts-rest/presence.d.ts +0 -30
- package/dist/routes/ts-rest/presence.js +0 -155
- package/dist/routes/ts-rest/presence.js.map +0 -1
- package/dist/routes/ts-rest/revision.d.ts +0 -4
- package/dist/routes/ts-rest/revision.js +0 -240
- package/dist/routes/ts-rest/revision.js.map +0 -1
- package/dist/routes/ts-rest/search.d.ts +0 -4
- package/dist/routes/ts-rest/search.js +0 -121
- package/dist/routes/ts-rest/search.js.map +0 -1
- package/dist/routes/ts-rest/tokenAuth.d.ts +0 -4
- package/dist/routes/ts-rest/tokenAuth.js +0 -94
- package/dist/routes/ts-rest/tokenAuth.js.map +0 -1
- package/dist/routes/ts-rest/user.d.ts +0 -4
- package/dist/routes/ts-rest/user.js +0 -307
- package/dist/routes/ts-rest/user.js.map +0 -1
- package/dist/types/express.d.ts +0 -34
- package/dist/types/express.js +0 -50
- package/dist/types/express.js.map +0 -1
- package/dist/util/accessTokenParser.d.ts +0 -1
- package/dist/util/accessTokenParser.js +0 -34
- package/dist/util/accessTokenParser.js.map +0 -1
- package/dist/util/apiPaginate.d.ts +0 -11
- package/dist/util/apiPaginate.js +0 -33
- package/dist/util/apiPaginate.js.map +0 -1
- package/dist/util/apiResponse.d.ts +0 -9
- package/dist/util/apiResponse.js +0 -23
- package/dist/util/apiResponse.js.map +0 -1
- package/dist/util/auth.d.ts +0 -11
- package/dist/util/auth.js +0 -48
- package/dist/util/auth.js.map +0 -1
- package/dist/util/aws-config-migration.d.ts +0 -11
- package/dist/util/aws-config-migration.js +0 -68
- package/dist/util/aws-config-migration.js.map +0 -1
- package/dist/util/formUtil.d.ts +0 -2
- package/dist/util/formUtil.js +0 -15
- package/dist/util/formUtil.js.map +0 -1
- package/dist/util/githubAuth.d.ts +0 -2
- package/dist/util/githubAuth.js +0 -82
- package/dist/util/githubAuth.js.map +0 -1
- package/dist/util/googleAuth.d.ts +0 -2
- package/dist/util/googleAuth.js +0 -85
- package/dist/util/googleAuth.js.map +0 -1
- package/dist/util/mailer.d.ts +0 -7
- package/dist/util/mailer.js +0 -98
- package/dist/util/mailer.js.map +0 -1
- package/dist/util/page-status-migration.d.ts +0 -23
- package/dist/util/page-status-migration.js +0 -48
- package/dist/util/page-status-migration.js.map +0 -1
- package/dist/util/ssr.d.ts +0 -3
- package/dist/util/ssr.js +0 -9
- package/dist/util/ssr.js.map +0 -1
- package/dist/util/view.d.ts +0 -10
- package/dist/util/view.js +0 -99
- 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
|
-
//
|
|
707
|
-
//
|
|
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:
|
|
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);
|