@crowi/api 2.0.0-alpha.0
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/LICENSE +21 -0
- package/dist/app.d.ts +8 -0
- package/dist/app.js +65 -0
- package/dist/app.js.map +1 -0
- package/dist/collab/attach.d.ts +33 -0
- package/dist/collab/attach.js +341 -0
- package/dist/collab/attach.js.map +1 -0
- package/dist/collab/extension-redis.d.ts +25 -0
- package/dist/collab/extension-redis.js +133 -0
- package/dist/collab/extension-redis.js.map +1 -0
- package/dist/common/functions/path2name.d.ts +1 -0
- package/dist/common/functions/path2name.js +22 -0
- package/dist/common/functions/path2name.js.map +1 -0
- package/dist/common/functions/renderIcon.d.ts +1 -0
- package/dist/common/functions/renderIcon.js +9 -0
- package/dist/common/functions/renderIcon.js.map +1 -0
- package/dist/controllers/admin.d.ts +3 -0
- package/dist/controllers/admin.js +474 -0
- package/dist/controllers/admin.js.map +1 -0
- package/dist/controllers/attachment.d.ts +4 -0
- package/dist/controllers/attachment.js +200 -0
- package/dist/controllers/attachment.js.map +1 -0
- package/dist/controllers/backlink.d.ts +3 -0
- package/dist/controllers/backlink.js +42 -0
- package/dist/controllers/backlink.js.map +1 -0
- package/dist/controllers/bookmark.d.ts +3 -0
- package/dist/controllers/bookmark.js +100 -0
- package/dist/controllers/bookmark.js.map +1 -0
- package/dist/controllers/comment.d.ts +3 -0
- package/dist/controllers/comment.js +111 -0
- package/dist/controllers/comment.js.map +1 -0
- package/dist/controllers/index.d.ts +25 -0
- package/dist/controllers/index.js +44 -0
- package/dist/controllers/index.js.map +1 -0
- package/dist/controllers/installer.d.ts +3 -0
- package/dist/controllers/installer.js +48 -0
- package/dist/controllers/installer.js.map +1 -0
- package/dist/controllers/login.d.ts +4 -0
- package/dist/controllers/login.js +438 -0
- package/dist/controllers/login.js.map +1 -0
- package/dist/controllers/logout.d.ts +5 -0
- package/dist/controllers/logout.js +11 -0
- package/dist/controllers/logout.js.map +1 -0
- package/dist/controllers/me.d.ts +4 -0
- package/dist/controllers/me.js +369 -0
- package/dist/controllers/me.js.map +1 -0
- package/dist/controllers/notification.d.ts +3 -0
- package/dist/controllers/notification.js +88 -0
- package/dist/controllers/notification.js.map +1 -0
- package/dist/controllers/page.d.ts +3 -0
- package/dist/controllers/page.js +881 -0
- package/dist/controllers/page.js.map +1 -0
- package/dist/controllers/revision.d.ts +3 -0
- package/dist/controllers/revision.js +91 -0
- package/dist/controllers/revision.js.map +1 -0
- package/dist/controllers/search.d.ts +3 -0
- package/dist/controllers/search.js +93 -0
- package/dist/controllers/search.js.map +1 -0
- package/dist/controllers/share.d.ts +3 -0
- package/dist/controllers/share.js +207 -0
- package/dist/controllers/share.js.map +1 -0
- package/dist/controllers/shareAccess.d.ts +3 -0
- package/dist/controllers/shareAccess.js +28 -0
- package/dist/controllers/shareAccess.js.map +1 -0
- package/dist/controllers/slack.d.ts +3 -0
- package/dist/controllers/slack.js +87 -0
- package/dist/controllers/slack.js.map +1 -0
- package/dist/controllers/tokenAuth.d.ts +10 -0
- package/dist/controllers/tokenAuth.js +292 -0
- package/dist/controllers/tokenAuth.js.map +1 -0
- package/dist/controllers/user.d.ts +3 -0
- package/dist/controllers/user.js +67 -0
- package/dist/controllers/user.js.map +1 -0
- package/dist/controllers/version.d.ts +4 -0
- package/dist/controllers/version.js +19 -0
- package/dist/controllers/version.js.map +1 -0
- package/dist/crowi/express-init.d.ts +4 -0
- package/dist/crowi/express-init.js +101 -0
- package/dist/crowi/express-init.js.map +1 -0
- package/dist/crowi/index.d.ts +245 -0
- package/dist/crowi/index.js +726 -0
- package/dist/crowi/index.js.map +1 -0
- package/dist/events/activity.d.ts +7 -0
- package/dist/events/activity.js +15 -0
- package/dist/events/activity.js.map +1 -0
- package/dist/events/bookmark.d.ts +8 -0
- package/dist/events/bookmark.js +16 -0
- package/dist/events/bookmark.js.map +1 -0
- package/dist/events/comment.d.ts +6 -0
- package/dist/events/comment.js +14 -0
- package/dist/events/comment.js.map +1 -0
- package/dist/events/config.d.ts +6 -0
- package/dist/events/config.js +12 -0
- package/dist/events/config.js.map +1 -0
- package/dist/events/index.d.ts +17 -0
- package/dist/events/index.js +22 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/mention-dispatch.d.ts +44 -0
- package/dist/events/mention-dispatch.js +151 -0
- package/dist/events/mention-dispatch.js.map +1 -0
- package/dist/events/notification.d.ts +7 -0
- package/dist/events/notification.js +15 -0
- package/dist/events/notification.js.map +1 -0
- package/dist/events/page.d.ts +44 -0
- package/dist/events/page.js +134 -0
- package/dist/events/page.js.map +1 -0
- package/dist/events/render-cache.d.ts +24 -0
- package/dist/events/render-cache.js +63 -0
- package/dist/events/render-cache.js.map +1 -0
- package/dist/events/user.d.ts +9 -0
- package/dist/events/user.js +39 -0
- package/dist/events/user.js.map +1 -0
- package/dist/form/admin/app.d.ts +2 -0
- package/dist/form/admin/app.js +9 -0
- package/dist/form/admin/app.js.map +1 -0
- package/dist/form/admin/auth.d.ts +2 -0
- package/dist/form/admin/auth.js +9 -0
- package/dist/form/admin/auth.js.map +1 -0
- package/dist/form/admin/aws.d.ts +2 -0
- package/dist/form/admin/aws.js +13 -0
- package/dist/form/admin/aws.js.map +1 -0
- package/dist/form/admin/github.d.ts +2 -0
- package/dist/form/admin/github.js +15 -0
- package/dist/form/admin/github.js.map +1 -0
- package/dist/form/admin/google.d.ts +2 -0
- package/dist/form/admin/google.js +13 -0
- package/dist/form/admin/google.js.map +1 -0
- package/dist/form/admin/mail.d.ts +2 -0
- package/dist/form/admin/mail.js +13 -0
- package/dist/form/admin/mail.js.map +1 -0
- package/dist/form/admin/sec.d.ts +2 -0
- package/dist/form/admin/sec.js +10 -0
- package/dist/form/admin/sec.js.map +1 -0
- package/dist/form/admin/slackSetting.d.ts +2 -0
- package/dist/form/admin/slackSetting.js +13 -0
- package/dist/form/admin/slackSetting.js.map +1 -0
- package/dist/form/admin/userEdit.d.ts +2 -0
- package/dist/form/admin/userEdit.js +9 -0
- package/dist/form/admin/userEdit.js.map +1 -0
- package/dist/form/admin/userInvite.d.ts +2 -0
- package/dist/form/admin/userInvite.js +9 -0
- package/dist/form/admin/userInvite.js.map +1 -0
- package/dist/form/comment.d.ts +2 -0
- package/dist/form/comment.js +9 -0
- package/dist/form/comment.js.map +1 -0
- package/dist/form/index.d.ts +25 -0
- package/dist/form/index.js +48 -0
- package/dist/form/index.js.map +1 -0
- package/dist/form/invited.d.ts +2 -0
- package/dist/form/invited.js +13 -0
- package/dist/form/invited.js.map +1 -0
- package/dist/form/login.d.ts +2 -0
- package/dist/form/login.js +11 -0
- package/dist/form/login.js.map +1 -0
- package/dist/form/me/apiToken.d.ts +2 -0
- package/dist/form/me/apiToken.js +9 -0
- package/dist/form/me/apiToken.js.map +1 -0
- package/dist/form/me/password.d.ts +2 -0
- package/dist/form/me/password.js +11 -0
- package/dist/form/me/password.js.map +1 -0
- package/dist/form/me/user.d.ts +2 -0
- package/dist/form/me/user.js +9 -0
- package/dist/form/me/user.js.map +1 -0
- package/dist/form/register.d.ts +2 -0
- package/dist/form/register.js +13 -0
- package/dist/form/register.js.map +1 -0
- package/dist/form/revision.d.ts +2 -0
- package/dist/form/revision.js +13 -0
- package/dist/form/revision.js.map +1 -0
- package/dist/hono/app.d.ts +19 -0
- package/dist/hono/app.js +21 -0
- package/dist/hono/app.js.map +1 -0
- package/dist/hono/handlers/_helpers/errors.d.ts +61 -0
- package/dist/hono/handlers/_helpers/errors.js +51 -0
- package/dist/hono/handlers/_helpers/errors.js.map +1 -0
- package/dist/hono/handlers/_helpers/user-shape.d.ts +46 -0
- package/dist/hono/handlers/_helpers/user-shape.js +23 -0
- package/dist/hono/handlers/_helpers/user-shape.js.map +1 -0
- package/dist/hono/handlers/access-token.d.ts +221 -0
- package/dist/hono/handlers/access-token.js +113 -0
- package/dist/hono/handlers/access-token.js.map +1 -0
- package/dist/hono/handlers/activation.d.ts +117 -0
- package/dist/hono/handlers/activation.js +77 -0
- package/dist/hono/handlers/activation.js.map +1 -0
- package/dist/hono/handlers/admin/app.d.ts +123 -0
- package/dist/hono/handlers/admin/app.js +76 -0
- package/dist/hono/handlers/admin/app.js.map +1 -0
- package/dist/hono/handlers/admin/auth.d.ts +127 -0
- package/dist/hono/handlers/admin/auth.js +91 -0
- package/dist/hono/handlers/admin/auth.js.map +1 -0
- package/dist/hono/handlers/admin/mail.d.ts +168 -0
- package/dist/hono/handlers/admin/mail.js +76 -0
- package/dist/hono/handlers/admin/mail.js.map +1 -0
- package/dist/hono/handlers/admin/plugins.d.ts +409 -0
- package/dist/hono/handlers/admin/plugins.js +257 -0
- package/dist/hono/handlers/admin/plugins.js.map +1 -0
- package/dist/hono/handlers/admin/search.d.ts +57 -0
- package/dist/hono/handlers/admin/search.js +55 -0
- package/dist/hono/handlers/admin/search.js.map +1 -0
- package/dist/hono/handlers/admin/security.d.ts +112 -0
- package/dist/hono/handlers/admin/security.js +71 -0
- package/dist/hono/handlers/admin/security.js.map +1 -0
- package/dist/hono/handlers/admin/share.d.ts +106 -0
- package/dist/hono/handlers/admin/share.js +55 -0
- package/dist/hono/handlers/admin/share.js.map +1 -0
- package/dist/hono/handlers/admin/storage.d.ts +55 -0
- package/dist/hono/handlers/admin/storage.js +40 -0
- package/dist/hono/handlers/admin/storage.js.map +1 -0
- package/dist/hono/handlers/admin/users.d.ts +1230 -0
- package/dist/hono/handlers/admin/users.js +316 -0
- package/dist/hono/handlers/admin/users.js.map +1 -0
- package/dist/hono/handlers/adminCrypto.d.ts +110 -0
- package/dist/hono/handlers/adminCrypto.js +151 -0
- package/dist/hono/handlers/adminCrypto.js.map +1 -0
- package/dist/hono/handlers/app.d.ts +26 -0
- package/dist/hono/handlers/app.js +34 -0
- package/dist/hono/handlers/app.js.map +1 -0
- package/dist/hono/handlers/attachment-stream.d.ts +4 -0
- package/dist/hono/handlers/attachment-stream.js +211 -0
- package/dist/hono/handlers/attachment-stream.js.map +1 -0
- package/dist/hono/handlers/attachment.d.ts +687 -0
- package/dist/hono/handlers/attachment.js +566 -0
- package/dist/hono/handlers/attachment.js.map +1 -0
- package/dist/hono/handlers/autocomplete.d.ts +160 -0
- package/dist/hono/handlers/autocomplete.js +181 -0
- package/dist/hono/handlers/autocomplete.js.map +1 -0
- package/dist/hono/handlers/backlink.d.ts +78 -0
- package/dist/hono/handlers/backlink.js +93 -0
- package/dist/hono/handlers/backlink.js.map +1 -0
- package/dist/hono/handlers/bookmark.d.ts +558 -0
- package/dist/hono/handlers/bookmark.js +166 -0
- package/dist/hono/handlers/bookmark.js.map +1 -0
- package/dist/hono/handlers/comment.d.ts +231 -0
- package/dist/hono/handlers/comment.js +191 -0
- package/dist/hono/handlers/comment.js.map +1 -0
- package/dist/hono/handlers/draft.d.ts +136 -0
- package/dist/hono/handlers/draft.js +191 -0
- package/dist/hono/handlers/draft.js.map +1 -0
- package/dist/hono/handlers/emailChange.d.ts +124 -0
- package/dist/hono/handlers/emailChange.js +79 -0
- package/dist/hono/handlers/emailChange.js.map +1 -0
- package/dist/hono/handlers/installer.d.ts +94 -0
- package/dist/hono/handlers/installer.js +93 -0
- package/dist/hono/handlers/installer.js.map +1 -0
- package/dist/hono/handlers/inviteAccept.d.ts +180 -0
- package/dist/hono/handlers/inviteAccept.js +94 -0
- package/dist/hono/handlers/inviteAccept.js.map +1 -0
- package/dist/hono/handlers/me.d.ts +401 -0
- package/dist/hono/handlers/me.js +390 -0
- package/dist/hono/handlers/me.js.map +1 -0
- package/dist/hono/handlers/notification.d.ts +274 -0
- package/dist/hono/handlers/notification.js +224 -0
- package/dist/hono/handlers/notification.js.map +1 -0
- package/dist/hono/handlers/oauth.d.ts +299 -0
- package/dist/hono/handlers/oauth.js +443 -0
- package/dist/hono/handlers/oauth.js.map +1 -0
- package/dist/hono/handlers/page-collab.d.ts +79 -0
- package/dist/hono/handlers/page-collab.js +98 -0
- package/dist/hono/handlers/page-collab.js.map +1 -0
- package/dist/hono/handlers/page-preview.d.ts +48 -0
- package/dist/hono/handlers/page-preview.js +83 -0
- package/dist/hono/handlers/page-preview.js.map +1 -0
- package/dist/hono/handlers/page.d.ts +2059 -0
- package/dist/hono/handlers/page.js +793 -0
- package/dist/hono/handlers/page.js.map +1 -0
- package/dist/hono/handlers/passwordReset.d.ts +181 -0
- package/dist/hono/handlers/passwordReset.js +101 -0
- package/dist/hono/handlers/passwordReset.js.map +1 -0
- package/dist/hono/handlers/presence.d.ts +178 -0
- package/dist/hono/handlers/presence.js +163 -0
- package/dist/hono/handlers/presence.js.map +1 -0
- package/dist/hono/handlers/revision.d.ts +345 -0
- package/dist/hono/handlers/revision.js +202 -0
- package/dist/hono/handlers/revision.js.map +1 -0
- package/dist/hono/handlers/search.d.ts +208 -0
- package/dist/hono/handlers/search.js +152 -0
- package/dist/hono/handlers/search.js.map +1 -0
- package/dist/hono/handlers/tokenAuth.d.ts +369 -0
- package/dist/hono/handlers/tokenAuth.js +240 -0
- package/dist/hono/handlers/tokenAuth.js.map +1 -0
- package/dist/hono/handlers/user.d.ts +710 -0
- package/dist/hono/handlers/user.js +212 -0
- package/dist/hono/handlers/user.js.map +1 -0
- package/dist/hono/index.d.ts +289 -0
- package/dist/hono/index.js +240 -0
- package/dist/hono/index.js.map +1 -0
- package/dist/hono/middleware/admin.d.ts +5 -0
- package/dist/hono/middleware/admin.js +34 -0
- package/dist/hono/middleware/admin.js.map +1 -0
- package/dist/hono/middleware/auth.d.ts +54 -0
- package/dist/hono/middleware/auth.js +142 -0
- package/dist/hono/middleware/auth.js.map +1 -0
- package/dist/hono/middleware/cors.d.ts +3 -0
- package/dist/hono/middleware/cors.js +86 -0
- package/dist/hono/middleware/cors.js.map +1 -0
- package/dist/hono/middleware/default-hook.d.ts +8 -0
- package/dist/hono/middleware/default-hook.js +17 -0
- package/dist/hono/middleware/default-hook.js.map +1 -0
- package/dist/hono/middleware/error-handler.d.ts +2 -0
- package/dist/hono/middleware/error-handler.js +20 -0
- package/dist/hono/middleware/error-handler.js.map +1 -0
- package/dist/hono/middleware/rate-limit.d.ts +57 -0
- package/dist/hono/middleware/rate-limit.js +42 -0
- package/dist/hono/middleware/rate-limit.js.map +1 -0
- package/dist/hono/middleware/require-scope.d.ts +50 -0
- package/dist/hono/middleware/require-scope.js +64 -0
- package/dist/hono/middleware/require-scope.js.map +1 -0
- package/dist/hono/path-rewrite.d.ts +15 -0
- package/dist/hono/path-rewrite.js +59 -0
- package/dist/hono/path-rewrite.js.map +1 -0
- package/dist/mail/i18n/en.d.ts +2 -0
- package/dist/mail/i18n/en.js +66 -0
- package/dist/mail/i18n/en.js.map +1 -0
- package/dist/mail/i18n/index.d.ts +46 -0
- package/dist/mail/i18n/index.js +31 -0
- package/dist/mail/i18n/index.js.map +1 -0
- package/dist/mail/i18n/ja.d.ts +2 -0
- package/dist/mail/i18n/ja.js +66 -0
- package/dist/mail/i18n/ja.js.map +1 -0
- package/dist/mcp/attach.d.ts +25 -0
- package/dist/mcp/attach.js +104 -0
- package/dist/mcp/attach.js.map +1 -0
- package/dist/mcp/dispatch.d.ts +59 -0
- package/dist/mcp/dispatch.js +70 -0
- package/dist/mcp/dispatch.js.map +1 -0
- package/dist/mcp/result.d.ts +40 -0
- package/dist/mcp/result.js +78 -0
- package/dist/mcp/result.js.map +1 -0
- package/dist/mcp/server.d.ts +67 -0
- package/dist/mcp/server.js +113 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/page.d.ts +2 -0
- package/dist/mcp/tools/page.js +256 -0
- package/dist/mcp/tools/page.js.map +1 -0
- package/dist/mcp/tools/search.d.ts +2 -0
- package/dist/mcp/tools/search.js +36 -0
- package/dist/mcp/tools/search.js.map +1 -0
- package/dist/middlewares/accessTokenParser.d.ts +4 -0
- package/dist/middlewares/accessTokenParser.js +29 -0
- package/dist/middlewares/accessTokenParser.js.map +1 -0
- package/dist/middlewares/adminRequired.d.ts +10 -0
- package/dist/middlewares/adminRequired.js +35 -0
- package/dist/middlewares/adminRequired.js.map +1 -0
- package/dist/middlewares/applicationInstalled.d.ts +3 -0
- package/dist/middlewares/applicationInstalled.js +20 -0
- package/dist/middlewares/applicationInstalled.js.map +1 -0
- package/dist/middlewares/applicationNotInstalled.d.ts +3 -0
- package/dist/middlewares/applicationNotInstalled.js +13 -0
- package/dist/middlewares/applicationNotInstalled.js.map +1 -0
- package/dist/middlewares/basicAuth.d.ts +4 -0
- package/dist/middlewares/basicAuth.js +23 -0
- package/dist/middlewares/basicAuth.js.map +1 -0
- package/dist/middlewares/csrfVerify.d.ts +4 -0
- package/dist/middlewares/csrfVerify.js +24 -0
- package/dist/middlewares/csrfVerify.js.map +1 -0
- package/dist/middlewares/encodeSpace.d.ts +3 -0
- package/dist/middlewares/encodeSpace.js +14 -0
- package/dist/middlewares/encodeSpace.js.map +1 -0
- package/dist/middlewares/fileAccessRightOrLoginRequired.d.ts +4 -0
- package/dist/middlewares/fileAccessRightOrLoginRequired.js +29 -0
- package/dist/middlewares/fileAccessRightOrLoginRequired.js.map +1 -0
- package/dist/middlewares/index.d.ts +16 -0
- package/dist/middlewares/index.js +30 -0
- package/dist/middlewares/index.js.map +1 -0
- package/dist/middlewares/jwtAdminRequired.d.ts +8 -0
- package/dist/middlewares/jwtAdminRequired.js +35 -0
- package/dist/middlewares/jwtAdminRequired.js.map +1 -0
- package/dist/middlewares/jwtAuth.d.ts +4 -0
- package/dist/middlewares/jwtAuth.js +104 -0
- package/dist/middlewares/jwtAuth.js.map +1 -0
- package/dist/middlewares/loginChecker.d.ts +4 -0
- package/dist/middlewares/loginChecker.js +32 -0
- package/dist/middlewares/loginChecker.js.map +1 -0
- package/dist/middlewares/loginRequired.d.ts +4 -0
- package/dist/middlewares/loginRequired.js +88 -0
- package/dist/middlewares/loginRequired.js.map +1 -0
- package/dist/migration/cli-api.d.ts +83 -0
- package/dist/migration/cli-api.js +128 -0
- package/dist/migration/cli-api.js.map +1 -0
- package/dist/migration/migrations/index.d.ts +12 -0
- package/dist/migration/migrations/index.js +24 -0
- package/dist/migration/migrations/index.js.map +1 -0
- package/dist/migration/migrations/page-status-default.d.ts +25 -0
- package/dist/migration/migrations/page-status-default.js +79 -0
- package/dist/migration/migrations/page-status-default.js.map +1 -0
- package/dist/migration/migrations/revisions-schema-unify.d.ts +33 -0
- package/dist/migration/migrations/revisions-schema-unify.js +88 -0
- package/dist/migration/migrations/revisions-schema-unify.js.map +1 -0
- package/dist/migration/migrations/user-unique-prepare.d.ts +1 -0
- package/dist/migration/migrations/user-unique-prepare.js +214 -0
- package/dist/migration/migrations/user-unique-prepare.js.map +1 -0
- package/dist/migration/migrations/wikilink-format.d.ts +97 -0
- package/dist/migration/migrations/wikilink-format.js +418 -0
- package/dist/migration/migrations/wikilink-format.js.map +1 -0
- package/dist/migration/rebuild-api.d.ts +50 -0
- package/dist/migration/rebuild-api.js +45 -0
- package/dist/migration/rebuild-api.js.map +1 -0
- package/dist/migration/rebuild-runner.d.ts +64 -0
- package/dist/migration/rebuild-runner.js +42 -0
- package/dist/migration/rebuild-runner.js.map +1 -0
- package/dist/migration/rebuilds/index.d.ts +26 -0
- package/dist/migration/rebuilds/index.js +69 -0
- package/dist/migration/rebuilds/index.js.map +1 -0
- package/dist/migration/registry.d.ts +15 -0
- package/dist/migration/registry.js +96 -0
- package/dist/migration/registry.js.map +1 -0
- package/dist/migration/run-boot-migrations.d.ts +31 -0
- package/dist/migration/run-boot-migrations.js +95 -0
- package/dist/migration/run-boot-migrations.js.map +1 -0
- package/dist/migration/runner.d.ts +120 -0
- package/dist/migration/runner.js +276 -0
- package/dist/migration/runner.js.map +1 -0
- package/dist/migration/types.d.ts +153 -0
- package/dist/migration/types.js +13 -0
- package/dist/migration/types.js.map +1 -0
- package/dist/models/activity.d.ts +34 -0
- package/dist/models/activity.js +263 -0
- package/dist/models/activity.js.map +1 -0
- package/dist/models/attachment.d.ts +25 -0
- package/dist/models/attachment.js +82 -0
- package/dist/models/attachment.js.map +1 -0
- package/dist/models/backlink.d.ts +19 -0
- package/dist/models/backlink.js +138 -0
- package/dist/models/backlink.js.map +1 -0
- package/dist/models/bookmark.d.ts +28 -0
- package/dist/models/bookmark.js +136 -0
- package/dist/models/bookmark.js.map +1 -0
- package/dist/models/comment.d.ts +21 -0
- package/dist/models/comment.js +87 -0
- package/dist/models/comment.js.map +1 -0
- package/dist/models/config-sensitive.d.ts +21 -0
- package/dist/models/config-sensitive.js +71 -0
- package/dist/models/config-sensitive.js.map +1 -0
- package/dist/models/config.d.ts +34 -0
- package/dist/models/config.js +161 -0
- package/dist/models/config.js.map +1 -0
- package/dist/models/index.d.ts +30 -0
- package/dist/models/index.js +55 -0
- package/dist/models/index.js.map +1 -0
- package/dist/models/migration-application.d.ts +54 -0
- package/dist/models/migration-application.js +36 -0
- package/dist/models/migration-application.js.map +1 -0
- package/dist/models/notification.d.ts +28 -0
- package/dist/models/notification.js +285 -0
- package/dist/models/notification.js.map +1 -0
- package/dist/models/oauth-authorization-code.d.ts +34 -0
- package/dist/models/oauth-authorization-code.js +100 -0
- package/dist/models/oauth-authorization-code.js.map +1 -0
- package/dist/models/oauth-client.d.ts +36 -0
- package/dist/models/oauth-client.js +56 -0
- package/dist/models/oauth-client.js.map +1 -0
- package/dist/models/oauth-device-code.d.ts +55 -0
- package/dist/models/oauth-device-code.js +158 -0
- package/dist/models/oauth-device-code.js.map +1 -0
- package/dist/models/oauth-refresh-token.d.ts +31 -0
- package/dist/models/oauth-refresh-token.js +118 -0
- package/dist/models/oauth-refresh-token.js.map +1 -0
- package/dist/models/page-yjs-update.d.ts +35 -0
- package/dist/models/page-yjs-update.js +33 -0
- package/dist/models/page-yjs-update.js.map +1 -0
- package/dist/models/page.d.ts +200 -0
- package/dist/models/page.js +1117 -0
- package/dist/models/page.js.map +1 -0
- package/dist/models/personal-access-token.d.ts +30 -0
- package/dist/models/personal-access-token.js +107 -0
- package/dist/models/personal-access-token.js.map +1 -0
- package/dist/models/plugin-render-cache.d.ts +40 -0
- package/dist/models/plugin-render-cache.js +39 -0
- package/dist/models/plugin-render-cache.js.map +1 -0
- package/dist/models/revision.d.ts +145 -0
- package/dist/models/revision.js +241 -0
- package/dist/models/revision.js.map +1 -0
- package/dist/models/share.d.ts +38 -0
- package/dist/models/share.js +137 -0
- package/dist/models/share.js.map +1 -0
- package/dist/models/shareAccess.d.ts +20 -0
- package/dist/models/shareAccess.js +45 -0
- package/dist/models/shareAccess.js.map +1 -0
- package/dist/models/tracking.d.ts +14 -0
- package/dist/models/tracking.js +14 -0
- package/dist/models/tracking.js.map +1 -0
- package/dist/models/updatePost.d.ts +25 -0
- package/dist/models/updatePost.js +87 -0
- package/dist/models/updatePost.js.map +1 -0
- package/dist/models/user.d.ts +144 -0
- package/dist/models/user.js +681 -0
- package/dist/models/user.js.map +1 -0
- package/dist/models/watcher.d.ts +23 -0
- package/dist/models/watcher.js +75 -0
- package/dist/models/watcher.js.map +1 -0
- package/dist/notifications/attach.d.ts +63 -0
- package/dist/notifications/attach.js +426 -0
- package/dist/notifications/attach.js.map +1 -0
- package/dist/notifications/channel.d.ts +13 -0
- package/dist/notifications/channel.js +18 -0
- package/dist/notifications/channel.js.map +1 -0
- package/dist/plugin/index.d.ts +2 -0
- package/dist/plugin/index.js +6 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/plugin-context.d.ts +22 -0
- package/dist/plugin/plugin-context.js +126 -0
- package/dist/plugin/plugin-context.js.map +1 -0
- package/dist/plugin/plugin-manager.d.ts +164 -0
- package/dist/plugin/plugin-manager.js +328 -0
- package/dist/plugin/plugin-manager.js.map +1 -0
- package/dist/plugin/plugin-namespace.d.ts +28 -0
- package/dist/plugin/plugin-namespace.js +53 -0
- package/dist/plugin/plugin-namespace.js.map +1 -0
- package/dist/plugin/registries.d.ts +38 -0
- package/dist/plugin/registries.js +71 -0
- package/dist/plugin/registries.js.map +1 -0
- package/dist/plugin/schema-serializer.d.ts +34 -0
- package/dist/plugin/schema-serializer.js +122 -0
- package/dist/plugin/schema-serializer.js.map +1 -0
- package/dist/plugin/topo-sort.d.ts +15 -0
- package/dist/plugin/topo-sort.js +59 -0
- package/dist/plugin/topo-sort.js.map +1 -0
- package/dist/presence/attach.d.ts +36 -0
- package/dist/presence/attach.js +399 -0
- package/dist/presence/attach.js.map +1 -0
- package/dist/renderer/__fixtures__/echo-embed.d.ts +27 -0
- package/dist/renderer/__fixtures__/echo-embed.js +24 -0
- package/dist/renderer/__fixtures__/echo-embed.js.map +1 -0
- package/dist/renderer/cache/index.d.ts +60 -0
- package/dist/renderer/cache/index.js +219 -0
- package/dist/renderer/cache/index.js.map +1 -0
- package/dist/renderer/cache/mongodb-cache.d.ts +82 -0
- package/dist/renderer/cache/mongodb-cache.js +180 -0
- package/dist/renderer/cache/mongodb-cache.js.map +1 -0
- package/dist/renderer/cache/reservation.d.ts +20 -0
- package/dist/renderer/cache/reservation.js +115 -0
- package/dist/renderer/cache/reservation.js.map +1 -0
- package/dist/renderer/core/_mdast-walk.d.ts +35 -0
- package/dist/renderer/core/_mdast-walk.js +45 -0
- package/dist/renderer/core/_mdast-walk.js.map +1 -0
- package/dist/renderer/core/code-block-dispatch.d.ts +31 -0
- package/dist/renderer/core/code-block-dispatch.js +166 -0
- package/dist/renderer/core/code-block-dispatch.js.map +1 -0
- package/dist/renderer/core/code-blocks.d.ts +12 -0
- package/dist/renderer/core/code-blocks.js +32 -0
- package/dist/renderer/core/code-blocks.js.map +1 -0
- package/dist/renderer/core/embed-tags.d.ts +14 -0
- package/dist/renderer/core/embed-tags.js +154 -0
- package/dist/renderer/core/embed-tags.js.map +1 -0
- package/dist/renderer/core/headings.d.ts +16 -0
- package/dist/renderer/core/headings.js +31 -0
- package/dist/renderer/core/headings.js.map +1 -0
- package/dist/renderer/core/index.d.ts +65 -0
- package/dist/renderer/core/index.js +83 -0
- package/dist/renderer/core/index.js.map +1 -0
- package/dist/renderer/core/mention-resolve.d.ts +39 -0
- package/dist/renderer/core/mention-resolve.js +75 -0
- package/dist/renderer/core/mention-resolve.js.map +1 -0
- package/dist/renderer/core/mentions.d.ts +2 -0
- package/dist/renderer/core/mentions.js +83 -0
- package/dist/renderer/core/mentions.js.map +1 -0
- package/dist/renderer/core/syntax-highlight.d.ts +21 -0
- package/dist/renderer/core/syntax-highlight.js +64 -0
- package/dist/renderer/core/syntax-highlight.js.map +1 -0
- package/dist/renderer/core/url-inline-expand.d.ts +9 -0
- package/dist/renderer/core/url-inline-expand.js +157 -0
- package/dist/renderer/core/url-inline-expand.js.map +1 -0
- package/dist/renderer/core/wikilinks.d.ts +2 -0
- package/dist/renderer/core/wikilinks.js +118 -0
- package/dist/renderer/core/wikilinks.js.map +1 -0
- package/dist/renderer/index.d.ts +67 -0
- package/dist/renderer/index.js +99 -0
- package/dist/renderer/index.js.map +1 -0
- package/dist/renderer/pipeline.d.ts +134 -0
- package/dist/renderer/pipeline.js +203 -0
- package/dist/renderer/pipeline.js.map +1 -0
- package/dist/renderer/registry.d.ts +83 -0
- package/dist/renderer/registry.js +130 -0
- package/dist/renderer/registry.js.map +1 -0
- package/dist/renderer/serialize.d.ts +27 -0
- package/dist/renderer/serialize.js +46 -0
- package/dist/renderer/serialize.js.map +1 -0
- package/dist/renderer/version.d.ts +30 -0
- package/dist/renderer/version.js +34 -0
- package/dist/renderer/version.js.map +1 -0
- package/dist/routes/admin.d.ts +4 -0
- package/dist/routes/admin.js +17 -0
- package/dist/routes/admin.js.map +1 -0
- package/dist/routes/api/admin.d.ts +4 -0
- package/dist/routes/api/admin.js +37 -0
- package/dist/routes/api/admin.js.map +1 -0
- package/dist/routes/api/attachment.d.ts +4 -0
- package/dist/routes/api/attachment.js +19 -0
- package/dist/routes/api/attachment.js.map +1 -0
- package/dist/routes/api/bookmark.d.ts +4 -0
- package/dist/routes/api/bookmark.js +15 -0
- package/dist/routes/api/bookmark.js.map +1 -0
- package/dist/routes/api/comment.d.ts +4 -0
- package/dist/routes/api/comment.js +14 -0
- package/dist/routes/api/comment.js.map +1 -0
- package/dist/routes/api/index.d.ts +4 -0
- package/dist/routes/api/index.js +36 -0
- package/dist/routes/api/index.js.map +1 -0
- package/dist/routes/api/like.d.ts +4 -0
- package/dist/routes/api/like.js +13 -0
- package/dist/routes/api/like.js.map +1 -0
- package/dist/routes/api/notification.d.ts +4 -0
- package/dist/routes/api/notification.js +15 -0
- package/dist/routes/api/notification.js.map +1 -0
- package/dist/routes/api/page.d.ts +4 -0
- package/dist/routes/api/page.js +24 -0
- package/dist/routes/api/page.js.map +1 -0
- package/dist/routes/api/revision.d.ts +4 -0
- package/dist/routes/api/revision.js +14 -0
- package/dist/routes/api/revision.js.map +1 -0
- package/dist/routes/api/share.d.ts +4 -0
- package/dist/routes/api/share.js +16 -0
- package/dist/routes/api/share.js.map +1 -0
- package/dist/routes/api/version.d.ts +4 -0
- package/dist/routes/api/version.js +10 -0
- package/dist/routes/api/version.js.map +1 -0
- package/dist/routes/index.d.ts +4 -0
- package/dist/routes/index.js +71 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/login.d.ts +4 -0
- package/dist/routes/login.js +18 -0
- package/dist/routes/login.js.map +1 -0
- package/dist/routes/me.d.ts +4 -0
- package/dist/routes/me.js +24 -0
- package/dist/routes/me.js.map +1 -0
- package/dist/routes/ts-rest/admin/app.d.ts +4 -0
- package/dist/routes/ts-rest/admin/app.js +67 -0
- package/dist/routes/ts-rest/admin/app.js.map +1 -0
- package/dist/routes/ts-rest/admin/auth.d.ts +4 -0
- package/dist/routes/ts-rest/admin/auth.js +95 -0
- package/dist/routes/ts-rest/admin/auth.js.map +1 -0
- package/dist/routes/ts-rest/admin/index.d.ts +10 -0
- package/dist/routes/ts-rest/admin/index.js +35 -0
- package/dist/routes/ts-rest/admin/index.js.map +1 -0
- package/dist/routes/ts-rest/admin/mail.d.ts +4 -0
- package/dist/routes/ts-rest/admin/mail.js +156 -0
- package/dist/routes/ts-rest/admin/mail.js.map +1 -0
- package/dist/routes/ts-rest/admin/plugins.d.ts +4 -0
- package/dist/routes/ts-rest/admin/plugins.js +317 -0
- package/dist/routes/ts-rest/admin/plugins.js.map +1 -0
- package/dist/routes/ts-rest/admin/search.d.ts +4 -0
- package/dist/routes/ts-rest/admin/search.js +67 -0
- package/dist/routes/ts-rest/admin/search.js.map +1 -0
- package/dist/routes/ts-rest/admin/security.d.ts +4 -0
- package/dist/routes/ts-rest/admin/security.js +114 -0
- package/dist/routes/ts-rest/admin/security.js.map +1 -0
- package/dist/routes/ts-rest/admin/share.d.ts +4 -0
- package/dist/routes/ts-rest/admin/share.js +69 -0
- package/dist/routes/ts-rest/admin/share.js.map +1 -0
- package/dist/routes/ts-rest/admin/storage.d.ts +4 -0
- package/dist/routes/ts-rest/admin/storage.js +59 -0
- package/dist/routes/ts-rest/admin/storage.js.map +1 -0
- package/dist/routes/ts-rest/admin/users.d.ts +4 -0
- package/dist/routes/ts-rest/admin/users.js +215 -0
- package/dist/routes/ts-rest/admin/users.js.map +1 -0
- package/dist/routes/ts-rest/adminCrypto.d.ts +4 -0
- package/dist/routes/ts-rest/adminCrypto.js +111 -0
- package/dist/routes/ts-rest/adminCrypto.js.map +1 -0
- package/dist/routes/ts-rest/app.d.ts +4 -0
- package/dist/routes/ts-rest/app.js +23 -0
- package/dist/routes/ts-rest/app.js.map +1 -0
- package/dist/routes/ts-rest/attachment.d.ts +4 -0
- package/dist/routes/ts-rest/attachment.js +830 -0
- package/dist/routes/ts-rest/attachment.js.map +1 -0
- package/dist/routes/ts-rest/auth.d.ts +4 -0
- package/dist/routes/ts-rest/auth.js +70 -0
- package/dist/routes/ts-rest/auth.js.map +1 -0
- package/dist/routes/ts-rest/autocomplete.d.ts +30 -0
- package/dist/routes/ts-rest/autocomplete.js +189 -0
- package/dist/routes/ts-rest/autocomplete.js.map +1 -0
- package/dist/routes/ts-rest/backlink.d.ts +4 -0
- package/dist/routes/ts-rest/backlink.js +106 -0
- package/dist/routes/ts-rest/backlink.js.map +1 -0
- package/dist/routes/ts-rest/bookmark.d.ts +4 -0
- package/dist/routes/ts-rest/bookmark.js +189 -0
- package/dist/routes/ts-rest/bookmark.js.map +1 -0
- package/dist/routes/ts-rest/comment.d.ts +4 -0
- package/dist/routes/ts-rest/comment.js +217 -0
- package/dist/routes/ts-rest/comment.js.map +1 -0
- package/dist/routes/ts-rest/draft.d.ts +22 -0
- package/dist/routes/ts-rest/draft.js +200 -0
- package/dist/routes/ts-rest/draft.js.map +1 -0
- package/dist/routes/ts-rest/index.d.ts +4 -0
- package/dist/routes/ts-rest/index.js +103 -0
- package/dist/routes/ts-rest/index.js.map +1 -0
- package/dist/routes/ts-rest/installer.d.ts +4 -0
- package/dist/routes/ts-rest/installer.js +77 -0
- package/dist/routes/ts-rest/installer.js.map +1 -0
- package/dist/routes/ts-rest/me.d.ts +4 -0
- package/dist/routes/ts-rest/me.js +410 -0
- package/dist/routes/ts-rest/me.js.map +1 -0
- package/dist/routes/ts-rest/notification.d.ts +4 -0
- package/dist/routes/ts-rest/notification.js +241 -0
- package/dist/routes/ts-rest/notification.js.map +1 -0
- package/dist/routes/ts-rest/page-collab.d.ts +29 -0
- package/dist/routes/ts-rest/page-collab.js +90 -0
- package/dist/routes/ts-rest/page-collab.js.map +1 -0
- package/dist/routes/ts-rest/page-preview.d.ts +26 -0
- package/dist/routes/ts-rest/page-preview.js +80 -0
- package/dist/routes/ts-rest/page-preview.js.map +1 -0
- package/dist/routes/ts-rest/page.d.ts +4 -0
- package/dist/routes/ts-rest/page.js +676 -0
- package/dist/routes/ts-rest/page.js.map +1 -0
- package/dist/routes/ts-rest/presence.d.ts +30 -0
- package/dist/routes/ts-rest/presence.js +155 -0
- package/dist/routes/ts-rest/presence.js.map +1 -0
- package/dist/routes/ts-rest/revision.d.ts +4 -0
- package/dist/routes/ts-rest/revision.js +240 -0
- package/dist/routes/ts-rest/revision.js.map +1 -0
- package/dist/routes/ts-rest/search.d.ts +4 -0
- package/dist/routes/ts-rest/search.js +121 -0
- package/dist/routes/ts-rest/search.js.map +1 -0
- package/dist/routes/ts-rest/tokenAuth.d.ts +4 -0
- package/dist/routes/ts-rest/tokenAuth.js +94 -0
- package/dist/routes/ts-rest/tokenAuth.js.map +1 -0
- package/dist/routes/ts-rest/user.d.ts +4 -0
- package/dist/routes/ts-rest/user.js +307 -0
- package/dist/routes/ts-rest/user.js.map +1 -0
- package/dist/service/config.d.ts +50 -0
- package/dist/service/config.js +202 -0
- package/dist/service/config.js.map +1 -0
- package/dist/service/lru.d.ts +11 -0
- package/dist/service/lru.js +47 -0
- package/dist/service/lru.js.map +1 -0
- package/dist/service/mail.d.ts +107 -0
- package/dist/service/mail.js +220 -0
- package/dist/service/mail.js.map +1 -0
- package/dist/service/notification.d.ts +9 -0
- package/dist/service/notification.js +19 -0
- package/dist/service/notification.js.map +1 -0
- package/dist/service/presence.d.ts +219 -0
- package/dist/service/presence.js +602 -0
- package/dist/service/presence.js.map +1 -0
- package/dist/types/error.d.ts +13 -0
- package/dist/types/error.js +13 -0
- package/dist/types/error.js.map +1 -0
- package/dist/types/express.d.ts +34 -0
- package/dist/types/express.js +50 -0
- package/dist/types/express.js.map +1 -0
- package/dist/types/mongoose-extensions.d.ts +8 -0
- package/dist/types/mongoose-extensions.js +24 -0
- package/dist/types/mongoose-extensions.js.map +1 -0
- package/dist/util/accessTokenParser.d.ts +1 -0
- package/dist/util/accessTokenParser.js +34 -0
- package/dist/util/accessTokenParser.js.map +1 -0
- package/dist/util/activityDefine.d.ts +15 -0
- package/dist/util/activityDefine.js +52 -0
- package/dist/util/activityDefine.js.map +1 -0
- package/dist/util/admin-config.d.ts +57 -0
- package/dist/util/admin-config.js +99 -0
- package/dist/util/admin-config.js.map +1 -0
- package/dist/util/admin-pager.d.ts +24 -0
- package/dist/util/admin-pager.js +73 -0
- package/dist/util/admin-pager.js.map +1 -0
- package/dist/util/apiPaginate.d.ts +11 -0
- package/dist/util/apiPaginate.js +33 -0
- package/dist/util/apiPaginate.js.map +1 -0
- package/dist/util/apiResponse.d.ts +9 -0
- package/dist/util/apiResponse.js +23 -0
- package/dist/util/apiResponse.js.map +1 -0
- package/dist/util/auth.d.ts +11 -0
- package/dist/util/auth.js +48 -0
- package/dist/util/auth.js.map +1 -0
- package/dist/util/auto-watch.d.ts +35 -0
- package/dist/util/auto-watch.js +24 -0
- package/dist/util/auto-watch.js.map +1 -0
- package/dist/util/autocomplete-match.d.ts +44 -0
- package/dist/util/autocomplete-match.js +80 -0
- package/dist/util/autocomplete-match.js.map +1 -0
- package/dist/util/aws-config-migration.d.ts +11 -0
- package/dist/util/aws-config-migration.js +68 -0
- package/dist/util/aws-config-migration.js.map +1 -0
- package/dist/util/boot-reporter.d.ts +130 -0
- package/dist/util/boot-reporter.js +242 -0
- package/dist/util/boot-reporter.js.map +1 -0
- package/dist/util/collab-cap.d.ts +39 -0
- package/dist/util/collab-cap.js +90 -0
- package/dist/util/collab-cap.js.map +1 -0
- package/dist/util/crypto.d.ts +39 -0
- package/dist/util/crypto.js +105 -0
- package/dist/util/crypto.js.map +1 -0
- package/dist/util/dedup-users.d.ts +96 -0
- package/dist/util/dedup-users.js +149 -0
- package/dist/util/dedup-users.js.map +1 -0
- package/dist/util/editor-cap-counter.d.ts +90 -0
- package/dist/util/editor-cap-counter.js +175 -0
- package/dist/util/editor-cap-counter.js.map +1 -0
- package/dist/util/fileUploader.d.ts +55 -0
- package/dist/util/fileUploader.js +70 -0
- package/dist/util/fileUploader.js.map +1 -0
- package/dist/util/formUtil.d.ts +2 -0
- package/dist/util/formUtil.js +15 -0
- package/dist/util/formUtil.js.map +1 -0
- package/dist/util/githubAuth.d.ts +2 -0
- package/dist/util/githubAuth.js +82 -0
- package/dist/util/githubAuth.js.map +1 -0
- package/dist/util/googleAuth.d.ts +2 -0
- package/dist/util/googleAuth.js +85 -0
- package/dist/util/googleAuth.js.map +1 -0
- package/dist/util/jwt.d.ts +50 -0
- package/dist/util/jwt.js +127 -0
- package/dist/util/jwt.js.map +1 -0
- package/dist/util/linkDetector.d.ts +3 -0
- package/dist/util/linkDetector.js +91 -0
- package/dist/util/linkDetector.js.map +1 -0
- package/dist/util/mail-token.d.ts +24 -0
- package/dist/util/mail-token.js +117 -0
- package/dist/util/mail-token.js.map +1 -0
- package/dist/util/mailer.d.ts +7 -0
- package/dist/util/mailer.js +98 -0
- package/dist/util/mailer.js.map +1 -0
- package/dist/util/map-duplicate-key-error.d.ts +26 -0
- package/dist/util/map-duplicate-key-error.js +41 -0
- package/dist/util/map-duplicate-key-error.js.map +1 -0
- package/dist/util/mongoose-paginate.d.ts +10 -0
- package/dist/util/mongoose-paginate.js +23 -0
- package/dist/util/mongoose-paginate.js.map +1 -0
- package/dist/util/notifications-token.d.ts +35 -0
- package/dist/util/notifications-token.js +140 -0
- package/dist/util/notifications-token.js.map +1 -0
- package/dist/util/oauth-client-seed.d.ts +2 -0
- package/dist/util/oauth-client-seed.js +48 -0
- package/dist/util/oauth-client-seed.js.map +1 -0
- package/dist/util/oauth-redirect-uri.d.ts +2 -0
- package/dist/util/oauth-redirect-uri.js +55 -0
- package/dist/util/oauth-redirect-uri.js.map +1 -0
- package/dist/util/page-response.d.ts +113 -0
- package/dist/util/page-response.js +154 -0
- package/dist/util/page-response.js.map +1 -0
- package/dist/util/page-search-index.d.ts +19 -0
- package/dist/util/page-search-index.js +91 -0
- package/dist/util/page-search-index.js.map +1 -0
- package/dist/util/page-status-migration.d.ts +23 -0
- package/dist/util/page-status-migration.js +48 -0
- package/dist/util/page-status-migration.js.map +1 -0
- package/dist/util/path.d.ts +2 -0
- package/dist/util/path.js +12 -0
- package/dist/util/path.js.map +1 -0
- package/dist/util/pkce.d.ts +13 -0
- package/dist/util/pkce.js +30 -0
- package/dist/util/pkce.js.map +1 -0
- package/dist/util/presence-token.d.ts +21 -0
- package/dist/util/presence-token.js +120 -0
- package/dist/util/presence-token.js.map +1 -0
- package/dist/util/rate-limit.d.ts +67 -0
- package/dist/util/rate-limit.js +87 -0
- package/dist/util/rate-limit.js.map +1 -0
- package/dist/util/rebuild-backlink.d.ts +25 -0
- package/dist/util/rebuild-backlink.js +7 -0
- package/dist/util/rebuild-backlink.js.map +1 -0
- package/dist/util/rebuild-renderer.d.ts +31 -0
- package/dist/util/rebuild-renderer.js +7 -0
- package/dist/util/rebuild-renderer.js.map +1 -0
- package/dist/util/redis-opts.d.ts +17 -0
- package/dist/util/redis-opts.js +40 -0
- package/dist/util/redis-opts.js.map +1 -0
- package/dist/util/regex.d.ts +2 -0
- package/dist/util/regex.js +8 -0
- package/dist/util/regex.js.map +1 -0
- package/dist/util/search-rebuild.d.ts +18 -0
- package/dist/util/search-rebuild.js +28 -0
- package/dist/util/search-rebuild.js.map +1 -0
- package/dist/util/ssr.d.ts +3 -0
- package/dist/util/ssr.js +9 -0
- package/dist/util/ssr.js.map +1 -0
- package/dist/util/storage-copy.d.ts +40 -0
- package/dist/util/storage-copy.js +123 -0
- package/dist/util/storage-copy.js.map +1 -0
- package/dist/util/ts-rest-helpers.d.ts +110 -0
- package/dist/util/ts-rest-helpers.js +110 -0
- package/dist/util/ts-rest-helpers.js.map +1 -0
- package/dist/util/url.d.ts +1 -0
- package/dist/util/url.js +11 -0
- package/dist/util/url.js.map +1 -0
- package/dist/util/user-code.d.ts +10 -0
- package/dist/util/user-code.js +55 -0
- package/dist/util/user-code.js.map +1 -0
- package/dist/util/view.d.ts +10 -0
- package/dist/util/view.js +99 -0
- package/dist/util/view.js.map +1 -0
- package/dist/util/watcher-backfill.d.ts +30 -0
- package/dist/util/watcher-backfill.js +43 -0
- package/dist/util/watcher-backfill.js.map +1 -0
- package/dist/util/ws-token.d.ts +24 -0
- package/dist/util/ws-token.js +134 -0
- package/dist/util/ws-token.js.map +1 -0
- package/package.json +106 -0
|
@@ -0,0 +1,793 @@
|
|
|
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
|
+
exports.registerPageRoutes = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* RFC-0006 Phase 4 Batch 4 — `page` resource Hono port.
|
|
9
|
+
*
|
|
10
|
+
* Replaces `packages/api/src/routes/ts-rest/page.ts`. 14 endpoints —
|
|
11
|
+
* the largest single resource in the API. Wire-format parity with the
|
|
12
|
+
* ts-rest era is preserved byte-for-byte (response shapes, error
|
|
13
|
+
* envelopes, status codes, idempotency / leak-guard semantics).
|
|
14
|
+
*
|
|
15
|
+
* **jwtAuth ownership** (important):
|
|
16
|
+
*
|
|
17
|
+
* The `revision` handler already installs
|
|
18
|
+
* app.use('/pages/*', createJwtAuth(crowi));
|
|
19
|
+
* app.use('/pages', createJwtAuth(crowi));
|
|
20
|
+
* on the shared chain (see
|
|
21
|
+
* `packages/api/src/hono/handlers/revision.ts`). Hono does NOT dedupe
|
|
22
|
+
* middleware by reference — re-installing the same factory output on
|
|
23
|
+
* the same prefix would run JWT verify + `User.findById` twice per
|
|
24
|
+
* request. The page handler relies on the revision handler having
|
|
25
|
+
* registered first in `buildHonoApp`, and does NOT install jwtAuth
|
|
26
|
+
* itself. Phase 6 will revisit this implicit ordering when the
|
|
27
|
+
* Express bridge is removed.
|
|
28
|
+
*/
|
|
29
|
+
const api_contract_1 = require("@crowi/api-contract");
|
|
30
|
+
const debug_1 = __importDefault(require("debug"));
|
|
31
|
+
const page_1 = require("../../models/page");
|
|
32
|
+
const page_response_1 = require("../../util/page-response");
|
|
33
|
+
const ts_rest_helpers_1 = require("../../util/ts-rest-helpers");
|
|
34
|
+
const require_scope_1 = require("../middleware/require-scope");
|
|
35
|
+
const errors_1 = require("./_helpers/errors");
|
|
36
|
+
const debug = (0, debug_1.default)('crowi:hono:handlers:page');
|
|
37
|
+
const VALID_GRANTS = Object.values(api_contract_1.PageGrantEnum);
|
|
38
|
+
const PAGE_NOT_GRANTED_BODY = {
|
|
39
|
+
error: { code: 'PAGE_NOT_GRANTED', message: 'Page is not granted for the user' },
|
|
40
|
+
};
|
|
41
|
+
const INVALID_GRANT_BODY = {
|
|
42
|
+
error: {
|
|
43
|
+
code: 'INVALID_GRANT',
|
|
44
|
+
message: 'grant must be one of 1 (public), 2 (restricted), 3 (specified), 4 (owner)',
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
// Build a 400 PAGE_* envelope without losing the literal narrowing on
|
|
48
|
+
// the `code` field (the contract widens `code` to `z.string()` for this
|
|
49
|
+
// resource so the helper keeps it simple).
|
|
50
|
+
const pageBadRequestBody = (code, message) => ({
|
|
51
|
+
error: { code, message },
|
|
52
|
+
});
|
|
53
|
+
const pageRevisionConflictBody = () => ({
|
|
54
|
+
error: { code: 'PAGE_REVISION_ERROR', message: 'Revision error.' },
|
|
55
|
+
});
|
|
56
|
+
// Structured 400 body shared by both subtree-rename paths (page_id-based and
|
|
57
|
+
// path-based). `partial: true` marks a mid-execution best-effort failure.
|
|
58
|
+
const renameTreeFailedBody = (message, conflicts, partial) => ({
|
|
59
|
+
error: { code: 'PAGE_RENAME_TREE_FAILED', message, conflicts, ...(partial ? { partial } : {}) },
|
|
60
|
+
});
|
|
61
|
+
/** `checkPagesRenamable`'s per-path error map → the non-empty `conflicts[]`. */
|
|
62
|
+
const toConflicts = (errorsByPath) => Object.entries(errorsByPath)
|
|
63
|
+
.filter(([, reasons]) => reasons.length > 0)
|
|
64
|
+
.map(([path, reasons]) => ({ path, reasons }));
|
|
65
|
+
const registerPageRoutes = (app, crowi) => {
|
|
66
|
+
const Page = crowi.model('Page');
|
|
67
|
+
const User = crowi.model('User');
|
|
68
|
+
const Watcher = crowi.model('Watcher');
|
|
69
|
+
// RFC-0010 — per-route scope guards (web sessions hold all scopes, so
|
|
70
|
+
// these only narrow OAuth tokens). Registered before the openapi
|
|
71
|
+
// handlers below so the guard runs first on a matching method + path.
|
|
72
|
+
//
|
|
73
|
+
// `seen` is a *view* side-effect (recording who looked at a page), so
|
|
74
|
+
// it is `pages:read`, not write — matching the read-oriented intent of
|
|
75
|
+
// marking a page seen. `like` / `unlike` / `watch` mutate per-user
|
|
76
|
+
// page relations and are `pages:write`.
|
|
77
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.getPageRoute, 'pages:read');
|
|
78
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.listPagesRoute, 'pages:read');
|
|
79
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.listPageChildrenRoute, 'pages:read');
|
|
80
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.getSeenUsersRoute, 'pages:read');
|
|
81
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.getWatchStatusRoute, 'pages:read');
|
|
82
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.seenPageRoute, 'pages:read');
|
|
83
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.createPageRoute, 'pages:write');
|
|
84
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.updatePageRoute, 'pages:write');
|
|
85
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.setPageGrantRoute, 'pages:write');
|
|
86
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.likePageRoute, 'pages:write');
|
|
87
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.unlikePageRoute, 'pages:write');
|
|
88
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.setWatchStatusRoute, 'pages:write');
|
|
89
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.deletePageRoute, 'pages:write');
|
|
90
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.revertDeletedPageRoute, 'pages:write');
|
|
91
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.renamePageRoute, 'pages:write');
|
|
92
|
+
(0, require_scope_1.applyScope)(app, api_contract_1.renameSubtreeRoute, 'pages:write');
|
|
93
|
+
/**
|
|
94
|
+
* Build the seen-users response. `seenUsersCount` reflects the full
|
|
95
|
+
* raw id-array length (matching the legacy `populatePageData`) so
|
|
96
|
+
* inactive users dropped by `findUsersByIds`' status filter do not
|
|
97
|
+
* deflate the count. `limit` only caps the returned `seenUsers` list.
|
|
98
|
+
*/
|
|
99
|
+
const buildSeenUsersResponse = async (seenUserIds, limit) => {
|
|
100
|
+
const ids = seenUserIds.filter((id) => id != null);
|
|
101
|
+
const seenUsersCount = ids.length;
|
|
102
|
+
if (ids.length === 0) {
|
|
103
|
+
return { seenUsers: [], seenUsersCount };
|
|
104
|
+
}
|
|
105
|
+
const idsToFetch = limit !== undefined ? ids.slice(0, limit) : ids;
|
|
106
|
+
const populated = (await User.findUsersByIds(idsToFetch));
|
|
107
|
+
return {
|
|
108
|
+
seenUsers: populated.map(ts_rest_helpers_1.toUserPublic),
|
|
109
|
+
seenUsersCount,
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
return (app
|
|
113
|
+
// --------------------------------------------------------------
|
|
114
|
+
// GET /pages — getPage (path-or-id)
|
|
115
|
+
// --------------------------------------------------------------
|
|
116
|
+
.openapi(api_contract_1.getPageRoute, async (c) => {
|
|
117
|
+
const user = c.get('user');
|
|
118
|
+
const { path, page_id, revision_id } = c.req.valid('query');
|
|
119
|
+
debug('getPage called with:', { path, page_id, revision_id, userId: user._id });
|
|
120
|
+
if (!path && !page_id) {
|
|
121
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
let page = null;
|
|
125
|
+
// page_id takes precedence over path (legacy controller order).
|
|
126
|
+
if (page_id) {
|
|
127
|
+
page = await Page.findPageByIdAndGrantedUser(page_id, user);
|
|
128
|
+
}
|
|
129
|
+
else if (path) {
|
|
130
|
+
page = await Page.findPage(path, user, revision_id || null);
|
|
131
|
+
}
|
|
132
|
+
if (!page) {
|
|
133
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
134
|
+
}
|
|
135
|
+
const pageResponse = (0, page_response_1.pageToResponse)(page, { withMeta: true, withRenderedAst: true });
|
|
136
|
+
// On-the-fly fallback for legacy revisions — one pipeline run
|
|
137
|
+
// produces both meta + renderedAst, stored values win on merge.
|
|
138
|
+
if (pageResponse.revision && (0, page_response_1.isPopulatedRevision)(page.revision)) {
|
|
139
|
+
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());
|
|
140
|
+
pageResponse.revision.meta = meta;
|
|
141
|
+
pageResponse.revision.renderedAst = renderedAst;
|
|
142
|
+
}
|
|
143
|
+
// Fire-and-forget recently-viewed touch — Redis hiccups must
|
|
144
|
+
// not block the page read.
|
|
145
|
+
crowi.lru.add(user._id.toString(), page._id.toString())?.catch?.((err) => {
|
|
146
|
+
debug('lru.add failed (non-fatal):', err);
|
|
147
|
+
});
|
|
148
|
+
return c.json({ page: pageResponse }, 200);
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
const error = err;
|
|
152
|
+
debug('Error fetching page:', error.message);
|
|
153
|
+
if (error.message === 'Page not found' || error.name === 'Crowi:Page:NotFound') {
|
|
154
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
155
|
+
}
|
|
156
|
+
if (error.message === 'Page is not granted for the user') {
|
|
157
|
+
return c.json(PAGE_NOT_GRANTED_BODY, 403);
|
|
158
|
+
}
|
|
159
|
+
// Legacy fallback — unknown errors collapse to PAGE_NOT_FOUND.
|
|
160
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
// --------------------------------------------------------------
|
|
164
|
+
// GET /pages/list — listPages
|
|
165
|
+
// --------------------------------------------------------------
|
|
166
|
+
.openapi(api_contract_1.listPagesRoute, async (c) => {
|
|
167
|
+
const user = c.get('user');
|
|
168
|
+
const { path, user: userParam, limit, offset, include_deleted, sort, order } = c.req.valid('query');
|
|
169
|
+
// Mongoose sort direction: 1 ascending, -1 descending.
|
|
170
|
+
const sortDir = order === 'asc' ? 1 : -1;
|
|
171
|
+
// Force-enable include_deleted for /trash and /trash/<sub> requests so
|
|
172
|
+
// the legacy deletedPageListShow semantics are preserved even when
|
|
173
|
+
// the client omits the query flag.
|
|
174
|
+
const isTrashPath = !!path && (path === '/trash' || path.startsWith('/trash/'));
|
|
175
|
+
const includeDeletedPage = include_deleted || isTrashPath;
|
|
176
|
+
debug('listPages called with:', { path, user: userParam, limit, offset, includeDeletedPage, userId: user._id });
|
|
177
|
+
try {
|
|
178
|
+
let pages = [];
|
|
179
|
+
let portalPage = null;
|
|
180
|
+
if (userParam) {
|
|
181
|
+
// List pages by creator.
|
|
182
|
+
const targetUser = await User.findById(userParam);
|
|
183
|
+
if (!targetUser) {
|
|
184
|
+
return c.json({
|
|
185
|
+
pages: [],
|
|
186
|
+
pager: { prev: null, next: null, offset: 0 },
|
|
187
|
+
portalPage: null,
|
|
188
|
+
}, 200);
|
|
189
|
+
}
|
|
190
|
+
// The creator listing keeps its own createdAt-desc order
|
|
191
|
+
// (the profile surface has no sort control); the `sort`/`order`
|
|
192
|
+
// query only drives the path + root directory listings below.
|
|
193
|
+
const rawPages = await Page.findListByCreator(targetUser, { limit, offset }, user);
|
|
194
|
+
pages = (await Page.populate(rawPages, [{ path: 'creator' }, { path: 'lastUpdateUser' }]));
|
|
195
|
+
}
|
|
196
|
+
else if (path && path !== '/') {
|
|
197
|
+
// List pages by path. /trash subtrees skip findPortalPage to
|
|
198
|
+
// mirror the legacy deletedPageListShow which always rendered
|
|
199
|
+
// with page=null.
|
|
200
|
+
const portalPagePromise = isTrashPath ? Promise.resolve(null) : Page.findPortalPage(path, user);
|
|
201
|
+
const listPromise = Page.findListByStartWith(path, user, { limit, offset, includeDeletedPage, sort, desc: sortDir });
|
|
202
|
+
const [rawPortalPage, rawPages] = await Promise.all([portalPagePromise, listPromise]);
|
|
203
|
+
[portalPage, pages] = (await Promise.all([
|
|
204
|
+
rawPortalPage ? Page.populate(rawPortalPage, [{ path: 'creator' }, { path: 'lastUpdateUser' }]) : null,
|
|
205
|
+
Page.populate(rawPages, [{ path: 'creator' }, { path: 'lastUpdateUser' }]),
|
|
206
|
+
]));
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
// List all pages the user can access (including path='/').
|
|
210
|
+
//
|
|
211
|
+
// Both visibility predicates come from the Page model:
|
|
212
|
+
// visiblePageStatusOr — published + the viewer's own drafts
|
|
213
|
+
// visiblePageGrantOr — public + restricted/specified/owner
|
|
214
|
+
// pages where the viewer is in
|
|
215
|
+
// grantedUsers
|
|
216
|
+
//
|
|
217
|
+
// Previously this branch hard-coded `grant: { $in: [1, 2] }`,
|
|
218
|
+
// which (a) silently dropped GRANT_OWNER and GRANT_SPECIFIED
|
|
219
|
+
// pages the viewer creates or is granted, and (b) leaked
|
|
220
|
+
// GRANT_RESTRICTED pages to non-members because the
|
|
221
|
+
// grantedUsers check was missing. Replacing both predicates
|
|
222
|
+
// with the model helpers keeps the path-based and root /
|
|
223
|
+
// no-path branches consistent.
|
|
224
|
+
//
|
|
225
|
+
// include_deleted: when set (or when isTrashPath forced it),
|
|
226
|
+
// omit the status filter entirely — mirrors
|
|
227
|
+
// `findListByStartWith`, which adds visiblePageStatusOr only
|
|
228
|
+
// in the `!includeDeletedPage` branch. Without this the root
|
|
229
|
+
// branch would silently ignore the flag (the status helper
|
|
230
|
+
// never emits STATUS_DELETED).
|
|
231
|
+
const andClauses = [{ $or: (0, page_1.visiblePageGrantOr)(user._id) }];
|
|
232
|
+
if (!includeDeletedPage) {
|
|
233
|
+
andClauses.push({ $or: (0, page_1.visiblePageStatusOr)(user._id) });
|
|
234
|
+
}
|
|
235
|
+
const conditions = {
|
|
236
|
+
redirectTo: null,
|
|
237
|
+
$and: andClauses,
|
|
238
|
+
};
|
|
239
|
+
if (path === '/') {
|
|
240
|
+
[portalPage, pages] = await Promise.all([
|
|
241
|
+
Page.findPortalPage(path, user),
|
|
242
|
+
Page.find(conditions)
|
|
243
|
+
.sort({ [sort]: sortDir })
|
|
244
|
+
.skip(offset)
|
|
245
|
+
.limit(limit)
|
|
246
|
+
.populate({ path: 'revision', populate: { path: 'author' } })
|
|
247
|
+
.populate('creator')
|
|
248
|
+
.populate('lastUpdateUser')
|
|
249
|
+
.exec(),
|
|
250
|
+
]);
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
pages = await Page.find(conditions)
|
|
254
|
+
.sort({ [sort]: sortDir })
|
|
255
|
+
.skip(offset)
|
|
256
|
+
.limit(limit)
|
|
257
|
+
.populate({ path: 'revision', populate: { path: 'author' } })
|
|
258
|
+
.populate('creator')
|
|
259
|
+
.populate('lastUpdateUser')
|
|
260
|
+
.exec();
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
// The portal document of the listed path is surfaced separately
|
|
264
|
+
// as `portalPage` (rendered as the portal card / fallback
|
|
265
|
+
// header), so drop it from the child rows. `findListByStartWith`
|
|
266
|
+
// matches `^{path}` which includes the `{path}` portal itself; a
|
|
267
|
+
// duplicate row is redundant and its link is a no-op (it's the
|
|
268
|
+
// page you're already on). Matches by id so a draft portal is
|
|
269
|
+
// dropped too.
|
|
270
|
+
if (portalPage) {
|
|
271
|
+
const portalId = String(portalPage._id);
|
|
272
|
+
pages = pages.filter((page) => String(page._id) !== portalId);
|
|
273
|
+
}
|
|
274
|
+
const pageResponses = pages.map((page) => (0, page_response_1.pageToResponse)(page));
|
|
275
|
+
// The portal document is rendered as a full page (PageContent)
|
|
276
|
+
// by the web client, so — unlike the list rows — it needs
|
|
277
|
+
// `renderedAst`. Mirror the getPage detail path: emit meta +
|
|
278
|
+
// renderedAst and run the on-the-fly fallback so legacy /
|
|
279
|
+
// version-mismatched revisions still render instead of getting
|
|
280
|
+
// stuck on the "Rendering…" placeholder. List rows stay lean
|
|
281
|
+
// (no renderedAst) as before.
|
|
282
|
+
const portalPageResponse = portalPage ? (0, page_response_1.pageToResponse)(portalPage, { withMeta: true, withRenderedAst: true }) : null;
|
|
283
|
+
if (portalPageResponse?.revision && portalPage && (0, page_response_1.isPopulatedRevision)(portalPage.revision)) {
|
|
284
|
+
const { meta, renderedAst } = await (0, page_response_1.computeRevisionRenderArtifactsAsync)(crowi, portalPage.revision.meta, portalPage.revision.renderedAst, portalPage.revision.body, portalPage.revision.rendererVersion, portalPage._id?.toString());
|
|
285
|
+
portalPageResponse.revision.meta = meta;
|
|
286
|
+
portalPageResponse.revision.renderedAst = renderedAst;
|
|
287
|
+
}
|
|
288
|
+
const prev = offset > 0 ? Math.max(0, offset - limit) : null;
|
|
289
|
+
const next = pages.length === limit ? offset + limit : null;
|
|
290
|
+
return c.json({
|
|
291
|
+
pages: pageResponses,
|
|
292
|
+
pager: { prev, next, offset },
|
|
293
|
+
portalPage: portalPageResponse,
|
|
294
|
+
}, 200);
|
|
295
|
+
}
|
|
296
|
+
catch (err) {
|
|
297
|
+
debug('Error listing pages:', err.message);
|
|
298
|
+
// Legacy behaviour: an unexpected error collapses to an empty
|
|
299
|
+
// list rather than 500. Preserved for wire compatibility.
|
|
300
|
+
return c.json({
|
|
301
|
+
pages: [],
|
|
302
|
+
pager: { prev: null, next: null, offset: 0 },
|
|
303
|
+
portalPage: null,
|
|
304
|
+
}, 200);
|
|
305
|
+
}
|
|
306
|
+
})
|
|
307
|
+
// --------------------------------------------------------------
|
|
308
|
+
// GET /pages/children — listPageChildren (sidebar tree)
|
|
309
|
+
// --------------------------------------------------------------
|
|
310
|
+
.openapi(api_contract_1.listPageChildrenRoute, async (c) => {
|
|
311
|
+
const user = c.get('user');
|
|
312
|
+
const { path } = c.req.valid('query');
|
|
313
|
+
debug('listPageChildren called with:', { path, userId: user._id });
|
|
314
|
+
try {
|
|
315
|
+
const children = await Page.findChildSegments(path, user);
|
|
316
|
+
return c.json({ children }, 200);
|
|
317
|
+
}
|
|
318
|
+
catch (err) {
|
|
319
|
+
// Mirror listPages: a scan error collapses to an empty tree
|
|
320
|
+
// rather than 500 — the sidebar is non-critical chrome.
|
|
321
|
+
debug('Error listing page children:', err.message);
|
|
322
|
+
return c.json({ children: [] }, 200);
|
|
323
|
+
}
|
|
324
|
+
})
|
|
325
|
+
// --------------------------------------------------------------
|
|
326
|
+
// POST /pages — createPage
|
|
327
|
+
// --------------------------------------------------------------
|
|
328
|
+
.openapi(api_contract_1.createPageRoute, async (c) => {
|
|
329
|
+
const user = c.get('user');
|
|
330
|
+
const { path, body, grant } = c.req.valid('json');
|
|
331
|
+
debug('createPage called with:', { path, grant, userId: user._id });
|
|
332
|
+
if (grant !== undefined && !VALID_GRANTS.includes(grant)) {
|
|
333
|
+
return c.json(INVALID_GRANT_BODY, 400);
|
|
334
|
+
}
|
|
335
|
+
try {
|
|
336
|
+
const existing = await Page.findPage(path, user, null, /* ignoreNotFound */ true);
|
|
337
|
+
if (existing !== null) {
|
|
338
|
+
return c.json(pageBadRequestBody('PAGE_EXISTS', 'Page exists'), 400);
|
|
339
|
+
}
|
|
340
|
+
// RFC-0010 — record the edit channel (web / oauth / pat) so the
|
|
341
|
+
// history view can flag API-token edits.
|
|
342
|
+
const createOptions = { editVia: c.get('authContext').kind };
|
|
343
|
+
if (grant !== undefined)
|
|
344
|
+
createOptions.grant = grant;
|
|
345
|
+
const created = (await Page.createPage(path, body, user, createOptions));
|
|
346
|
+
if (!created) {
|
|
347
|
+
throw new Error('Failed to create page.');
|
|
348
|
+
}
|
|
349
|
+
const populated = await Page.populatePageData(created, null);
|
|
350
|
+
return c.json({ page: (0, page_response_1.pageToResponse)(populated) }, 200);
|
|
351
|
+
}
|
|
352
|
+
catch (err) {
|
|
353
|
+
const error = err;
|
|
354
|
+
debug('Error creating page:', error.message);
|
|
355
|
+
if (error.message === 'Cannot create non existent user page.') {
|
|
356
|
+
return c.json(pageBadRequestBody('NON_EXISTENT_USER_PAGE', error.message), 400);
|
|
357
|
+
}
|
|
358
|
+
// Both 'existed path' and 'not granted' collapse to PAGE_EXISTS
|
|
359
|
+
// — the latter is a stricter-grant race we must not leak.
|
|
360
|
+
if (error.message === 'Cannot create new page to existed path' || error.message === 'Page is not granted for the user') {
|
|
361
|
+
return c.json(pageBadRequestBody('PAGE_EXISTS', 'Page exists'), 400);
|
|
362
|
+
}
|
|
363
|
+
return c.json(pageBadRequestBody('PAGE_CREATE_FAILED', error.message || 'Failed to create page'), 400);
|
|
364
|
+
}
|
|
365
|
+
})
|
|
366
|
+
// --------------------------------------------------------------
|
|
367
|
+
// PUT /pages — updatePage
|
|
368
|
+
// --------------------------------------------------------------
|
|
369
|
+
.openapi(api_contract_1.updatePageRoute, async (c) => {
|
|
370
|
+
const user = c.get('user');
|
|
371
|
+
const { page_id, body, revision_id, grant } = c.req.valid('json');
|
|
372
|
+
debug('updatePage called with:', { page_id, revision_id, grant, userId: user._id });
|
|
373
|
+
if (grant !== undefined && !VALID_GRANTS.includes(grant)) {
|
|
374
|
+
return c.json(INVALID_GRANT_BODY, 400);
|
|
375
|
+
}
|
|
376
|
+
try {
|
|
377
|
+
const pageData = (await Page.findPageByIdAndGrantedUser(page_id, user));
|
|
378
|
+
if (!pageData) {
|
|
379
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
380
|
+
}
|
|
381
|
+
if (revision_id && !pageData.isUpdatable(revision_id)) {
|
|
382
|
+
return c.json(pageRevisionConflictBody(), 409);
|
|
383
|
+
}
|
|
384
|
+
// RFC-0010 — record the edit channel (web / oauth / pat) so the
|
|
385
|
+
// history view can flag API-token edits.
|
|
386
|
+
const updateOptions = { grant: grant ?? pageData.grant, editVia: c.get('authContext').kind };
|
|
387
|
+
const updated = (await Page.updatePage(pageData, body, user, updateOptions));
|
|
388
|
+
const populated = await Page.populatePageData(updated, null);
|
|
389
|
+
return c.json({ page: (0, page_response_1.pageToResponse)(populated) }, 200);
|
|
390
|
+
}
|
|
391
|
+
catch (err) {
|
|
392
|
+
const error = err;
|
|
393
|
+
debug('Error updating page:', error.message);
|
|
394
|
+
if (error.message === 'Page not found' || error.message === 'Page is not granted for the user') {
|
|
395
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
396
|
+
}
|
|
397
|
+
return c.json(pageBadRequestBody('PAGE_UPDATE_FAILED', error.message || 'Failed to update page'), 400);
|
|
398
|
+
}
|
|
399
|
+
})
|
|
400
|
+
// --------------------------------------------------------------
|
|
401
|
+
// PUT /pages/grant — setPageGrant
|
|
402
|
+
// --------------------------------------------------------------
|
|
403
|
+
.openapi(api_contract_1.setPageGrantRoute, async (c) => {
|
|
404
|
+
const user = c.get('user');
|
|
405
|
+
const { page_id, grant } = c.req.valid('json');
|
|
406
|
+
debug('setPageGrant called with:', { page_id, grant, userId: user._id });
|
|
407
|
+
if (!VALID_GRANTS.includes(grant)) {
|
|
408
|
+
return c.json(INVALID_GRANT_BODY, 400);
|
|
409
|
+
}
|
|
410
|
+
try {
|
|
411
|
+
const pageData = (await Page.findPageByIdAndGrantedUser(page_id, user));
|
|
412
|
+
if (!pageData) {
|
|
413
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
414
|
+
}
|
|
415
|
+
const updated = (await Page.updateGrant(pageData, grant, user));
|
|
416
|
+
const populated = await Page.populatePageData(updated, null);
|
|
417
|
+
return c.json({ page: (0, page_response_1.pageToResponse)(populated) }, 200);
|
|
418
|
+
}
|
|
419
|
+
catch (err) {
|
|
420
|
+
const error = err;
|
|
421
|
+
debug('Error updating page grant:', error.message);
|
|
422
|
+
if (error.message === 'Page not found' || error.message === 'Page is not granted for the user') {
|
|
423
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
424
|
+
}
|
|
425
|
+
return c.json(pageBadRequestBody('PAGE_GRANT_UPDATE_FAILED', error.message || 'Failed to update page grant'), 400);
|
|
426
|
+
}
|
|
427
|
+
})
|
|
428
|
+
// --------------------------------------------------------------
|
|
429
|
+
// POST /pages/seen — seenPage (idempotent via Page.seen addToSet)
|
|
430
|
+
// --------------------------------------------------------------
|
|
431
|
+
.openapi(api_contract_1.seenPageRoute, async (c) => {
|
|
432
|
+
const user = c.get('user');
|
|
433
|
+
const { page_id } = c.req.valid('json');
|
|
434
|
+
debug('seenPage called with:', { page_id, userId: user._id });
|
|
435
|
+
if (!(0, ts_rest_helpers_1.isValidObjectId)(page_id)) {
|
|
436
|
+
return c.json(errors_1.INVALID_PAGE_ID_BODY, 400);
|
|
437
|
+
}
|
|
438
|
+
const loaded = await (0, ts_rest_helpers_1.loadGrantedPage)(Page, page_id, user);
|
|
439
|
+
if ('error' in loaded)
|
|
440
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
441
|
+
const updated = (await loaded.page.seen(user));
|
|
442
|
+
return c.json(await buildSeenUsersResponse(updated.seenUsers), 200);
|
|
443
|
+
})
|
|
444
|
+
// --------------------------------------------------------------
|
|
445
|
+
// GET /pages/seen-users — getSeenUsers
|
|
446
|
+
// --------------------------------------------------------------
|
|
447
|
+
.openapi(api_contract_1.getSeenUsersRoute, async (c) => {
|
|
448
|
+
const user = c.get('user');
|
|
449
|
+
const { page_id, limit } = c.req.valid('query');
|
|
450
|
+
debug('getSeenUsers called with:', { page_id, limit, userId: user._id });
|
|
451
|
+
if (!(0, ts_rest_helpers_1.isValidObjectId)(page_id)) {
|
|
452
|
+
return c.json(errors_1.INVALID_PAGE_ID_BODY, 400);
|
|
453
|
+
}
|
|
454
|
+
const loaded = await (0, ts_rest_helpers_1.loadGrantedPage)(Page, page_id, user);
|
|
455
|
+
if ('error' in loaded) {
|
|
456
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
457
|
+
}
|
|
458
|
+
return c.json(await buildSeenUsersResponse(loaded.page.seenUsers, limit), 200);
|
|
459
|
+
})
|
|
460
|
+
// --------------------------------------------------------------
|
|
461
|
+
// POST /pages/like — likePage
|
|
462
|
+
// --------------------------------------------------------------
|
|
463
|
+
.openapi(api_contract_1.likePageRoute, async (c) => {
|
|
464
|
+
const user = c.get('user');
|
|
465
|
+
const { page_id } = c.req.valid('json');
|
|
466
|
+
debug('likePage called with:', { page_id, userId: user._id });
|
|
467
|
+
if (!(0, ts_rest_helpers_1.isValidObjectId)(page_id)) {
|
|
468
|
+
return c.json(errors_1.INVALID_PAGE_ID_BODY, 400);
|
|
469
|
+
}
|
|
470
|
+
const loaded = await (0, ts_rest_helpers_1.loadGrantedPage)(Page, page_id, user);
|
|
471
|
+
if ('error' in loaded) {
|
|
472
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
473
|
+
}
|
|
474
|
+
// `like` is a no-op when the user already liked the page.
|
|
475
|
+
await loaded.page.like(user);
|
|
476
|
+
const populated = await Page.populatePageData(loaded.page, null);
|
|
477
|
+
return c.json({ page: (0, page_response_1.pageToResponse)(populated) }, 200);
|
|
478
|
+
})
|
|
479
|
+
// --------------------------------------------------------------
|
|
480
|
+
// POST /pages/unlike — unlikePage
|
|
481
|
+
// --------------------------------------------------------------
|
|
482
|
+
.openapi(api_contract_1.unlikePageRoute, async (c) => {
|
|
483
|
+
const user = c.get('user');
|
|
484
|
+
const { page_id } = c.req.valid('json');
|
|
485
|
+
debug('unlikePage called with:', { page_id, userId: user._id });
|
|
486
|
+
if (!(0, ts_rest_helpers_1.isValidObjectId)(page_id)) {
|
|
487
|
+
return c.json(errors_1.INVALID_PAGE_ID_BODY, 400);
|
|
488
|
+
}
|
|
489
|
+
const loaded = await (0, ts_rest_helpers_1.loadGrantedPage)(Page, page_id, user);
|
|
490
|
+
if ('error' in loaded) {
|
|
491
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
492
|
+
}
|
|
493
|
+
await loaded.page.unlike(user);
|
|
494
|
+
const populated = await Page.populatePageData(loaded.page, null);
|
|
495
|
+
return c.json({ page: (0, page_response_1.pageToResponse)(populated) }, 200);
|
|
496
|
+
})
|
|
497
|
+
// --------------------------------------------------------------
|
|
498
|
+
// GET /pages/watch — getWatchStatus
|
|
499
|
+
// --------------------------------------------------------------
|
|
500
|
+
.openapi(api_contract_1.getWatchStatusRoute, async (c) => {
|
|
501
|
+
const user = c.get('user');
|
|
502
|
+
const { page_id } = c.req.valid('query');
|
|
503
|
+
debug('getWatchStatus called with:', { page_id, userId: user._id });
|
|
504
|
+
if (!(0, ts_rest_helpers_1.isValidObjectId)(page_id)) {
|
|
505
|
+
return c.json(errors_1.INVALID_PAGE_ID_BODY, 400);
|
|
506
|
+
}
|
|
507
|
+
const loaded = await (0, ts_rest_helpers_1.loadGrantedPage)(Page, page_id, user);
|
|
508
|
+
if ('error' in loaded) {
|
|
509
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
510
|
+
}
|
|
511
|
+
// feature-watch-autosubscribe — watch state is now exactly the
|
|
512
|
+
// presence of a WATCH watcher row. Participation auto-creates one
|
|
513
|
+
// (events/page.ts + comment handler), so the previous derive-from-
|
|
514
|
+
// getNotificationTargetUsers fallback is no longer needed.
|
|
515
|
+
const watcher = await Watcher.findByUserIdAndTargetId(user._id, loaded.page._id);
|
|
516
|
+
return c.json({ watching: watcher ? watcher.isWatching() : false }, 200);
|
|
517
|
+
})
|
|
518
|
+
// --------------------------------------------------------------
|
|
519
|
+
// PUT /pages/watch — setWatchStatus (2-state: WATCH / IGNORE)
|
|
520
|
+
// --------------------------------------------------------------
|
|
521
|
+
.openapi(api_contract_1.setWatchStatusRoute, async (c) => {
|
|
522
|
+
const user = c.get('user');
|
|
523
|
+
const { page_id, watching } = c.req.valid('json');
|
|
524
|
+
debug('setWatchStatus called with:', { page_id, watching, userId: user._id });
|
|
525
|
+
if (!(0, ts_rest_helpers_1.isValidObjectId)(page_id)) {
|
|
526
|
+
return c.json(errors_1.INVALID_PAGE_ID_BODY, 400);
|
|
527
|
+
}
|
|
528
|
+
const loaded = await (0, ts_rest_helpers_1.loadGrantedPage)(Page, page_id, user);
|
|
529
|
+
if ('error' in loaded) {
|
|
530
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
531
|
+
}
|
|
532
|
+
const status = watching ? Watcher.STATUS_WATCH : Watcher.STATUS_IGNORE;
|
|
533
|
+
await Watcher.watchByPageId(user._id, loaded.page._id, status);
|
|
534
|
+
return c.json({ watching }, 200);
|
|
535
|
+
})
|
|
536
|
+
// --------------------------------------------------------------
|
|
537
|
+
// DELETE /pages — deletePage (soft / hard with completely=true)
|
|
538
|
+
// --------------------------------------------------------------
|
|
539
|
+
.openapi(api_contract_1.deletePageRoute, async (c) => {
|
|
540
|
+
const user = c.get('user');
|
|
541
|
+
const { page_id, revision_id, completely } = c.req.valid('json');
|
|
542
|
+
debug('deletePage called with:', { page_id, revision_id, completely, userId: user._id });
|
|
543
|
+
try {
|
|
544
|
+
const pageData = (await Page.findPageByIdAndGrantedUser(page_id, user));
|
|
545
|
+
if (!pageData) {
|
|
546
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
547
|
+
}
|
|
548
|
+
if (completely === true) {
|
|
549
|
+
// Hard delete bypasses the revision check (legacy parity).
|
|
550
|
+
await Page.completelyDeletePage(pageData, user);
|
|
551
|
+
// The document is gone from Mongo; echo the in-memory snapshot
|
|
552
|
+
// so the client knows what was deleted.
|
|
553
|
+
return c.json({ page: (0, page_response_1.pageToResponse)(pageData) }, 200);
|
|
554
|
+
}
|
|
555
|
+
if (revision_id && !pageData.isUpdatable(revision_id)) {
|
|
556
|
+
return c.json(pageRevisionConflictBody(), 409);
|
|
557
|
+
}
|
|
558
|
+
// Page.deletePage mutates `pageData` (status -> deleted, path
|
|
559
|
+
// -> /trash/<path>); the returned value is the *redirect* page
|
|
560
|
+
// (a quirk of the legacy model). Re-populate the mutated
|
|
561
|
+
// pageData so the response reflects the soft-deleted page
|
|
562
|
+
// itself, which is what clients want.
|
|
563
|
+
await Page.deletePage(pageData, user);
|
|
564
|
+
const populated = await Page.populatePageData(pageData, null);
|
|
565
|
+
return c.json({ page: (0, page_response_1.pageToResponse)(populated) }, 200);
|
|
566
|
+
}
|
|
567
|
+
catch (err) {
|
|
568
|
+
const error = err;
|
|
569
|
+
debug('Error deleting page:', error.message);
|
|
570
|
+
if (error.message === 'Page not found' || error.message === 'Page is not granted for the user') {
|
|
571
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
572
|
+
}
|
|
573
|
+
return c.json(pageBadRequestBody('PAGE_DELETE_FAILED', error.message || 'Failed to delete page'), 400);
|
|
574
|
+
}
|
|
575
|
+
})
|
|
576
|
+
// --------------------------------------------------------------
|
|
577
|
+
// POST /pages/revert — revertDeletedPage
|
|
578
|
+
// --------------------------------------------------------------
|
|
579
|
+
.openapi(api_contract_1.revertDeletedPageRoute, async (c) => {
|
|
580
|
+
const user = c.get('user');
|
|
581
|
+
const { page_id } = c.req.valid('json');
|
|
582
|
+
debug('revertDeletedPage called with:', { page_id, userId: user._id });
|
|
583
|
+
try {
|
|
584
|
+
const pageData = (await Page.findPageByIdAndGrantedUser(page_id, user));
|
|
585
|
+
if (!pageData) {
|
|
586
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
587
|
+
}
|
|
588
|
+
// Mutates pageData (path -> non-trash, status -> published)
|
|
589
|
+
// and removes the redirect stub at the original /trash path.
|
|
590
|
+
await Page.revertDeletedPage(pageData, user);
|
|
591
|
+
const populated = await Page.populatePageData(pageData, null);
|
|
592
|
+
return c.json({ page: (0, page_response_1.pageToResponse)(populated) }, 200);
|
|
593
|
+
}
|
|
594
|
+
catch (err) {
|
|
595
|
+
const error = err;
|
|
596
|
+
debug('Error reverting deleted page:', error.message);
|
|
597
|
+
if (error.message === 'Page not found' || error.message === 'Page is not granted for the user') {
|
|
598
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
599
|
+
}
|
|
600
|
+
return c.json(pageBadRequestBody('PAGE_REVERT_FAILED', error.message || 'Failed to revert deleted page'), 400);
|
|
601
|
+
}
|
|
602
|
+
})
|
|
603
|
+
// --------------------------------------------------------------
|
|
604
|
+
// POST /pages/rename — renamePage
|
|
605
|
+
// --------------------------------------------------------------
|
|
606
|
+
.openapi(api_contract_1.renamePageRoute, async (c) => {
|
|
607
|
+
const user = c.get('user');
|
|
608
|
+
const { page_id, new_path, revision_id, create_redirect, include_descendants } = c.req.valid('json');
|
|
609
|
+
debug('renamePage called with:', { page_id, new_path, revision_id, create_redirect, include_descendants, userId: user._id });
|
|
610
|
+
// Normalise the destination path first so obviously-bad inputs
|
|
611
|
+
// are rejected without touching the DB.
|
|
612
|
+
const newPagePath = Page.normalizePath(new_path);
|
|
613
|
+
const newPageIsPortal = newPagePath.endsWith('/');
|
|
614
|
+
// Destination must be a creatable name and must not be a user
|
|
615
|
+
// home page (`/user/<name>`) — that path is username-bound and
|
|
616
|
+
// can't be hijacked by renaming another page onto it.
|
|
617
|
+
if (!Page.isCreatableName(newPagePath) || !Page.isRenamableName(newPagePath)) {
|
|
618
|
+
return c.json(pageBadRequestBody('PAGE_INVALID_NAME', `Cannot rename to this page name (${newPagePath})`), 400);
|
|
619
|
+
}
|
|
620
|
+
try {
|
|
621
|
+
const pageData = (await Page.findPageByIdAndGrantedUser(page_id, user));
|
|
622
|
+
if (!pageData) {
|
|
623
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
624
|
+
}
|
|
625
|
+
// The user home page (`/user/<username>`) is bound to the username
|
|
626
|
+
// and must not be renamed (mirrors `isDeletableName`). Checked on
|
|
627
|
+
// the source path so it blocks both the single-page and
|
|
628
|
+
// include_descendants forms.
|
|
629
|
+
if (!Page.isRenamableName(pageData.path)) {
|
|
630
|
+
return c.json(pageBadRequestBody('PAGE_INVALID_NAME', `This page cannot be renamed (${pageData.path})`), 400);
|
|
631
|
+
}
|
|
632
|
+
// Optimistic-lock on the root page's revision — same as the
|
|
633
|
+
// single-page path. Sub-pages are not individually version-checked
|
|
634
|
+
// (legacy renameTree parity).
|
|
635
|
+
if (revision_id && !pageData.isUpdatable(revision_id)) {
|
|
636
|
+
return c.json(pageRevisionConflictBody(), 409);
|
|
637
|
+
}
|
|
638
|
+
// ------------------------------------------------------------
|
|
639
|
+
// Subtree move (renameTree) — root + grant-visible descendants.
|
|
640
|
+
// ------------------------------------------------------------
|
|
641
|
+
if (include_descendants) {
|
|
642
|
+
const oldStripped = pageData.path.replace(/\/+$/, '');
|
|
643
|
+
// Grant-filtered subtree under the root. `findListByStartWith`
|
|
644
|
+
// also returns the un-slashed twin of a portal path, and the
|
|
645
|
+
// root itself — drop both so `descendants` is only the subtree.
|
|
646
|
+
// Mirrors rename-dialog.tsx:85-94 on the client side.
|
|
647
|
+
const descendantRoot = pageData.path.endsWith('/') ? pageData.path : `${pageData.path}/`;
|
|
648
|
+
const selfPaths = new Set([pageData.path, oldStripped]);
|
|
649
|
+
const subtree = await Page.findListByStartWith(descendantRoot, user, { limit: 0 });
|
|
650
|
+
const descendants = subtree.filter((p) => !selfPaths.has(p.path));
|
|
651
|
+
// Build old→new for the root + every visible descendant.
|
|
652
|
+
// `getPathMap` strips the trailing slash on `search` itself but
|
|
653
|
+
// only `normalizePath`s `replace` (which keeps a trailing slash),
|
|
654
|
+
// so a portal destination ('/foo/') would yield '/foo//child'.
|
|
655
|
+
// Strip it here for the descendant base to match the client
|
|
656
|
+
// preview (rename-dialog.tsx:104).
|
|
657
|
+
const newBase = newPagePath.replace(/\/+$/, '');
|
|
658
|
+
const pathMap = Page.getPathMap([{ path: pageData.path }, ...descendants.map((p) => ({ path: p.path }))], pageData.path, newBase);
|
|
659
|
+
// The root preserves the caller's portal intent (trailing slash);
|
|
660
|
+
// renameTree skips redirect creation for portal destinations, so
|
|
661
|
+
// restore the slash on the root entry the single-page path keeps.
|
|
662
|
+
if (newPageIsPortal) {
|
|
663
|
+
pathMap[pageData.path] = newPagePath;
|
|
664
|
+
}
|
|
665
|
+
const newPaths = Object.values(pathMap);
|
|
666
|
+
// Up-front validation: name legality + destination collisions.
|
|
667
|
+
const [hasError, errorsByPath] = (await Page.checkPagesRenamable(newPaths, user));
|
|
668
|
+
if (hasError) {
|
|
669
|
+
const conflicts = toConflicts(errorsByPath);
|
|
670
|
+
return c.json(renameTreeFailedBody('Some pages cannot be moved to the destination path.', conflicts), 400);
|
|
671
|
+
}
|
|
672
|
+
// Execute. Non-transactional best-effort: a mid-way failure may
|
|
673
|
+
// leave some pages already moved.
|
|
674
|
+
try {
|
|
675
|
+
await Page.renameTree(pathMap, user, { createRedirectPage: Boolean(create_redirect), preserveUpdatedAt: true });
|
|
676
|
+
}
|
|
677
|
+
catch (err) {
|
|
678
|
+
const error = err;
|
|
679
|
+
debug('Error renaming subtree:', error.message);
|
|
680
|
+
return c.json(renameTreeFailedBody(`Failed to move the whole subtree — some pages may already have been moved. (${error.message})`, [], true), 400);
|
|
681
|
+
}
|
|
682
|
+
const movedRoot = (await Page.findPageByPath(newPagePath));
|
|
683
|
+
const populated = movedRoot ? await Page.populatePageData(movedRoot, null) : await Page.populatePageData(pageData, null);
|
|
684
|
+
return c.json({ page: (0, page_response_1.pageToResponse)(populated), renamed_count: newPaths.length }, 200);
|
|
685
|
+
}
|
|
686
|
+
// ------------------------------------------------------------
|
|
687
|
+
// Single-page rename (default / back-compat).
|
|
688
|
+
// ------------------------------------------------------------
|
|
689
|
+
// Collision at the destination path — unlink an existing
|
|
690
|
+
// redirect when the caller has permission, otherwise refuse.
|
|
691
|
+
const existingAtNewPath = await Page.findOne({ path: newPagePath });
|
|
692
|
+
if (existingAtNewPath) {
|
|
693
|
+
if (existingAtNewPath.isUnlinkable(user)) {
|
|
694
|
+
try {
|
|
695
|
+
await existingAtNewPath.unlink(user);
|
|
696
|
+
}
|
|
697
|
+
catch (err) {
|
|
698
|
+
const error = err;
|
|
699
|
+
return c.json(pageBadRequestBody('PAGE_RENAME_FAILED', error.message || 'Failed to unlink redirect page at destination'), 400);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
else {
|
|
703
|
+
return c.json(pageBadRequestBody('PAGE_EXISTS', `Cannot rename to this page name (${newPagePath}). Page exists.`), 400);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
// Legacy controller: portal paths (ending in '/') never get a
|
|
707
|
+
// redirect page even if requested.
|
|
708
|
+
const options = {
|
|
709
|
+
createRedirectPage: !newPageIsPortal && Boolean(create_redirect),
|
|
710
|
+
};
|
|
711
|
+
await Page.rename(pageData, newPagePath, user, options);
|
|
712
|
+
const populated = await Page.populatePageData(pageData, null);
|
|
713
|
+
return c.json({ page: (0, page_response_1.pageToResponse)(populated), renamed_count: 1 }, 200);
|
|
714
|
+
}
|
|
715
|
+
catch (err) {
|
|
716
|
+
const error = err;
|
|
717
|
+
debug('Error renaming page:', error.message);
|
|
718
|
+
if (error.message === 'Page not found' || error.message === 'Page is not granted for the user') {
|
|
719
|
+
return c.json(errors_1.PAGE_NOT_FOUND_BODY, 404);
|
|
720
|
+
}
|
|
721
|
+
return c.json(pageBadRequestBody('PAGE_RENAME_FAILED', error.message || 'Failed to rename page'), 400);
|
|
722
|
+
}
|
|
723
|
+
})
|
|
724
|
+
// --------------------------------------------------------------
|
|
725
|
+
// POST /pages/rename-subtree — move a whole subtree by PATH.
|
|
726
|
+
//
|
|
727
|
+
// For a portal-less folder (a path like '/foo/bar/' that has
|
|
728
|
+
// descendants but no page document of its own, so there is no
|
|
729
|
+
// page_id / revision to key on). Always a subtree move: every
|
|
730
|
+
// grant-visible page under `old_path` is rewritten under `new_path`.
|
|
731
|
+
// --------------------------------------------------------------
|
|
732
|
+
.openapi(api_contract_1.renameSubtreeRoute, async (c) => {
|
|
733
|
+
const user = c.get('user');
|
|
734
|
+
const { old_path, new_path, create_redirect } = c.req.valid('json');
|
|
735
|
+
debug('renameSubtree called with:', { old_path, new_path, create_redirect, userId: user._id });
|
|
736
|
+
const newPagePath = Page.normalizePath(new_path);
|
|
737
|
+
const oldBase = old_path.replace(/\/+$/, '');
|
|
738
|
+
const newBase = newPagePath.replace(/\/+$/, '');
|
|
739
|
+
// Refuse a destination that normalises to the root portal — every
|
|
740
|
+
// descendant would be rewritten with an empty base.
|
|
741
|
+
if (newBase === '' || !Page.isCreatableName(newBase)) {
|
|
742
|
+
return c.json(pageBadRequestBody('PAGE_INVALID_NAME', `Cannot move the subtree to this path (${newPagePath})`), 400);
|
|
743
|
+
}
|
|
744
|
+
try {
|
|
745
|
+
// Grant-filtered subtree under the folder. Drop the folder path
|
|
746
|
+
// itself and its un-slashed twin (a separate page, not a child) —
|
|
747
|
+
// mirrors the client preview (rename-dialog.tsx).
|
|
748
|
+
const descendantRoot = old_path.endsWith('/') ? old_path : `${old_path}/`;
|
|
749
|
+
const selfPaths = new Set([descendantRoot, oldBase]);
|
|
750
|
+
const subtree = await Page.findListByStartWith(descendantRoot, user, { limit: 0 });
|
|
751
|
+
const descendants = subtree.filter((p) => !selfPaths.has(p.path));
|
|
752
|
+
if (descendants.length === 0) {
|
|
753
|
+
return c.json(renameTreeFailedBody('There are no pages to move under this path.', []), 400);
|
|
754
|
+
}
|
|
755
|
+
// Folder rename moves every descendant. A subtree rooted at
|
|
756
|
+
// `/user/` (or `/`) sweeps in every user's home page
|
|
757
|
+
// (`/user/<name>`), which would bypass the single-page rename
|
|
758
|
+
// guard. Refuse the whole move if any source is a home page.
|
|
759
|
+
const protectedSource = descendants.find((p) => !Page.isRenamableName(p.path));
|
|
760
|
+
if (protectedSource) {
|
|
761
|
+
return c.json(renameTreeFailedBody(`This subtree contains a page that cannot be renamed (${protectedSource.path}).`, [
|
|
762
|
+
{ path: protectedSource.path, reasons: ['PAGE_INVALID_NAME'] },
|
|
763
|
+
]), 400);
|
|
764
|
+
}
|
|
765
|
+
const pathMap = Page.getPathMap(descendants.map((p) => ({ path: p.path })), oldBase, newBase);
|
|
766
|
+
const newPaths = Object.values(pathMap);
|
|
767
|
+
// Up-front validation: name legality + destination collisions.
|
|
768
|
+
const [hasError, errorsByPath] = (await Page.checkPagesRenamable(newPaths, user));
|
|
769
|
+
if (hasError) {
|
|
770
|
+
const conflicts = toConflicts(errorsByPath);
|
|
771
|
+
return c.json(renameTreeFailedBody('Some pages cannot be moved to the destination path.', conflicts), 400);
|
|
772
|
+
}
|
|
773
|
+
// Execute. Non-transactional best-effort: a mid-way failure may
|
|
774
|
+
// leave some pages already moved.
|
|
775
|
+
try {
|
|
776
|
+
await Page.renameTree(pathMap, user, { createRedirectPage: Boolean(create_redirect), preserveUpdatedAt: true });
|
|
777
|
+
}
|
|
778
|
+
catch (err) {
|
|
779
|
+
const error = err;
|
|
780
|
+
debug('Error renaming subtree by path:', error.message);
|
|
781
|
+
return c.json(renameTreeFailedBody(`Failed to move the whole subtree — some pages may already have been moved. (${error.message})`, [], true), 400);
|
|
782
|
+
}
|
|
783
|
+
return c.json({ renamed_count: newPaths.length }, 200);
|
|
784
|
+
}
|
|
785
|
+
catch (err) {
|
|
786
|
+
const error = err;
|
|
787
|
+
debug('Error renaming subtree by path:', error.message);
|
|
788
|
+
return c.json(renameTreeFailedBody(error.message || 'Failed to move the subtree.', []), 400);
|
|
789
|
+
}
|
|
790
|
+
}));
|
|
791
|
+
};
|
|
792
|
+
exports.registerPageRoutes = registerPageRoutes;
|
|
793
|
+
//# sourceMappingURL=page.js.map
|