@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,1117 @@
|
|
|
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.TYPES = exports.TYPE_PUBLIC = exports.TYPE_USER = exports.TYPE_PORTAL = exports.USER_HOME_PAGE_PATH = exports.STATUSES = exports.STATUS_DRAFT = exports.STATUS_DEPRECATED = exports.STATUS_DELETED = exports.STATUS_PUBLISHED = exports.STATUS_WIP = exports.PAGE_GRANT_ERROR = exports.GRANTS = exports.GRANT_OWNER = exports.GRANT_SPECIFIED = exports.GRANT_RESTRICTED = exports.GRANT_PUBLIC = void 0;
|
|
7
|
+
exports.visiblePageStatusOr = visiblePageStatusOr;
|
|
8
|
+
exports.visiblePageGrantOr = visiblePageGrantOr;
|
|
9
|
+
const debug_1 = __importDefault(require("debug"));
|
|
10
|
+
const mongoose_1 = require("mongoose");
|
|
11
|
+
exports.GRANT_PUBLIC = 1;
|
|
12
|
+
exports.GRANT_RESTRICTED = 2;
|
|
13
|
+
exports.GRANT_SPECIFIED = 3;
|
|
14
|
+
exports.GRANT_OWNER = 4;
|
|
15
|
+
exports.GRANTS = [exports.GRANT_PUBLIC, exports.GRANT_RESTRICTED, exports.GRANT_SPECIFIED, exports.GRANT_OWNER];
|
|
16
|
+
exports.PAGE_GRANT_ERROR = 1;
|
|
17
|
+
exports.STATUS_WIP = 'wip';
|
|
18
|
+
exports.STATUS_PUBLISHED = 'published';
|
|
19
|
+
exports.STATUS_DELETED = 'deleted';
|
|
20
|
+
exports.STATUS_DEPRECATED = 'deprecated';
|
|
21
|
+
/**
|
|
22
|
+
* RFC-0004: first-class draft state. A page created via `POST
|
|
23
|
+
* /api/v2/pages/drafts` (Phase 3) starts as `draft` and transitions to
|
|
24
|
+
* `published` exactly once when the author first saves. The transition
|
|
25
|
+
* is one-way — there is no path back to `draft`. Draft pages are
|
|
26
|
+
* visible only to their author: listing / search / backlink queries
|
|
27
|
+
* exclude other users' drafts (see `findListByStartWith` /
|
|
28
|
+
* `findListByCreator`), and collab WebSocket connections to a draft
|
|
29
|
+
* page are rejected for non-authors (see `routes/ts-rest/page-collab.ts`
|
|
30
|
+
* + `@crowi/collab` `onAuthenticate`).
|
|
31
|
+
*/
|
|
32
|
+
exports.STATUS_DRAFT = 'draft';
|
|
33
|
+
exports.STATUSES = [exports.STATUS_WIP, exports.STATUS_PUBLISHED, exports.STATUS_DELETED, exports.STATUS_DEPRECATED, exports.STATUS_DRAFT];
|
|
34
|
+
/**
|
|
35
|
+
* A user's home page (`/user/<username>`). Its path is bound to the
|
|
36
|
+
* username, so it can be neither renamed nor deleted (it is also not a
|
|
37
|
+
* valid rename *destination*). Tolerates an optional trailing slash for
|
|
38
|
+
* defence-in-depth. Deeper pages under the home (`/user/<name>/memo`)
|
|
39
|
+
* are normal pages and are NOT matched. Shared by `isDeletableName` /
|
|
40
|
+
* `isRenamableName` so the two guards never drift; mirrors the web
|
|
41
|
+
* `isUserHomePath`.
|
|
42
|
+
*/
|
|
43
|
+
exports.USER_HOME_PAGE_PATH = /^\/user\/[^/]+\/?$/;
|
|
44
|
+
/**
|
|
45
|
+
* `$or` status clause for "pages visible to a given viewer" (RFC-0004):
|
|
46
|
+
* published and legacy-null pages are always visible; a `draft` page is
|
|
47
|
+
* visible only to its creator.
|
|
48
|
+
*
|
|
49
|
+
* When the surrounding query is already pinned to a single `creator`,
|
|
50
|
+
* pass that as `creatorId` — the draft clause is then a bare
|
|
51
|
+
* `{ status: 'draft' }`, included only when `viewerId === creatorId`.
|
|
52
|
+
* When the query spans multiple creators, omit `creatorId` — the draft
|
|
53
|
+
* clause carries its own `creator: viewerId` constraint.
|
|
54
|
+
*/
|
|
55
|
+
function visiblePageStatusOr(viewerId, creatorId) {
|
|
56
|
+
const or = [{ status: null }, { status: exports.STATUS_PUBLISHED }];
|
|
57
|
+
if (creatorId === undefined) {
|
|
58
|
+
or.push({ status: exports.STATUS_DRAFT, creator: viewerId });
|
|
59
|
+
}
|
|
60
|
+
else if (String(viewerId) === String(creatorId)) {
|
|
61
|
+
or.push({ status: exports.STATUS_DRAFT });
|
|
62
|
+
}
|
|
63
|
+
return or;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* `$or` grant clause for "pages readable by a given user": public and
|
|
67
|
+
* legacy-null pages are always readable; restricted / specified / owner
|
|
68
|
+
* pages only when the user is in `grantedUsers`.
|
|
69
|
+
*/
|
|
70
|
+
function visiblePageGrantOr(userId) {
|
|
71
|
+
return [
|
|
72
|
+
{ grant: null },
|
|
73
|
+
{ grant: exports.GRANT_PUBLIC },
|
|
74
|
+
{ grant: exports.GRANT_RESTRICTED, grantedUsers: userId },
|
|
75
|
+
{ grant: exports.GRANT_SPECIFIED, grantedUsers: userId },
|
|
76
|
+
{ grant: exports.GRANT_OWNER, grantedUsers: userId },
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
/** Builds the `Crowi:Page:NotFound` error that callers map onto a 404. */
|
|
80
|
+
function pageNotFoundError() {
|
|
81
|
+
const error = new Error('Page not found');
|
|
82
|
+
error.name = 'Crowi:Page:NotFound';
|
|
83
|
+
return error;
|
|
84
|
+
}
|
|
85
|
+
/** Max simultaneous per-page operations during a subtree rename (renameTree). */
|
|
86
|
+
const RENAME_TREE_CONCURRENCY = 8;
|
|
87
|
+
/**
|
|
88
|
+
* Run `fn` over `items` with at most `limit` in flight at once, preserving
|
|
89
|
+
* result order. Rejects on the first error (like `Promise.all`); in-flight
|
|
90
|
+
* siblings are not cancelled but no new work is started after a rejection.
|
|
91
|
+
*/
|
|
92
|
+
async function mapWithConcurrency(items, limit, fn) {
|
|
93
|
+
const results = new Array(items.length);
|
|
94
|
+
let cursor = 0;
|
|
95
|
+
const worker = async () => {
|
|
96
|
+
while (cursor < items.length) {
|
|
97
|
+
const index = cursor++;
|
|
98
|
+
results[index] = await fn(items[index]);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));
|
|
102
|
+
return results;
|
|
103
|
+
}
|
|
104
|
+
exports.TYPE_PORTAL = 'portal';
|
|
105
|
+
exports.TYPE_USER = 'user';
|
|
106
|
+
exports.TYPE_PUBLIC = 'public';
|
|
107
|
+
exports.TYPES = [exports.TYPE_PORTAL, exports.TYPE_USER, exports.TYPE_PUBLIC];
|
|
108
|
+
exports.default = (crowi) => {
|
|
109
|
+
const debug = (0, debug_1.default)('crowi:models:page');
|
|
110
|
+
const pageEvent = crowi.event('Page');
|
|
111
|
+
function isPortalPath(path) {
|
|
112
|
+
return path.endsWith('/');
|
|
113
|
+
}
|
|
114
|
+
function addTrailingSlash(path) {
|
|
115
|
+
return path.endsWith('/') ? path : `${path}/`;
|
|
116
|
+
}
|
|
117
|
+
function removeTrailingSlash(string) {
|
|
118
|
+
return string.endsWith('/') ? string.substring(0, string.length - 1) : string;
|
|
119
|
+
}
|
|
120
|
+
const pageSchema = new mongoose_1.Schema({
|
|
121
|
+
path: { type: String, required: true, index: true, unique: true },
|
|
122
|
+
revision: { type: mongoose_1.Schema.Types.ObjectId, ref: 'Revision' },
|
|
123
|
+
redirectTo: { type: String, index: true },
|
|
124
|
+
status: { type: String, default: exports.STATUS_PUBLISHED, index: true },
|
|
125
|
+
grant: { type: Number, default: exports.GRANT_PUBLIC, index: true },
|
|
126
|
+
grantedUsers: [{ type: mongoose_1.Schema.Types.ObjectId, ref: 'User' }],
|
|
127
|
+
creator: { type: mongoose_1.Schema.Types.ObjectId, ref: 'User', index: true },
|
|
128
|
+
// lastUpdateUser: this schema is from 1.5.x (by deletion feature), and null is default.
|
|
129
|
+
// the last update user on the screen is by revesion.author for B.C.
|
|
130
|
+
lastUpdateUser: { type: mongoose_1.Schema.Types.ObjectId, ref: 'User', index: true },
|
|
131
|
+
liker: [{ type: mongoose_1.Schema.Types.ObjectId, ref: 'User', index: true }],
|
|
132
|
+
seenUsers: [{ type: mongoose_1.Schema.Types.ObjectId, ref: 'User', index: true }],
|
|
133
|
+
commentCount: { type: Number, default: 0 },
|
|
134
|
+
extended: {
|
|
135
|
+
type: String,
|
|
136
|
+
default: {},
|
|
137
|
+
get: function (data) {
|
|
138
|
+
try {
|
|
139
|
+
const parsed = JSON.parse(data);
|
|
140
|
+
// for fixing data wile bugging.
|
|
141
|
+
// the data could be '"{}"' (parsed as '{}' so the data should be converted to empty object
|
|
142
|
+
if (typeof parsed === 'string' && parsed === '{}') {
|
|
143
|
+
return {};
|
|
144
|
+
}
|
|
145
|
+
return parsed;
|
|
146
|
+
}
|
|
147
|
+
catch (e) {
|
|
148
|
+
return data;
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
set: function (data) {
|
|
152
|
+
return JSON.stringify(data);
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
createdAt: { type: Date, default: Date.now },
|
|
156
|
+
updatedAt: Date,
|
|
157
|
+
// RFC-0003: pointer to the latest collaborative-save `Revision`.
|
|
158
|
+
// Co-exists with `revision` during the v2.1 transition; the
|
|
159
|
+
// legacy field stays the source of truth until Phase 5 lands
|
|
160
|
+
// the dual-write inside the save transaction.
|
|
161
|
+
currentRevision: { type: mongoose_1.Schema.Types.ObjectId, ref: 'Revision', default: null },
|
|
162
|
+
// RFC-0003: binary Y.Doc snapshot. Hocuspocus checkpoints into
|
|
163
|
+
// this field (Phase 4); `onLoadDocument` (Phase 3) reads it.
|
|
164
|
+
// `null` means "no live Yjs state — rebuild from `body`".
|
|
165
|
+
yjsState: { type: Buffer, default: null },
|
|
166
|
+
// RFC-0003: timestamp anchor for the most recent `yjsState`
|
|
167
|
+
// checkpoint. Driven by the compaction loop (Phase 4).
|
|
168
|
+
yjsCheckpointAt: { type: Date, default: null },
|
|
169
|
+
}, {
|
|
170
|
+
toJSON: { getters: true },
|
|
171
|
+
toObject: { getters: true },
|
|
172
|
+
});
|
|
173
|
+
// RFC-0004: backs `GET /api/v2/pages/drafts` — `find({ creator, status })`
|
|
174
|
+
// sorted by `createdAt` desc. Without it the listing scans a single-field
|
|
175
|
+
// index then sorts in memory.
|
|
176
|
+
pageSchema.index({ creator: 1, status: 1, createdAt: -1 });
|
|
177
|
+
pageEvent.on('create', pageEvent.onCreate);
|
|
178
|
+
pageEvent.on('update', pageEvent.onUpdate);
|
|
179
|
+
pageEvent.on('delete', pageEvent.onDelete);
|
|
180
|
+
pageSchema.methods.isWIP = function () {
|
|
181
|
+
return this.status === exports.STATUS_WIP;
|
|
182
|
+
};
|
|
183
|
+
pageSchema.methods.isPublished = function () {
|
|
184
|
+
// null: this is for B.C.
|
|
185
|
+
return this.status === null || this.status === exports.STATUS_PUBLISHED;
|
|
186
|
+
};
|
|
187
|
+
pageSchema.methods.isDeleted = function () {
|
|
188
|
+
return this.status === exports.STATUS_DELETED;
|
|
189
|
+
};
|
|
190
|
+
pageSchema.methods.isDeprecated = function () {
|
|
191
|
+
return this.status === exports.STATUS_DEPRECATED;
|
|
192
|
+
};
|
|
193
|
+
pageSchema.methods.isDraft = function () {
|
|
194
|
+
return this.status === exports.STATUS_DRAFT;
|
|
195
|
+
};
|
|
196
|
+
pageSchema.methods.isPublic = function () {
|
|
197
|
+
if (!this.grant || this.grant == exports.GRANT_PUBLIC) {
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
return false;
|
|
201
|
+
};
|
|
202
|
+
pageSchema.methods.isPortal = function () {
|
|
203
|
+
return isPortalPath(this.path);
|
|
204
|
+
};
|
|
205
|
+
pageSchema.methods.isCreator = function (userData) {
|
|
206
|
+
if (this.populated('creator') && this.creator._id.toString() === userData._id.toString()) {
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
else if (this.creator.toString() === userData._id.toString()) {
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
return false;
|
|
213
|
+
};
|
|
214
|
+
pageSchema.methods.isGrantedFor = function (userData) {
|
|
215
|
+
if (this.isPublic() || this.isCreator(userData)) {
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
if (this.grantedUsers.indexOf(userData._id) >= 0) {
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
return false;
|
|
222
|
+
};
|
|
223
|
+
pageSchema.methods.isLatestRevision = function () {
|
|
224
|
+
// populate されていなくて判断できない
|
|
225
|
+
if (!this.latestRevision || !this.revision) {
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
return this.latestRevision == this.revision._id.toString();
|
|
229
|
+
};
|
|
230
|
+
pageSchema.methods.isUpdatable = function (previousRevision) {
|
|
231
|
+
const revision = this.latestRevision || this.revision;
|
|
232
|
+
if (revision != previousRevision) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
return true;
|
|
236
|
+
};
|
|
237
|
+
pageSchema.methods.isLiked = function (userData) {
|
|
238
|
+
return this.liker.some(function (likedUser) {
|
|
239
|
+
return likedUser == userData._id.toString();
|
|
240
|
+
});
|
|
241
|
+
};
|
|
242
|
+
pageSchema.methods.isRedirectOriginPage = function () {
|
|
243
|
+
return this.redirectTo !== null;
|
|
244
|
+
};
|
|
245
|
+
pageSchema.methods.isUnlinkable = function (userData) {
|
|
246
|
+
return this.isRedirectOriginPage() && this.isGrantedFor(userData);
|
|
247
|
+
};
|
|
248
|
+
pageSchema.methods.like = async function (userData) {
|
|
249
|
+
const Activity = crowi.model('Activity');
|
|
250
|
+
const added = this.liker.addToSet(userData._id);
|
|
251
|
+
if (added.length > 0) {
|
|
252
|
+
const data = await this.save();
|
|
253
|
+
debug('liker updated!', added);
|
|
254
|
+
try {
|
|
255
|
+
const activityLog = await Activity.createByPageLike(data, userData);
|
|
256
|
+
debug('Activity created', activityLog);
|
|
257
|
+
}
|
|
258
|
+
catch (err) {
|
|
259
|
+
debug('Activity err', err);
|
|
260
|
+
}
|
|
261
|
+
return data;
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
debug('liker not updated');
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
pageSchema.methods.unlike = async function (userData) {
|
|
268
|
+
const Activity = crowi.model('Activity');
|
|
269
|
+
const liker = this.liker;
|
|
270
|
+
const beforeCount = liker.length;
|
|
271
|
+
liker.pull(userData._id);
|
|
272
|
+
if (liker.length != beforeCount) {
|
|
273
|
+
const data = await this.save();
|
|
274
|
+
try {
|
|
275
|
+
await Activity.removeByPageUnlike(data, userData);
|
|
276
|
+
debug('Activity removed');
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
debug('Activity remove err', err);
|
|
280
|
+
}
|
|
281
|
+
return data;
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
debug('liker not updated');
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
// Unlink: Remove redirect origin page
|
|
288
|
+
pageSchema.methods.unlink = async function (userData) {
|
|
289
|
+
const Page = crowi.model('Page');
|
|
290
|
+
if (this.isUnlinkable(userData)) {
|
|
291
|
+
debug('Unlink page', this._id, this.path);
|
|
292
|
+
try {
|
|
293
|
+
const redirectPage = await Page.removePageById(this._id);
|
|
294
|
+
debug('Redirect Page deleted', redirectPage.path);
|
|
295
|
+
}
|
|
296
|
+
catch (err) {
|
|
297
|
+
debug('Error occured while get setting', err, err.stack);
|
|
298
|
+
throw new Error(`Failed to delete redirect page (${this.path}).`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
throw new Error('Page is not unlinkable');
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
pageSchema.methods.isSeenUser = function (userData) {
|
|
306
|
+
const seenUsers = this.seenUsers;
|
|
307
|
+
return seenUsers.some(function (seenUser) {
|
|
308
|
+
return seenUser.equals(userData._id);
|
|
309
|
+
});
|
|
310
|
+
};
|
|
311
|
+
pageSchema.methods.seen = async function (userData) {
|
|
312
|
+
const seenUsers = this.seenUsers;
|
|
313
|
+
if (this.isSeenUser(userData)) {
|
|
314
|
+
debug('seenUsers not updated');
|
|
315
|
+
return this;
|
|
316
|
+
}
|
|
317
|
+
if (!userData || !userData._id) {
|
|
318
|
+
throw new Error('User data is not valid');
|
|
319
|
+
}
|
|
320
|
+
const added = seenUsers.addToSet(userData);
|
|
321
|
+
await this.save();
|
|
322
|
+
debug('seenUsers updated!', added);
|
|
323
|
+
return this;
|
|
324
|
+
};
|
|
325
|
+
pageSchema.methods.getSlackChannel = function () {
|
|
326
|
+
const extended = this.get('extended');
|
|
327
|
+
if (!extended) {
|
|
328
|
+
return '';
|
|
329
|
+
}
|
|
330
|
+
return extended.slack || '';
|
|
331
|
+
};
|
|
332
|
+
pageSchema.methods.updateSlackChannel = function (slackChannel) {
|
|
333
|
+
const extended = this.extended;
|
|
334
|
+
extended.slack = slackChannel;
|
|
335
|
+
return this.updateExtended(extended);
|
|
336
|
+
};
|
|
337
|
+
pageSchema.methods.updateExtended = function (extended) {
|
|
338
|
+
this.extended = extended;
|
|
339
|
+
return this.save();
|
|
340
|
+
};
|
|
341
|
+
pageSchema.statics.populatePageData = function (pageData, revisionId) {
|
|
342
|
+
pageData.latestRevision = pageData.revision;
|
|
343
|
+
if (revisionId) {
|
|
344
|
+
pageData.revision = revisionId;
|
|
345
|
+
}
|
|
346
|
+
pageData.likerCount = pageData.liker.length || 0;
|
|
347
|
+
pageData.seenUsersCount = pageData.seenUsers.length || 0;
|
|
348
|
+
return pageData.populate([
|
|
349
|
+
{ path: 'lastUpdateUser', model: 'User' },
|
|
350
|
+
{ path: 'creator', model: 'User' },
|
|
351
|
+
{ path: 'revision', model: 'Revision', populate: { path: 'author', model: 'User' } },
|
|
352
|
+
]);
|
|
353
|
+
};
|
|
354
|
+
pageSchema.statics.populatePagesRevision = async function (pages, revisions) {
|
|
355
|
+
if (pages.length !== revisions.length) {
|
|
356
|
+
throw new TypeError('page.length must be equal revisions.length');
|
|
357
|
+
}
|
|
358
|
+
pages = pages.map((page, i) => {
|
|
359
|
+
const revision = revisions[i];
|
|
360
|
+
if (revision) {
|
|
361
|
+
page.revision = revision;
|
|
362
|
+
}
|
|
363
|
+
return page;
|
|
364
|
+
});
|
|
365
|
+
return Page.populate(pages, { path: 'revision', model: 'Revision' });
|
|
366
|
+
};
|
|
367
|
+
pageSchema.statics.populatePageListToAnyObjects = async function (pageIdObjectArray) {
|
|
368
|
+
const pageIdMappings = {};
|
|
369
|
+
const pageIds = pageIdObjectArray.map(function (page, idx) {
|
|
370
|
+
if (!page._id) {
|
|
371
|
+
throw new Error('Pass the arg of populatePageListToAnyObjects() must have _id on each element.');
|
|
372
|
+
}
|
|
373
|
+
pageIdMappings[String(page._id)] = idx;
|
|
374
|
+
return page._id;
|
|
375
|
+
});
|
|
376
|
+
const pages = await Page.findListByPageIds(pageIds, { limit: 100 }); // limit => if the pagIds is greater than 100, ignore
|
|
377
|
+
for (const p of pages) {
|
|
378
|
+
Object.assign(pageIdObjectArray[pageIdMappings[String(p._id)]], p._doc);
|
|
379
|
+
}
|
|
380
|
+
return pageIdObjectArray;
|
|
381
|
+
};
|
|
382
|
+
pageSchema.statics.updateCommentCount = function (page, num) {
|
|
383
|
+
return Page.updateOne({ _id: page }, { commentCount: num }, {});
|
|
384
|
+
};
|
|
385
|
+
pageSchema.statics.hasPortalPage = async function (path, user, revisionId) {
|
|
386
|
+
try {
|
|
387
|
+
const page = await Page.findPage(path, user, revisionId);
|
|
388
|
+
return !!page;
|
|
389
|
+
}
|
|
390
|
+
catch (err) {
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
pageSchema.statics.findPortalPage = async function (path, user, revisionId) {
|
|
395
|
+
try {
|
|
396
|
+
const page = await Page.findPage(path, user, revisionId);
|
|
397
|
+
return page;
|
|
398
|
+
}
|
|
399
|
+
catch (err) {
|
|
400
|
+
return null;
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
pageSchema.statics.getGrantLabels = function () {
|
|
404
|
+
const grantLabels = {};
|
|
405
|
+
grantLabels[exports.GRANT_PUBLIC] = 'Public'; // 公開
|
|
406
|
+
grantLabels[exports.GRANT_RESTRICTED] = 'Anyone with the link'; // リンクを知っている人のみ
|
|
407
|
+
// grantLabels[GRANT_SPECIFIED] = 'Specified users only'; // 特定ユーザーのみ
|
|
408
|
+
grantLabels[exports.GRANT_OWNER] = 'Just me'; // 自分のみ
|
|
409
|
+
return grantLabels;
|
|
410
|
+
};
|
|
411
|
+
pageSchema.statics.normalizePath = function (path) {
|
|
412
|
+
if (!path.match(/^\//)) {
|
|
413
|
+
path = '/' + path;
|
|
414
|
+
}
|
|
415
|
+
path = path.replace(/\/\s+?/g, '/').replace(/\s+\//g, '/');
|
|
416
|
+
return path;
|
|
417
|
+
};
|
|
418
|
+
pageSchema.statics.getUserPagePath = function (user) {
|
|
419
|
+
return '/user/' + user.username;
|
|
420
|
+
};
|
|
421
|
+
pageSchema.statics.getDeletedPageName = function (path) {
|
|
422
|
+
if (path.match('/')) {
|
|
423
|
+
path = path.substr(1);
|
|
424
|
+
}
|
|
425
|
+
return '/trash/' + path;
|
|
426
|
+
};
|
|
427
|
+
pageSchema.statics.getRevertDeletedPageName = function (path) {
|
|
428
|
+
return path.replace('/trash', '');
|
|
429
|
+
};
|
|
430
|
+
// The user home page is the only non-deletable / non-renamable name;
|
|
431
|
+
// both guards share `USER_HOME_PAGE_PATH` so they can never drift.
|
|
432
|
+
pageSchema.statics.isDeletableName = function (path) {
|
|
433
|
+
return !exports.USER_HOME_PAGE_PATH.test(path);
|
|
434
|
+
};
|
|
435
|
+
pageSchema.statics.isRenamableName = function (path) {
|
|
436
|
+
return !exports.USER_HOME_PAGE_PATH.test(path);
|
|
437
|
+
};
|
|
438
|
+
pageSchema.statics.isCreatableName = function (name) {
|
|
439
|
+
const forbiddenPages = [
|
|
440
|
+
/\^|\$|\*|\+|\?|#/,
|
|
441
|
+
/^\/_.*/, // /_api/* and so on
|
|
442
|
+
/^\/-\/.*/,
|
|
443
|
+
/^\/_r\/.*/,
|
|
444
|
+
/^\/user\/?$/, // `/user` and `/user/` are the member directory — no portal/page here
|
|
445
|
+
/^\/user\/[^/]+\/(bookmarks|comments|activities|pages|recent-create|recent-edit)/, // reserved
|
|
446
|
+
/^\/?https?:\/\/.+$/, // avoid miss in renaming
|
|
447
|
+
/\/{2,}/, // avoid miss in renaming
|
|
448
|
+
/\s+\/\s+/, // avoid miss in renaming
|
|
449
|
+
/.+\/edit$/,
|
|
450
|
+
/.+\.md$/,
|
|
451
|
+
/^\/(installer|register|login|logout|admin|me|files|trash|paste|comments)(\/.*|$)/,
|
|
452
|
+
];
|
|
453
|
+
let isCreatable = true;
|
|
454
|
+
forbiddenPages.forEach(function (page) {
|
|
455
|
+
const pageNameReg = new RegExp(page);
|
|
456
|
+
if (name.match(pageNameReg)) {
|
|
457
|
+
isCreatable = false;
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
return isCreatable;
|
|
461
|
+
};
|
|
462
|
+
pageSchema.statics.fixToCreatableName = function (path) {
|
|
463
|
+
return path.replace(/\/\//g, '/');
|
|
464
|
+
};
|
|
465
|
+
pageSchema.statics.updateRevision = function (pageId, revisionId, cb) {
|
|
466
|
+
// mongoose 7 dropped the callback form of updateOne(); bridge the promise
|
|
467
|
+
// to the existing callback signature.
|
|
468
|
+
Page.updateOne({ _id: pageId }, { revision: revisionId }).then((data) => cb(null, data), (err) => cb(err, undefined));
|
|
469
|
+
};
|
|
470
|
+
pageSchema.statics.exists = async function (query) {
|
|
471
|
+
const count = await Page.countDocuments(query);
|
|
472
|
+
return count > 0;
|
|
473
|
+
};
|
|
474
|
+
pageSchema.statics.findUpdatedList = function (offset, limit, cb) {
|
|
475
|
+
Page.find({}).sort({ updatedAt: -1 }).skip(offset).limit(limit).exec();
|
|
476
|
+
};
|
|
477
|
+
pageSchema.statics.findPageById = async function (id) {
|
|
478
|
+
const pageData = await Page.findOne({ _id: id });
|
|
479
|
+
if (pageData === null) {
|
|
480
|
+
throw new Error('Page not found');
|
|
481
|
+
}
|
|
482
|
+
return Page.populatePageData(pageData, null);
|
|
483
|
+
};
|
|
484
|
+
pageSchema.statics.findPageByIdAndGrantedUser = async function (id, userData) {
|
|
485
|
+
const pageData = await Page.findPageById(id);
|
|
486
|
+
// RFC-0004: a draft page is visible only to its author. Collapse a
|
|
487
|
+
// non-author's by-id access into a not-found error (not a grant
|
|
488
|
+
// error) so draft existence is never leaked.
|
|
489
|
+
if (pageData.isDraft() && (!userData || !pageData.isCreator(userData))) {
|
|
490
|
+
throw pageNotFoundError();
|
|
491
|
+
}
|
|
492
|
+
if (userData && !pageData.isGrantedFor(userData)) {
|
|
493
|
+
throw new Error('Page is not granted for the user'); // PAGE_GRANT_ERROR, null);
|
|
494
|
+
}
|
|
495
|
+
return pageData;
|
|
496
|
+
};
|
|
497
|
+
// find page and check if granted user
|
|
498
|
+
pageSchema.statics.findPage = async function (path, userData, revisionId, ignoreNotFound) {
|
|
499
|
+
const pageData = await Page.findOne({ path });
|
|
500
|
+
if (pageData === null) {
|
|
501
|
+
if (ignoreNotFound) {
|
|
502
|
+
return null;
|
|
503
|
+
}
|
|
504
|
+
throw pageNotFoundError();
|
|
505
|
+
}
|
|
506
|
+
// RFC-0004: a draft page is visible only to its author. By-path
|
|
507
|
+
// access by anyone else collapses into the same not-found error a
|
|
508
|
+
// missing page raises, so a draft's existence at a path is never
|
|
509
|
+
// leaked to non-authors.
|
|
510
|
+
if (pageData.isDraft() && (!userData || !pageData.isCreator(userData))) {
|
|
511
|
+
throw pageNotFoundError();
|
|
512
|
+
}
|
|
513
|
+
if (!pageData.isGrantedFor(userData)) {
|
|
514
|
+
throw new Error('Page is not granted for the user'); // PAGE_GRANT_ERROR, null);
|
|
515
|
+
}
|
|
516
|
+
return Page.populatePageData(pageData, revisionId || null);
|
|
517
|
+
};
|
|
518
|
+
// find page by path
|
|
519
|
+
pageSchema.statics.findPageByPath = async function (path) {
|
|
520
|
+
const pageData = await Page.findOne({ path });
|
|
521
|
+
if (pageData === null) {
|
|
522
|
+
throw new Error('Page not found');
|
|
523
|
+
}
|
|
524
|
+
return pageData;
|
|
525
|
+
};
|
|
526
|
+
pageSchema.statics.isExistByPath = async function (path) {
|
|
527
|
+
const pageData = await Page.findOne({ path });
|
|
528
|
+
if (pageData === null) {
|
|
529
|
+
return false;
|
|
530
|
+
}
|
|
531
|
+
return pageData._id;
|
|
532
|
+
};
|
|
533
|
+
pageSchema.statics.isExistById = async function (id) {
|
|
534
|
+
const pageData = await Page.findOne({ _id: id });
|
|
535
|
+
if (pageData === null) {
|
|
536
|
+
return false;
|
|
537
|
+
}
|
|
538
|
+
return pageData._id;
|
|
539
|
+
};
|
|
540
|
+
pageSchema.statics.isNonExistentUserPage = async (path) => {
|
|
541
|
+
if (!path.startsWith('/user')) {
|
|
542
|
+
return false;
|
|
543
|
+
}
|
|
544
|
+
const username = path.match(/^\/user\/(?<username>[^/]+)/)?.groups?.username;
|
|
545
|
+
if (username === undefined) {
|
|
546
|
+
return false;
|
|
547
|
+
}
|
|
548
|
+
const User = crowi.model('User');
|
|
549
|
+
const userData = await User.findUserByUsername(username);
|
|
550
|
+
return userData === null;
|
|
551
|
+
};
|
|
552
|
+
pageSchema.statics.isNonExistentUserTrashPage = async (path) => {
|
|
553
|
+
if (!path.startsWith('/trash/user')) {
|
|
554
|
+
return false;
|
|
555
|
+
}
|
|
556
|
+
const username = path.match(/^\/trash\/user\/(?<username>[^/]+)/)?.groups?.username;
|
|
557
|
+
if (username === undefined) {
|
|
558
|
+
return false;
|
|
559
|
+
}
|
|
560
|
+
const User = crowi.model('User');
|
|
561
|
+
const userData = await User.findUserByUsername(username);
|
|
562
|
+
return userData === null;
|
|
563
|
+
};
|
|
564
|
+
pageSchema.statics.findListByPageIds = function (ids, options) {
|
|
565
|
+
options = options || {};
|
|
566
|
+
const limit = options.limit || 50;
|
|
567
|
+
const offset = options.skip || 0;
|
|
568
|
+
return (Page.find({ _id: { $in: ids } })
|
|
569
|
+
// .sort({createdAt: -1}) // TODO optionize
|
|
570
|
+
.skip(offset)
|
|
571
|
+
.limit(limit)
|
|
572
|
+
.populate([
|
|
573
|
+
{ path: 'creator', model: 'User' },
|
|
574
|
+
{ path: 'revision', model: 'Revision', populate: { path: 'author' } },
|
|
575
|
+
])
|
|
576
|
+
.exec());
|
|
577
|
+
};
|
|
578
|
+
pageSchema.statics.findPageByRedirectTo = async function (path) {
|
|
579
|
+
const pageData = await Page.findOne({ redirectTo: path });
|
|
580
|
+
if (pageData === null) {
|
|
581
|
+
throw new Error('Page not found');
|
|
582
|
+
}
|
|
583
|
+
return pageData;
|
|
584
|
+
};
|
|
585
|
+
pageSchema.statics.findPagesByIds = function (ids) {
|
|
586
|
+
const query = {
|
|
587
|
+
_id: { $in: ids },
|
|
588
|
+
redirectTo: null,
|
|
589
|
+
};
|
|
590
|
+
return Page.find(query)
|
|
591
|
+
.populate([
|
|
592
|
+
{ path: 'creator', model: 'User' },
|
|
593
|
+
{
|
|
594
|
+
path: 'revision',
|
|
595
|
+
model: 'Revision',
|
|
596
|
+
populate: {
|
|
597
|
+
path: 'author',
|
|
598
|
+
model: 'User',
|
|
599
|
+
},
|
|
600
|
+
},
|
|
601
|
+
])
|
|
602
|
+
.exec();
|
|
603
|
+
};
|
|
604
|
+
pageSchema.statics.findListByCreator = function (user, option, currentUser) {
|
|
605
|
+
const limit = option.limit || 50;
|
|
606
|
+
const offset = option.offset || 0;
|
|
607
|
+
const conditions = {
|
|
608
|
+
creator: user._id,
|
|
609
|
+
redirectTo: null,
|
|
610
|
+
$or: visiblePageStatusOr(currentUser._id, user._id),
|
|
611
|
+
};
|
|
612
|
+
if (!user.equals(currentUser._id)) {
|
|
613
|
+
conditions.grant = exports.GRANT_PUBLIC;
|
|
614
|
+
}
|
|
615
|
+
return Page.find(conditions)
|
|
616
|
+
.sort({ createdAt: -1 })
|
|
617
|
+
.skip(offset)
|
|
618
|
+
.limit(limit)
|
|
619
|
+
.populate({ path: 'revision', populate: { path: 'author' } })
|
|
620
|
+
.exec();
|
|
621
|
+
};
|
|
622
|
+
/**
|
|
623
|
+
* Bulk get (for internal only)
|
|
624
|
+
*/
|
|
625
|
+
pageSchema.statics.getStreamOfFindAll = function (options = {}) {
|
|
626
|
+
const publicOnly = options.publicOnly !== false;
|
|
627
|
+
const criteria = { redirectTo: null };
|
|
628
|
+
if (publicOnly) {
|
|
629
|
+
criteria.grant = exports.GRANT_PUBLIC;
|
|
630
|
+
}
|
|
631
|
+
return Page.find(criteria)
|
|
632
|
+
.populate([
|
|
633
|
+
{ path: 'creator', model: 'User' },
|
|
634
|
+
{ path: 'revision', model: 'Revision' },
|
|
635
|
+
])
|
|
636
|
+
.lean()
|
|
637
|
+
.cursor();
|
|
638
|
+
};
|
|
639
|
+
/**
|
|
640
|
+
* findListByStartWith
|
|
641
|
+
*
|
|
642
|
+
* If `path` has `/` at the end, returns '{path}/*' and '{path}' self.
|
|
643
|
+
* If `path` doesn't have `/` at the end, returns '{path}*'
|
|
644
|
+
* e.g.
|
|
645
|
+
*/
|
|
646
|
+
pageSchema.statics.findListByStartWith = function (path, userData, option) {
|
|
647
|
+
const pathCondition = [];
|
|
648
|
+
const includeDeletedPage = option.includeDeletedPage || false;
|
|
649
|
+
if (!option) {
|
|
650
|
+
option = { sort: 'updatedAt', desc: -1, offset: 0, limit: 50 };
|
|
651
|
+
}
|
|
652
|
+
const opt = {
|
|
653
|
+
sort: option.sort || 'updatedAt',
|
|
654
|
+
desc: option.desc || -1,
|
|
655
|
+
offset: option.offset || 0,
|
|
656
|
+
limit: option.limit === 0 ? 0 : option.limit || 50,
|
|
657
|
+
};
|
|
658
|
+
const sortOpt = {};
|
|
659
|
+
sortOpt[opt.sort] = opt.desc;
|
|
660
|
+
const queryReg = new RegExp('^' + path);
|
|
661
|
+
// var sliceOption = option.revisionSlice || { $slice: 1 }
|
|
662
|
+
pathCondition.push({ path: queryReg });
|
|
663
|
+
if (path.match(/\/$/) && path.length > 1) {
|
|
664
|
+
debug('Page list by ending with /, so find also upper level page');
|
|
665
|
+
pathCondition.push({ path: path.substr(0, path.length - 1) });
|
|
666
|
+
}
|
|
667
|
+
// FIXME: might be heavy
|
|
668
|
+
const query = {
|
|
669
|
+
redirectTo: null,
|
|
670
|
+
$or: visiblePageGrantOr(userData._id),
|
|
671
|
+
};
|
|
672
|
+
debug('findListByStartWith query:', JSON.stringify({ path, opt, pathCondition, userData: userData._id }));
|
|
673
|
+
const q = Page.find(query)
|
|
674
|
+
.populate({ path: 'revision', populate: { path: 'author', model: 'User' } })
|
|
675
|
+
.and({
|
|
676
|
+
$or: pathCondition,
|
|
677
|
+
})
|
|
678
|
+
.sort(sortOpt)
|
|
679
|
+
.skip(opt.offset)
|
|
680
|
+
.limit(opt.limit);
|
|
681
|
+
if (!includeDeletedPage) {
|
|
682
|
+
q.and({
|
|
683
|
+
$or: visiblePageStatusOr(userData._id),
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
return q.exec().then((results) => {
|
|
687
|
+
debug('findListByStartWith results count:', results.length);
|
|
688
|
+
return results;
|
|
689
|
+
});
|
|
690
|
+
};
|
|
691
|
+
pageSchema.statics.findChildrenByPath = async function (path, userData, option) {
|
|
692
|
+
path = addTrailingSlash(path);
|
|
693
|
+
return Page.findListByStartWith(path, userData, { limit: 0, ...option });
|
|
694
|
+
};
|
|
695
|
+
/**
|
|
696
|
+
* Aggregate the immediate child "directories" (next path segment)
|
|
697
|
+
* directly under a portal `path`, for the sidebar tree. Returns one
|
|
698
|
+
* entry per distinct first segment beneath `path`, with whether a
|
|
699
|
+
* real portal page is saved there (`hasPortal` → compass icon) and a
|
|
700
|
+
* descendant count.
|
|
701
|
+
*
|
|
702
|
+
* Implemented as a lean `path`-only scan + in-process grouping rather
|
|
703
|
+
* than a `$group` aggregation: extracting "the segment after the
|
|
704
|
+
* prefix" is awkward in MongoDB's expression language, and a portal's
|
|
705
|
+
* subtree is bounded. Visibility (grant + draft status) is enforced
|
|
706
|
+
* with the same `$or` predicates as the listing endpoints so the
|
|
707
|
+
* sidebar never leaks a page the viewer can't open.
|
|
708
|
+
*/
|
|
709
|
+
pageSchema.statics.findChildSegments = async function (path, userData) {
|
|
710
|
+
const prefix = addTrailingSlash(path);
|
|
711
|
+
// Escape regex metacharacters so a path like `/foo(bar)/` is matched
|
|
712
|
+
// literally, not as a pattern.
|
|
713
|
+
const escaped = prefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
714
|
+
const query = {
|
|
715
|
+
redirectTo: null,
|
|
716
|
+
path: new RegExp(`^${escaped}`),
|
|
717
|
+
$and: [{ $or: visiblePageGrantOr(userData._id) }, { $or: visiblePageStatusOr(userData._id) }],
|
|
718
|
+
};
|
|
719
|
+
const docs = await Page.find(query, { path: 1, status: 1 }).lean().exec();
|
|
720
|
+
const map = new Map();
|
|
721
|
+
for (const doc of docs) {
|
|
722
|
+
// Skip the portal page for `path` itself (e.g. `/crowi/` when
|
|
723
|
+
// querying `/crowi/`) — it is the parent, not a child.
|
|
724
|
+
if (doc.path === prefix)
|
|
725
|
+
continue;
|
|
726
|
+
const rest = doc.path.slice(prefix.length);
|
|
727
|
+
const slashIdx = rest.indexOf('/');
|
|
728
|
+
const segment = slashIdx === -1 ? rest : rest.slice(0, slashIdx);
|
|
729
|
+
if (!segment)
|
|
730
|
+
continue;
|
|
731
|
+
let entry = map.get(segment);
|
|
732
|
+
if (!entry) {
|
|
733
|
+
entry = { segment, path: `${prefix}${segment}/`, isPage: false, hasPortal: false, count: 0 };
|
|
734
|
+
map.set(segment, entry);
|
|
735
|
+
}
|
|
736
|
+
if (slashIdx === -1) {
|
|
737
|
+
// doc.path === `${prefix}${segment}` — the segment is a real page.
|
|
738
|
+
entry.isPage = true;
|
|
739
|
+
}
|
|
740
|
+
else if (rest === `${segment}/`) {
|
|
741
|
+
// doc.path === `${prefix}${segment}/` — a portal page. Only a
|
|
742
|
+
// *published* portal earns the sidebar portal marker; a draft
|
|
743
|
+
// portal (creator-visible via the status filter above) is not yet
|
|
744
|
+
// a real portal, so it must not flag the node.
|
|
745
|
+
entry.hasPortal = doc.status !== exports.STATUS_DRAFT;
|
|
746
|
+
}
|
|
747
|
+
else {
|
|
748
|
+
// A deeper descendant (`${prefix}${segment}/...`).
|
|
749
|
+
entry.count += 1;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
return (Array.from(map.values())
|
|
753
|
+
// Drop phantom nodes that exist only because of a draft portal
|
|
754
|
+
// (no real page, no published portal, no descendants) so a draft
|
|
755
|
+
// portal never surfaces in the sidebar.
|
|
756
|
+
.filter((e) => e.isPage || e.hasPortal || e.count > 0)
|
|
757
|
+
.sort((a, b) => a.segment.localeCompare(b.segment)));
|
|
758
|
+
};
|
|
759
|
+
pageSchema.statics.findUnfurlablePages = async function (type, array, grants = [exports.GRANT_PUBLIC, exports.GRANT_RESTRICTED]) {
|
|
760
|
+
const page = await Page.find({
|
|
761
|
+
[type]: { $in: array },
|
|
762
|
+
$or: grants.map((grant) => ({ grant })),
|
|
763
|
+
});
|
|
764
|
+
return page;
|
|
765
|
+
};
|
|
766
|
+
pageSchema.statics.findUnfurlablePagesByIds = async function (ids) {
|
|
767
|
+
return Page.findUnfurlablePages('_id', ids);
|
|
768
|
+
};
|
|
769
|
+
pageSchema.statics.findUnfurlablePagesByPaths = async function (paths) {
|
|
770
|
+
// `GRANT_RESTRICTED` pages can not be accessed using path
|
|
771
|
+
return Page.findUnfurlablePages('path', paths, [exports.GRANT_PUBLIC]);
|
|
772
|
+
};
|
|
773
|
+
pageSchema.statics.updatePageProperty = function (page, updateData) {
|
|
774
|
+
return Page.updateOne({ _id: page._id }, { $set: updateData });
|
|
775
|
+
};
|
|
776
|
+
pageSchema.statics.updateGrant = async function (page, grant, userData) {
|
|
777
|
+
page.grant = grant;
|
|
778
|
+
if (grant == exports.GRANT_PUBLIC) {
|
|
779
|
+
page.grantedUsers = [];
|
|
780
|
+
}
|
|
781
|
+
else {
|
|
782
|
+
page.grantedUsers = [];
|
|
783
|
+
page.grantedUsers.addToSet(userData._id);
|
|
784
|
+
}
|
|
785
|
+
const data = await page.save();
|
|
786
|
+
debug('Page.updateGrant, saved grantedUsers.', (data && data.path) || {});
|
|
787
|
+
return data;
|
|
788
|
+
};
|
|
789
|
+
// Instance method でいいのでは
|
|
790
|
+
pageSchema.statics.pushToGrantedUsers = function (page, userData) {
|
|
791
|
+
if (!page.grantedUsers || !Array.isArray(page.grantedUsers)) {
|
|
792
|
+
page.grantedUsers = [];
|
|
793
|
+
}
|
|
794
|
+
page.grantedUsers.addToSet(userData);
|
|
795
|
+
return page.save();
|
|
796
|
+
};
|
|
797
|
+
pageSchema.statics.pushRevision = async function (pageData, newRevision, user) {
|
|
798
|
+
const isCreate = pageData.revision === undefined;
|
|
799
|
+
if (isCreate) {
|
|
800
|
+
debug('pushRevision on Create');
|
|
801
|
+
}
|
|
802
|
+
await newRevision.save();
|
|
803
|
+
debug('Successfully saved new revision', newRevision);
|
|
804
|
+
pageData.revision = newRevision;
|
|
805
|
+
pageData.lastUpdateUser = user;
|
|
806
|
+
pageData.updatedAt = Date.now();
|
|
807
|
+
const data = pageData.save();
|
|
808
|
+
if (!isCreate) {
|
|
809
|
+
debug('pushRevision on Update');
|
|
810
|
+
}
|
|
811
|
+
return data;
|
|
812
|
+
};
|
|
813
|
+
pageSchema.statics.createPage = async function (path, body, user, options) {
|
|
814
|
+
const Revision = crowi.model('Revision');
|
|
815
|
+
const format = options.format || 'markdown';
|
|
816
|
+
let grant = options.grant || exports.GRANT_PUBLIC;
|
|
817
|
+
const redirectTo = options.redirectTo || null;
|
|
818
|
+
const allowNonExistentUserPage = options.allowNonExistentUserPage || false;
|
|
819
|
+
if (!allowNonExistentUserPage) {
|
|
820
|
+
const isNonExistentUserPage = await Page.isNonExistentUserPage(path);
|
|
821
|
+
if (isNonExistentUserPage) {
|
|
822
|
+
throw new Error('Cannot create non existent user page.');
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
// force public
|
|
826
|
+
if (isPortalPath(path)) {
|
|
827
|
+
grant = exports.GRANT_PUBLIC;
|
|
828
|
+
}
|
|
829
|
+
const pageData = await Page.findOne({ path });
|
|
830
|
+
if (pageData) {
|
|
831
|
+
throw new Error('Cannot create new page to existed path');
|
|
832
|
+
}
|
|
833
|
+
const newPage = await Page.create({
|
|
834
|
+
path,
|
|
835
|
+
creator: user,
|
|
836
|
+
lastUpdateUser: user,
|
|
837
|
+
createdAt: Date.now(),
|
|
838
|
+
updatedAt: Date.now(),
|
|
839
|
+
redirectTo: redirectTo,
|
|
840
|
+
grant: grant,
|
|
841
|
+
status: exports.STATUS_PUBLISHED,
|
|
842
|
+
grantedUsers: user ? [user] : [],
|
|
843
|
+
});
|
|
844
|
+
const newRevision = await Revision.prepareRevision(newPage, body, user, { format, editVia: options.editVia });
|
|
845
|
+
try {
|
|
846
|
+
const revisionData = await Page.pushRevision(newPage, newRevision, user);
|
|
847
|
+
pageEvent.emit('create', revisionData, user);
|
|
848
|
+
return revisionData;
|
|
849
|
+
}
|
|
850
|
+
catch (err) {
|
|
851
|
+
debug('Push Revision Error on create page', err);
|
|
852
|
+
throw err;
|
|
853
|
+
}
|
|
854
|
+
};
|
|
855
|
+
pageSchema.statics.updatePage = async function (pageData, body, user, options = {}) {
|
|
856
|
+
const Revision = crowi.model('Revision');
|
|
857
|
+
const Bookmark = crowi.model('Bookmark');
|
|
858
|
+
const grant = options.grant || null;
|
|
859
|
+
// update existing page
|
|
860
|
+
const newRevision = await Revision.prepareRevision(pageData, body, user, { editVia: options.editVia });
|
|
861
|
+
// This is the external (REST / API) edit path — it bypasses the
|
|
862
|
+
// collaborative editor. Per RFC-0003 §"Server-side direct Markdown
|
|
863
|
+
// edits", a direct body write MUST drop the persisted Y.Doc snapshot so
|
|
864
|
+
// the next `onLoadDocument` rebuilds a fresh doc from this revision
|
|
865
|
+
// instead of restoring the pre-edit `yjsState` (which would show stale
|
|
866
|
+
// content in the editor and, on its next autosave, silently revert this
|
|
867
|
+
// edit). Re-point `currentRevision` to the new revision so that rebuild
|
|
868
|
+
// (`currentRevision ?? revision`) seeds from the new body. The collab
|
|
869
|
+
// save flow manages these fields itself and never routes through
|
|
870
|
+
// `updatePage`, so this only affects external writes.
|
|
871
|
+
pageData.currentRevision = newRevision;
|
|
872
|
+
pageData.yjsState = null;
|
|
873
|
+
pageData.yjsCheckpointAt = null;
|
|
874
|
+
await Page.pushRevision(pageData, newRevision, user);
|
|
875
|
+
const bookmarkCount = await Bookmark.countByPageId(pageData._id);
|
|
876
|
+
// The 4th arg flags "a new revision was created" so events/page.ts can
|
|
877
|
+
// fan out an UPDATE notification only for body updates (not rename /
|
|
878
|
+
// metadata-only 'update' emits). updatePage always goes through
|
|
879
|
+
// pushRevision above, so this path is always a new revision.
|
|
880
|
+
if (grant != pageData.grant) {
|
|
881
|
+
const data = await Page.updateGrant(pageData, grant, user);
|
|
882
|
+
pageEvent.emit('update', data, user, bookmarkCount, true);
|
|
883
|
+
return data;
|
|
884
|
+
}
|
|
885
|
+
pageEvent.emit('update', pageData, user, bookmarkCount, true);
|
|
886
|
+
return pageData;
|
|
887
|
+
};
|
|
888
|
+
pageSchema.statics.deletePage = async function (pageData, user) {
|
|
889
|
+
const Share = crowi.model('Share');
|
|
890
|
+
const newPath = Page.getDeletedPageName(pageData.path);
|
|
891
|
+
const isNonExistentUserPage = await Page.isNonExistentUserPage(pageData.path);
|
|
892
|
+
if (Page.isDeletableName(pageData.path) || isNonExistentUserPage) {
|
|
893
|
+
await Page.updatePageProperty(pageData, { status: exports.STATUS_DELETED, lastUpdateUser: user });
|
|
894
|
+
await Share.deleteByPageId(pageData._id);
|
|
895
|
+
pageData.status = exports.STATUS_DELETED;
|
|
896
|
+
// ページ名が /trash/ 以下に存在する場合、おかしなことになる
|
|
897
|
+
// が、 /trash 以下にページが有るのは、個別に作っていたケースのみ。
|
|
898
|
+
// 一応しばらく前から uncreatable pages になっているのでこれでいいことにする
|
|
899
|
+
debug('Deleted the page, and rename it', pageData.path, newPath);
|
|
900
|
+
return Page.rename(pageData, newPath, user, { createRedirectPage: true });
|
|
901
|
+
}
|
|
902
|
+
throw new Error('Page is not deletable.');
|
|
903
|
+
};
|
|
904
|
+
pageSchema.statics.revertDeletedPage = async function (pageData, user) {
|
|
905
|
+
const newPath = Page.getRevertDeletedPageName(pageData.path);
|
|
906
|
+
const isNonExistentUserPage = await Page.isNonExistentUserPage(newPath);
|
|
907
|
+
if (isNonExistentUserPage) {
|
|
908
|
+
throw new Error('Cannot revert non existent user page.');
|
|
909
|
+
}
|
|
910
|
+
// 削除時、元ページの path には必ず redirectTo 付きで、ページが作成される。
|
|
911
|
+
// そのため、そいつは削除してOK
|
|
912
|
+
// が、redirectTo ではないページが存在している場合それは何かがおかしい。(データ補正が必要)
|
|
913
|
+
const originPageData = await Page.findPageByPath(newPath);
|
|
914
|
+
if (originPageData.redirectTo !== pageData.path) {
|
|
915
|
+
throw new Error('The new page of to revert is exists and the redirect path of the page is not the deleted page.');
|
|
916
|
+
}
|
|
917
|
+
await Page.completelyDeletePage(originPageData);
|
|
918
|
+
await Page.updatePageProperty(pageData, { status: exports.STATUS_PUBLISHED, lastUpdateUser: user });
|
|
919
|
+
pageData.status = exports.STATUS_PUBLISHED;
|
|
920
|
+
debug('Revert deleted the page, and rename again it', pageData, newPath);
|
|
921
|
+
await Page.rename(pageData, newPath, user, {});
|
|
922
|
+
pageData.path = newPath;
|
|
923
|
+
return pageData;
|
|
924
|
+
};
|
|
925
|
+
/**
|
|
926
|
+
* This is danger.
|
|
927
|
+
*/
|
|
928
|
+
pageSchema.statics.completelyDeletePage = async function (pageData, user) {
|
|
929
|
+
// Delete Bookmarks, Attachments, Revisions, Pages and emit delete
|
|
930
|
+
const Bookmark = crowi.model('Bookmark');
|
|
931
|
+
const Attachment = crowi.model('Attachment');
|
|
932
|
+
const Comment = crowi.model('Comment');
|
|
933
|
+
const Activity = crowi.model('Activity');
|
|
934
|
+
const pageId = pageData._id;
|
|
935
|
+
debug('Completely delete', pageData.path);
|
|
936
|
+
await Bookmark.removeBookmarksByPageId(pageId);
|
|
937
|
+
await Attachment.removeAttachmentsByPageId(pageId);
|
|
938
|
+
await Comment.removeCommentsByPageId(pageId);
|
|
939
|
+
await Page.removePageById(pageId);
|
|
940
|
+
await Page.removeRedirectOriginPageByPath(pageData.path);
|
|
941
|
+
await Activity.removeByPage(pageId);
|
|
942
|
+
pageEvent.emit('delete', pageData, user); // update as renamed page
|
|
943
|
+
return pageData;
|
|
944
|
+
};
|
|
945
|
+
pageSchema.statics.removePage = async function (pageData) {
|
|
946
|
+
const Revision = crowi.model('Revision');
|
|
947
|
+
const { _id } = pageData;
|
|
948
|
+
debug('Remove phisically, the page', _id);
|
|
949
|
+
try {
|
|
950
|
+
await Page.deleteOne({ _id });
|
|
951
|
+
}
|
|
952
|
+
catch (err) {
|
|
953
|
+
debug(' --> error', _id);
|
|
954
|
+
throw err;
|
|
955
|
+
}
|
|
956
|
+
await Revision.removeRevisionsByPath(pageData.path);
|
|
957
|
+
return pageData;
|
|
958
|
+
};
|
|
959
|
+
pageSchema.statics.removePageById = async function (pageId) {
|
|
960
|
+
const pageData = await Page.findPageById(pageId);
|
|
961
|
+
await Page.removePage(pageData);
|
|
962
|
+
return pageData;
|
|
963
|
+
};
|
|
964
|
+
pageSchema.statics.removePageByPath = async function (pagePath) {
|
|
965
|
+
const pageData = await Page.findPageByPath(pagePath);
|
|
966
|
+
await Page.removePage(pageData);
|
|
967
|
+
return pageData;
|
|
968
|
+
};
|
|
969
|
+
/**
|
|
970
|
+
* remove the page that is redirecting to specified `pagePath` recursively
|
|
971
|
+
* ex: when
|
|
972
|
+
* '/page1' redirects to '/page2' and
|
|
973
|
+
* '/page2' redirects to '/page3'
|
|
974
|
+
* and given '/page3',
|
|
975
|
+
* '/page1' and '/page2' will be removed
|
|
976
|
+
*
|
|
977
|
+
* @param {string} pagePath
|
|
978
|
+
*/
|
|
979
|
+
pageSchema.statics.removeRedirectOriginPageByPath = function (pagePath) {
|
|
980
|
+
return Page.findPageByRedirectTo(pagePath)
|
|
981
|
+
.then((redirectOriginPageData) => {
|
|
982
|
+
// remove
|
|
983
|
+
return (Page.removePageById(redirectOriginPageData.id)
|
|
984
|
+
// remove recursive
|
|
985
|
+
.then(() => {
|
|
986
|
+
return Page.removeRedirectOriginPageByPath(redirectOriginPageData.path);
|
|
987
|
+
}));
|
|
988
|
+
})
|
|
989
|
+
.catch((err) => {
|
|
990
|
+
// do nothing if origin page doesn't exist
|
|
991
|
+
return Promise.resolve();
|
|
992
|
+
});
|
|
993
|
+
};
|
|
994
|
+
pageSchema.statics.rename = async function (pageData, newPagePath, user, options) {
|
|
995
|
+
const Revision = crowi.model('Revision');
|
|
996
|
+
const path = pageData.path;
|
|
997
|
+
const createRedirectPage = options.createRedirectPage || false;
|
|
998
|
+
const preserveUpdatedAt = options.preserveUpdatedAt || false;
|
|
999
|
+
const updatedAt = preserveUpdatedAt ? {} : { updatedAt: Date.now() };
|
|
1000
|
+
const updateData = { path: newPagePath, lastUpdateUser: user, ...updatedAt };
|
|
1001
|
+
// pageData の path を変更
|
|
1002
|
+
await Page.updatePageProperty(pageData, updateData);
|
|
1003
|
+
// reivisions の path を変更
|
|
1004
|
+
const data = await Revision.updateRevisionListByPath(path, { path: newPagePath });
|
|
1005
|
+
pageData.path = newPagePath;
|
|
1006
|
+
if (createRedirectPage) {
|
|
1007
|
+
const body = 'redirect ' + newPagePath;
|
|
1008
|
+
return Page.createPage(path, body, user, {
|
|
1009
|
+
redirectTo: newPagePath,
|
|
1010
|
+
allowNonExistentUserPage: true,
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
pageEvent.emit('update', pageData, user); // update as renamed page
|
|
1014
|
+
return data;
|
|
1015
|
+
};
|
|
1016
|
+
pageSchema.statics.getPathMap = function (paths, search, replace) {
|
|
1017
|
+
search = removeTrailingSlash(search);
|
|
1018
|
+
replace = this.normalizePath(replace);
|
|
1019
|
+
const renamePath = (path) => path.replace(search, replace);
|
|
1020
|
+
// { [oldPath]: newPath }
|
|
1021
|
+
return paths.map(({ path }) => [path, renamePath(path)]).reduce((l, [k, v]) => Object.assign(l, { [k]: v }), {});
|
|
1022
|
+
};
|
|
1023
|
+
pageSchema.statics.checkPagesRenamable = async function (paths, user) {
|
|
1024
|
+
let error = false;
|
|
1025
|
+
let errors = {};
|
|
1026
|
+
for (const path of paths) {
|
|
1027
|
+
const e = [];
|
|
1028
|
+
if (!Page.isCreatableName(path)) {
|
|
1029
|
+
e.push('rename_tree.error.can_not_use_this_name');
|
|
1030
|
+
}
|
|
1031
|
+
const isAlreadyExists = await Page.exists({ path });
|
|
1032
|
+
if (isAlreadyExists) {
|
|
1033
|
+
const newPage = await Page.findPageByPath(path);
|
|
1034
|
+
if (!newPage.isUnlinkable(user)) {
|
|
1035
|
+
e.push('rename_tree.error.already_exists');
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
if (!error && e.length > 0) {
|
|
1039
|
+
error = true;
|
|
1040
|
+
}
|
|
1041
|
+
errors = Object.assign(errors, { [path]: e });
|
|
1042
|
+
}
|
|
1043
|
+
return [error, errors];
|
|
1044
|
+
};
|
|
1045
|
+
pageSchema.statics.renameTree = async function (pathMap, user, options) {
|
|
1046
|
+
const { createRedirectPage = false, preserveUpdatedAt = true } = options;
|
|
1047
|
+
// Bound the fan-out: each rename emits a page `update` event that triggers
|
|
1048
|
+
// re-indexing / backlink / notification recomputation, so an unbounded
|
|
1049
|
+
// `Promise.all` over a large subtree would fire a reindex storm at the
|
|
1050
|
+
// search backend and Mongo. A small pool keeps the load steady while still
|
|
1051
|
+
// being far faster than fully sequential.
|
|
1052
|
+
await mapWithConcurrency(Object.values(pathMap), RENAME_TREE_CONCURRENCY, async (newPath) => {
|
|
1053
|
+
if (await Page.exists({ path: newPath })) {
|
|
1054
|
+
const newPage = await Page.findPageByPath(newPath);
|
|
1055
|
+
if (newPage.isUnlinkable(user)) {
|
|
1056
|
+
await newPage.unlink(user);
|
|
1057
|
+
}
|
|
1058
|
+
else {
|
|
1059
|
+
throw new Error(`Failed to create this page (${newPage.path}). It already exists.`);
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
});
|
|
1063
|
+
return mapWithConcurrency(Object.entries(pathMap), RENAME_TREE_CONCURRENCY, async ([oldPath, newPath]) => {
|
|
1064
|
+
try {
|
|
1065
|
+
const options = {
|
|
1066
|
+
createRedirectPage: !isPortalPath(newPath) && createRedirectPage,
|
|
1067
|
+
preserveUpdatedAt,
|
|
1068
|
+
};
|
|
1069
|
+
const oldPage = await Page.findPageByPath(oldPath);
|
|
1070
|
+
await Page.rename(oldPage, newPath, user, options);
|
|
1071
|
+
return oldPage;
|
|
1072
|
+
}
|
|
1073
|
+
catch (err) {
|
|
1074
|
+
throw new Error(`Failed to update page (${oldPath}).`);
|
|
1075
|
+
}
|
|
1076
|
+
});
|
|
1077
|
+
};
|
|
1078
|
+
pageSchema.statics.allPageCount = function () {
|
|
1079
|
+
const query = { redirectTo: null, grant: exports.GRANT_PUBLIC };
|
|
1080
|
+
return Page.countDocuments(query); // TODO: option にする
|
|
1081
|
+
};
|
|
1082
|
+
pageSchema.methods.getNotificationTargetUsers = async function () {
|
|
1083
|
+
const Comment = crowi.model('Comment');
|
|
1084
|
+
const Revision = crowi.model('Revision');
|
|
1085
|
+
const [commentCreators, revisionAuthors] = await Promise.all([Comment.findCreatorsByPage(this), Revision.findAuthorsByPage(this)]);
|
|
1086
|
+
debug('commentCreators', commentCreators);
|
|
1087
|
+
debug('revisionAuthors', revisionAuthors);
|
|
1088
|
+
const targetUsers = [this.creator].concat(commentCreators, revisionAuthors);
|
|
1089
|
+
debug('targetUsers', targetUsers);
|
|
1090
|
+
const uniqueChecker = {};
|
|
1091
|
+
const uniqueUsers = [];
|
|
1092
|
+
targetUsers.forEach(function (user) {
|
|
1093
|
+
const userId = user.toString();
|
|
1094
|
+
if (uniqueChecker[userId] !== 1) {
|
|
1095
|
+
uniqueUsers.push(user);
|
|
1096
|
+
uniqueChecker[userId] = 1;
|
|
1097
|
+
}
|
|
1098
|
+
});
|
|
1099
|
+
debug('uniqueUsers', uniqueUsers);
|
|
1100
|
+
return uniqueUsers;
|
|
1101
|
+
};
|
|
1102
|
+
// Backlink registration moved to events/page.ts (pageEvent.on('create'/'update'))
|
|
1103
|
+
// to avoid double-registration on every save and to fire only when content
|
|
1104
|
+
// actually changes via createPage / updatePage. See migrate-backlink task.
|
|
1105
|
+
const Page = (0, mongoose_1.model)('Page', pageSchema);
|
|
1106
|
+
// 静的プロパティをスキーマではなくモデルに直接割り当て
|
|
1107
|
+
Page.GRANT_PUBLIC = exports.GRANT_PUBLIC;
|
|
1108
|
+
Page.GRANT_RESTRICTED = exports.GRANT_RESTRICTED;
|
|
1109
|
+
Page.GRANT_SPECIFIED = exports.GRANT_SPECIFIED;
|
|
1110
|
+
Page.GRANT_OWNER = exports.GRANT_OWNER;
|
|
1111
|
+
Page.PAGE_GRANT_ERROR = exports.PAGE_GRANT_ERROR;
|
|
1112
|
+
Page.TYPE_PORTAL = exports.TYPE_PORTAL;
|
|
1113
|
+
Page.TYPE_PUBLIC = exports.TYPE_PUBLIC;
|
|
1114
|
+
Page.TYPE_USER = exports.TYPE_USER;
|
|
1115
|
+
return Page;
|
|
1116
|
+
};
|
|
1117
|
+
//# sourceMappingURL=page.js.map
|