@crowi/api 2.0.0-alpha.1 → 2.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/collab/attach.d.ts +34 -10
- package/dist/collab/attach.js +77 -1
- package/dist/collab/attach.js.map +1 -1
- package/dist/crowi/index.js +7 -6
- package/dist/crowi/index.js.map +1 -1
- package/dist/hono/handlers/activation.d.ts +3 -3
- package/dist/hono/handlers/admin/users.d.ts +118 -0
- package/dist/hono/handlers/admin/users.js +28 -0
- package/dist/hono/handlers/admin/users.js.map +1 -1
- package/dist/hono/handlers/app.d.ts +1 -0
- package/dist/hono/handlers/app.js +11 -0
- package/dist/hono/handlers/app.js.map +1 -1
- package/dist/hono/handlers/attachment-stream.js +23 -0
- package/dist/hono/handlers/attachment-stream.js.map +1 -1
- package/dist/hono/handlers/draft.js +10 -0
- package/dist/hono/handlers/draft.js.map +1 -1
- package/dist/hono/handlers/emailChange.d.ts +4 -4
- package/dist/hono/handlers/inviteAccept.d.ts +6 -6
- package/dist/hono/handlers/page-collab.js +4 -0
- package/dist/hono/handlers/page-collab.js.map +1 -1
- package/dist/hono/handlers/page.d.ts +251 -0
- package/dist/hono/handlers/page.js +123 -6
- package/dist/hono/handlers/page.js.map +1 -1
- package/dist/hono/handlers/passwordReset.d.ts +5 -5
- package/dist/hono/handlers/tokenAuth.d.ts +7 -7
- package/dist/mcp/result.d.ts +42 -16
- package/dist/mcp/result.js +56 -10
- package/dist/mcp/result.js.map +1 -1
- package/dist/mcp/tools/page.js +21 -1
- package/dist/mcp/tools/page.js.map +1 -1
- package/dist/mcp/tools/search.d.ts +12 -0
- package/dist/mcp/tools/search.js +21 -5
- package/dist/mcp/tools/search.js.map +1 -1
- package/dist/migration/cli-api.d.ts +8 -1
- package/dist/migration/cli-api.js +2 -0
- package/dist/migration/cli-api.js.map +1 -1
- package/dist/migration/helpers.d.ts +13 -0
- package/dist/migration/helpers.js +29 -0
- package/dist/migration/helpers.js.map +1 -0
- package/dist/migration/migrations/code-mask.d.ts +76 -0
- package/dist/migration/migrations/code-mask.js +224 -0
- package/dist/migration/migrations/code-mask.js.map +1 -0
- package/dist/migration/migrations/files-url-to-attachments.d.ts +99 -0
- package/dist/migration/migrations/files-url-to-attachments.js +305 -0
- package/dist/migration/migrations/files-url-to-attachments.js.map +1 -0
- package/dist/migration/migrations/index.js +4 -0
- package/dist/migration/migrations/index.js.map +1 -1
- package/dist/migration/migrations/page-status-default.d.ts +31 -1
- package/dist/migration/migrations/published-current-revision.d.ts +47 -0
- package/dist/migration/migrations/published-current-revision.js +90 -0
- package/dist/migration/migrations/published-current-revision.js.map +1 -0
- package/dist/migration/migrations/relocate-reserved-api-paths.d.ts +37 -1
- package/dist/migration/migrations/relocate-reserved-api-paths.js +11 -3
- package/dist/migration/migrations/relocate-reserved-api-paths.js.map +1 -1
- package/dist/migration/migrations/revisions-schema-unify.d.ts +35 -1
- package/dist/migration/migrations/user-unique-prepare.d.ts +55 -1
- package/dist/migration/migrations/user-unique-prepare.js +5 -0
- package/dist/migration/migrations/user-unique-prepare.js.map +1 -1
- package/dist/migration/migrations/wikilink-format.d.ts +75 -12
- package/dist/migration/migrations/wikilink-format.js +23 -157
- package/dist/migration/migrations/wikilink-format.js.map +1 -1
- package/dist/migration/migrations/wikilink-html-recover.d.ts +191 -0
- package/dist/migration/migrations/wikilink-html-recover.js +340 -0
- package/dist/migration/migrations/wikilink-html-recover.js.map +1 -0
- package/dist/migration/registry.d.ts +8 -2
- package/dist/migration/registry.js +5 -1
- package/dist/migration/registry.js.map +1 -1
- package/dist/migration/run-boot-migrations.d.ts +4 -1
- package/dist/migration/run-boot-migrations.js +55 -23
- package/dist/migration/run-boot-migrations.js.map +1 -1
- package/dist/migration/runner.js +8 -1
- package/dist/migration/runner.js.map +1 -1
- package/dist/migration/types.d.ts +57 -5
- package/dist/migration/types.js.map +1 -1
- package/dist/models/page.d.ts +23 -3
- package/dist/models/page.js +91 -5
- package/dist/models/page.js.map +1 -1
- package/dist/models/user.d.ts +1 -0
- package/dist/models/user.js +40 -21
- package/dist/models/user.js.map +1 -1
- package/dist/plugin/plugin-manager.js +1 -1
- package/dist/renderer/core/headings.d.ts +12 -1
- package/dist/renderer/core/headings.js +48 -8
- package/dist/renderer/core/headings.js.map +1 -1
- package/dist/renderer/pipeline.d.ts +6 -0
- package/dist/renderer/pipeline.js.map +1 -1
- package/dist/renderer/registry.js +1 -1
- package/dist/util/page-response.js +19 -2
- package/dist/util/page-response.js.map +1 -1
- package/dist/util/ws-token.d.ts +13 -0
- package/dist/util/ws-token.js +43 -3
- package/dist/util/ws-token.js.map +1 -1
- package/package.json +13 -7
- package/views/mail/layout.mjml +7 -5
- package/dist/common/functions/path2name.d.ts +0 -1
- package/dist/common/functions/path2name.js +0 -22
- package/dist/common/functions/path2name.js.map +0 -1
- package/dist/common/functions/renderIcon.d.ts +0 -1
- package/dist/common/functions/renderIcon.js +0 -9
- package/dist/common/functions/renderIcon.js.map +0 -1
- package/dist/controllers/admin.d.ts +0 -3
- package/dist/controllers/admin.js +0 -474
- package/dist/controllers/admin.js.map +0 -1
- package/dist/controllers/attachment.d.ts +0 -4
- package/dist/controllers/attachment.js +0 -200
- package/dist/controllers/attachment.js.map +0 -1
- package/dist/controllers/backlink.d.ts +0 -3
- package/dist/controllers/backlink.js +0 -42
- package/dist/controllers/backlink.js.map +0 -1
- package/dist/controllers/bookmark.d.ts +0 -3
- package/dist/controllers/bookmark.js +0 -100
- package/dist/controllers/bookmark.js.map +0 -1
- package/dist/controllers/comment.d.ts +0 -3
- package/dist/controllers/comment.js +0 -111
- package/dist/controllers/comment.js.map +0 -1
- package/dist/controllers/index.d.ts +0 -25
- package/dist/controllers/index.js +0 -44
- package/dist/controllers/index.js.map +0 -1
- package/dist/controllers/installer.d.ts +0 -3
- package/dist/controllers/installer.js +0 -48
- package/dist/controllers/installer.js.map +0 -1
- package/dist/controllers/login.d.ts +0 -4
- package/dist/controllers/login.js +0 -438
- package/dist/controllers/login.js.map +0 -1
- package/dist/controllers/logout.d.ts +0 -5
- package/dist/controllers/logout.js +0 -11
- package/dist/controllers/logout.js.map +0 -1
- package/dist/controllers/me.d.ts +0 -4
- package/dist/controllers/me.js +0 -369
- package/dist/controllers/me.js.map +0 -1
- package/dist/controllers/notification.d.ts +0 -3
- package/dist/controllers/notification.js +0 -88
- package/dist/controllers/notification.js.map +0 -1
- package/dist/controllers/page.d.ts +0 -3
- package/dist/controllers/page.js +0 -881
- package/dist/controllers/page.js.map +0 -1
- package/dist/controllers/revision.d.ts +0 -3
- package/dist/controllers/revision.js +0 -91
- package/dist/controllers/revision.js.map +0 -1
- package/dist/controllers/search.d.ts +0 -3
- package/dist/controllers/search.js +0 -93
- package/dist/controllers/search.js.map +0 -1
- package/dist/controllers/share.d.ts +0 -3
- package/dist/controllers/share.js +0 -207
- package/dist/controllers/share.js.map +0 -1
- package/dist/controllers/shareAccess.d.ts +0 -3
- package/dist/controllers/shareAccess.js +0 -28
- package/dist/controllers/shareAccess.js.map +0 -1
- package/dist/controllers/slack.d.ts +0 -3
- package/dist/controllers/slack.js +0 -87
- package/dist/controllers/slack.js.map +0 -1
- package/dist/controllers/tokenAuth.d.ts +0 -10
- package/dist/controllers/tokenAuth.js +0 -292
- package/dist/controllers/tokenAuth.js.map +0 -1
- package/dist/controllers/user.d.ts +0 -3
- package/dist/controllers/user.js +0 -67
- package/dist/controllers/user.js.map +0 -1
- package/dist/controllers/version.d.ts +0 -4
- package/dist/controllers/version.js +0 -19
- package/dist/controllers/version.js.map +0 -1
- package/dist/crowi/express-init.d.ts +0 -4
- package/dist/crowi/express-init.js +0 -101
- package/dist/crowi/express-init.js.map +0 -1
- package/dist/form/admin/app.d.ts +0 -2
- package/dist/form/admin/app.js +0 -9
- package/dist/form/admin/app.js.map +0 -1
- package/dist/form/admin/auth.d.ts +0 -2
- package/dist/form/admin/auth.js +0 -9
- package/dist/form/admin/auth.js.map +0 -1
- package/dist/form/admin/aws.d.ts +0 -2
- package/dist/form/admin/aws.js +0 -13
- package/dist/form/admin/aws.js.map +0 -1
- package/dist/form/admin/github.d.ts +0 -2
- package/dist/form/admin/github.js +0 -15
- package/dist/form/admin/github.js.map +0 -1
- package/dist/form/admin/google.d.ts +0 -2
- package/dist/form/admin/google.js +0 -13
- package/dist/form/admin/google.js.map +0 -1
- package/dist/form/admin/mail.d.ts +0 -2
- package/dist/form/admin/mail.js +0 -13
- package/dist/form/admin/mail.js.map +0 -1
- package/dist/form/admin/sec.d.ts +0 -2
- package/dist/form/admin/sec.js +0 -10
- package/dist/form/admin/sec.js.map +0 -1
- package/dist/form/admin/slackSetting.d.ts +0 -2
- package/dist/form/admin/slackSetting.js +0 -13
- package/dist/form/admin/slackSetting.js.map +0 -1
- package/dist/form/admin/userEdit.d.ts +0 -2
- package/dist/form/admin/userEdit.js +0 -9
- package/dist/form/admin/userEdit.js.map +0 -1
- package/dist/form/admin/userInvite.d.ts +0 -2
- package/dist/form/admin/userInvite.js +0 -9
- package/dist/form/admin/userInvite.js.map +0 -1
- package/dist/form/comment.d.ts +0 -2
- package/dist/form/comment.js +0 -9
- package/dist/form/comment.js.map +0 -1
- package/dist/form/index.d.ts +0 -25
- package/dist/form/index.js +0 -48
- package/dist/form/index.js.map +0 -1
- package/dist/form/invited.d.ts +0 -2
- package/dist/form/invited.js +0 -13
- package/dist/form/invited.js.map +0 -1
- package/dist/form/login.d.ts +0 -2
- package/dist/form/login.js +0 -11
- package/dist/form/login.js.map +0 -1
- package/dist/form/me/apiToken.d.ts +0 -2
- package/dist/form/me/apiToken.js +0 -9
- package/dist/form/me/apiToken.js.map +0 -1
- package/dist/form/me/password.d.ts +0 -2
- package/dist/form/me/password.js +0 -11
- package/dist/form/me/password.js.map +0 -1
- package/dist/form/me/user.d.ts +0 -2
- package/dist/form/me/user.js +0 -9
- package/dist/form/me/user.js.map +0 -1
- package/dist/form/register.d.ts +0 -2
- package/dist/form/register.js +0 -13
- package/dist/form/register.js.map +0 -1
- package/dist/form/revision.d.ts +0 -2
- package/dist/form/revision.js +0 -13
- package/dist/form/revision.js.map +0 -1
- package/dist/hono/handlers/admin/share.d.ts +0 -106
- package/dist/hono/handlers/admin/share.js +0 -55
- package/dist/hono/handlers/admin/share.js.map +0 -1
- package/dist/middlewares/accessTokenParser.d.ts +0 -4
- package/dist/middlewares/accessTokenParser.js +0 -29
- package/dist/middlewares/accessTokenParser.js.map +0 -1
- package/dist/middlewares/adminRequired.d.ts +0 -10
- package/dist/middlewares/adminRequired.js +0 -35
- package/dist/middlewares/adminRequired.js.map +0 -1
- package/dist/middlewares/applicationInstalled.d.ts +0 -3
- package/dist/middlewares/applicationInstalled.js +0 -20
- package/dist/middlewares/applicationInstalled.js.map +0 -1
- package/dist/middlewares/applicationNotInstalled.d.ts +0 -3
- package/dist/middlewares/applicationNotInstalled.js +0 -13
- package/dist/middlewares/applicationNotInstalled.js.map +0 -1
- package/dist/middlewares/basicAuth.d.ts +0 -4
- package/dist/middlewares/basicAuth.js +0 -23
- package/dist/middlewares/basicAuth.js.map +0 -1
- package/dist/middlewares/csrfVerify.d.ts +0 -4
- package/dist/middlewares/csrfVerify.js +0 -24
- package/dist/middlewares/csrfVerify.js.map +0 -1
- package/dist/middlewares/encodeSpace.d.ts +0 -3
- package/dist/middlewares/encodeSpace.js +0 -14
- package/dist/middlewares/encodeSpace.js.map +0 -1
- package/dist/middlewares/fileAccessRightOrLoginRequired.d.ts +0 -4
- package/dist/middlewares/fileAccessRightOrLoginRequired.js +0 -29
- package/dist/middlewares/fileAccessRightOrLoginRequired.js.map +0 -1
- package/dist/middlewares/index.d.ts +0 -16
- package/dist/middlewares/index.js +0 -30
- package/dist/middlewares/index.js.map +0 -1
- package/dist/middlewares/jwtAdminRequired.d.ts +0 -8
- package/dist/middlewares/jwtAdminRequired.js +0 -35
- package/dist/middlewares/jwtAdminRequired.js.map +0 -1
- package/dist/middlewares/jwtAuth.d.ts +0 -4
- package/dist/middlewares/jwtAuth.js +0 -104
- package/dist/middlewares/jwtAuth.js.map +0 -1
- package/dist/middlewares/loginChecker.d.ts +0 -4
- package/dist/middlewares/loginChecker.js +0 -32
- package/dist/middlewares/loginChecker.js.map +0 -1
- package/dist/middlewares/loginRequired.d.ts +0 -4
- package/dist/middlewares/loginRequired.js +0 -88
- package/dist/middlewares/loginRequired.js.map +0 -1
- package/dist/routes/admin.d.ts +0 -4
- package/dist/routes/admin.js +0 -17
- package/dist/routes/admin.js.map +0 -1
- package/dist/routes/api/admin.d.ts +0 -4
- package/dist/routes/api/admin.js +0 -37
- package/dist/routes/api/admin.js.map +0 -1
- package/dist/routes/api/attachment.d.ts +0 -4
- package/dist/routes/api/attachment.js +0 -19
- package/dist/routes/api/attachment.js.map +0 -1
- package/dist/routes/api/bookmark.d.ts +0 -4
- package/dist/routes/api/bookmark.js +0 -15
- package/dist/routes/api/bookmark.js.map +0 -1
- package/dist/routes/api/comment.d.ts +0 -4
- package/dist/routes/api/comment.js +0 -14
- package/dist/routes/api/comment.js.map +0 -1
- package/dist/routes/api/index.d.ts +0 -4
- package/dist/routes/api/index.js +0 -36
- package/dist/routes/api/index.js.map +0 -1
- package/dist/routes/api/like.d.ts +0 -4
- package/dist/routes/api/like.js +0 -13
- package/dist/routes/api/like.js.map +0 -1
- package/dist/routes/api/notification.d.ts +0 -4
- package/dist/routes/api/notification.js +0 -15
- package/dist/routes/api/notification.js.map +0 -1
- package/dist/routes/api/page.d.ts +0 -4
- package/dist/routes/api/page.js +0 -24
- package/dist/routes/api/page.js.map +0 -1
- package/dist/routes/api/revision.d.ts +0 -4
- package/dist/routes/api/revision.js +0 -14
- package/dist/routes/api/revision.js.map +0 -1
- package/dist/routes/api/share.d.ts +0 -4
- package/dist/routes/api/share.js +0 -16
- package/dist/routes/api/share.js.map +0 -1
- package/dist/routes/api/version.d.ts +0 -4
- package/dist/routes/api/version.js +0 -10
- package/dist/routes/api/version.js.map +0 -1
- package/dist/routes/index.d.ts +0 -4
- package/dist/routes/index.js +0 -71
- package/dist/routes/index.js.map +0 -1
- package/dist/routes/login.d.ts +0 -4
- package/dist/routes/login.js +0 -18
- package/dist/routes/login.js.map +0 -1
- package/dist/routes/me.d.ts +0 -4
- package/dist/routes/me.js +0 -24
- package/dist/routes/me.js.map +0 -1
- package/dist/routes/ts-rest/admin/app.d.ts +0 -4
- package/dist/routes/ts-rest/admin/app.js +0 -67
- package/dist/routes/ts-rest/admin/app.js.map +0 -1
- package/dist/routes/ts-rest/admin/auth.d.ts +0 -4
- package/dist/routes/ts-rest/admin/auth.js +0 -95
- package/dist/routes/ts-rest/admin/auth.js.map +0 -1
- package/dist/routes/ts-rest/admin/index.d.ts +0 -10
- package/dist/routes/ts-rest/admin/index.js +0 -35
- package/dist/routes/ts-rest/admin/index.js.map +0 -1
- package/dist/routes/ts-rest/admin/mail.d.ts +0 -4
- package/dist/routes/ts-rest/admin/mail.js +0 -156
- package/dist/routes/ts-rest/admin/mail.js.map +0 -1
- package/dist/routes/ts-rest/admin/plugins.d.ts +0 -4
- package/dist/routes/ts-rest/admin/plugins.js +0 -317
- package/dist/routes/ts-rest/admin/plugins.js.map +0 -1
- package/dist/routes/ts-rest/admin/search.d.ts +0 -4
- package/dist/routes/ts-rest/admin/search.js +0 -67
- package/dist/routes/ts-rest/admin/search.js.map +0 -1
- package/dist/routes/ts-rest/admin/security.d.ts +0 -4
- package/dist/routes/ts-rest/admin/security.js +0 -114
- package/dist/routes/ts-rest/admin/security.js.map +0 -1
- package/dist/routes/ts-rest/admin/share.d.ts +0 -4
- package/dist/routes/ts-rest/admin/share.js +0 -69
- package/dist/routes/ts-rest/admin/share.js.map +0 -1
- package/dist/routes/ts-rest/admin/storage.d.ts +0 -4
- package/dist/routes/ts-rest/admin/storage.js +0 -59
- package/dist/routes/ts-rest/admin/storage.js.map +0 -1
- package/dist/routes/ts-rest/admin/users.d.ts +0 -4
- package/dist/routes/ts-rest/admin/users.js +0 -215
- package/dist/routes/ts-rest/admin/users.js.map +0 -1
- package/dist/routes/ts-rest/adminCrypto.d.ts +0 -4
- package/dist/routes/ts-rest/adminCrypto.js +0 -111
- package/dist/routes/ts-rest/adminCrypto.js.map +0 -1
- package/dist/routes/ts-rest/app.d.ts +0 -4
- package/dist/routes/ts-rest/app.js +0 -23
- package/dist/routes/ts-rest/app.js.map +0 -1
- package/dist/routes/ts-rest/attachment.d.ts +0 -4
- package/dist/routes/ts-rest/attachment.js +0 -830
- package/dist/routes/ts-rest/attachment.js.map +0 -1
- package/dist/routes/ts-rest/auth.d.ts +0 -4
- package/dist/routes/ts-rest/auth.js +0 -70
- package/dist/routes/ts-rest/auth.js.map +0 -1
- package/dist/routes/ts-rest/autocomplete.d.ts +0 -30
- package/dist/routes/ts-rest/autocomplete.js +0 -189
- package/dist/routes/ts-rest/autocomplete.js.map +0 -1
- package/dist/routes/ts-rest/backlink.d.ts +0 -4
- package/dist/routes/ts-rest/backlink.js +0 -106
- package/dist/routes/ts-rest/backlink.js.map +0 -1
- package/dist/routes/ts-rest/bookmark.d.ts +0 -4
- package/dist/routes/ts-rest/bookmark.js +0 -189
- package/dist/routes/ts-rest/bookmark.js.map +0 -1
- package/dist/routes/ts-rest/comment.d.ts +0 -4
- package/dist/routes/ts-rest/comment.js +0 -217
- package/dist/routes/ts-rest/comment.js.map +0 -1
- package/dist/routes/ts-rest/draft.d.ts +0 -22
- package/dist/routes/ts-rest/draft.js +0 -200
- package/dist/routes/ts-rest/draft.js.map +0 -1
- package/dist/routes/ts-rest/index.d.ts +0 -4
- package/dist/routes/ts-rest/index.js +0 -103
- package/dist/routes/ts-rest/index.js.map +0 -1
- package/dist/routes/ts-rest/installer.d.ts +0 -4
- package/dist/routes/ts-rest/installer.js +0 -77
- package/dist/routes/ts-rest/installer.js.map +0 -1
- package/dist/routes/ts-rest/me.d.ts +0 -4
- package/dist/routes/ts-rest/me.js +0 -410
- package/dist/routes/ts-rest/me.js.map +0 -1
- package/dist/routes/ts-rest/notification.d.ts +0 -4
- package/dist/routes/ts-rest/notification.js +0 -241
- package/dist/routes/ts-rest/notification.js.map +0 -1
- package/dist/routes/ts-rest/page-collab.d.ts +0 -29
- package/dist/routes/ts-rest/page-collab.js +0 -90
- package/dist/routes/ts-rest/page-collab.js.map +0 -1
- package/dist/routes/ts-rest/page-preview.d.ts +0 -26
- package/dist/routes/ts-rest/page-preview.js +0 -80
- package/dist/routes/ts-rest/page-preview.js.map +0 -1
- package/dist/routes/ts-rest/page.d.ts +0 -4
- package/dist/routes/ts-rest/page.js +0 -676
- package/dist/routes/ts-rest/page.js.map +0 -1
- package/dist/routes/ts-rest/presence.d.ts +0 -30
- package/dist/routes/ts-rest/presence.js +0 -155
- package/dist/routes/ts-rest/presence.js.map +0 -1
- package/dist/routes/ts-rest/revision.d.ts +0 -4
- package/dist/routes/ts-rest/revision.js +0 -240
- package/dist/routes/ts-rest/revision.js.map +0 -1
- package/dist/routes/ts-rest/search.d.ts +0 -4
- package/dist/routes/ts-rest/search.js +0 -121
- package/dist/routes/ts-rest/search.js.map +0 -1
- package/dist/routes/ts-rest/tokenAuth.d.ts +0 -4
- package/dist/routes/ts-rest/tokenAuth.js +0 -94
- package/dist/routes/ts-rest/tokenAuth.js.map +0 -1
- package/dist/routes/ts-rest/user.d.ts +0 -4
- package/dist/routes/ts-rest/user.js +0 -307
- package/dist/routes/ts-rest/user.js.map +0 -1
- package/dist/types/express.d.ts +0 -34
- package/dist/types/express.js +0 -50
- package/dist/types/express.js.map +0 -1
- package/dist/util/accessTokenParser.d.ts +0 -1
- package/dist/util/accessTokenParser.js +0 -34
- package/dist/util/accessTokenParser.js.map +0 -1
- package/dist/util/apiPaginate.d.ts +0 -11
- package/dist/util/apiPaginate.js +0 -33
- package/dist/util/apiPaginate.js.map +0 -1
- package/dist/util/apiResponse.d.ts +0 -9
- package/dist/util/apiResponse.js +0 -23
- package/dist/util/apiResponse.js.map +0 -1
- package/dist/util/auth.d.ts +0 -11
- package/dist/util/auth.js +0 -48
- package/dist/util/auth.js.map +0 -1
- package/dist/util/aws-config-migration.d.ts +0 -11
- package/dist/util/aws-config-migration.js +0 -68
- package/dist/util/aws-config-migration.js.map +0 -1
- package/dist/util/formUtil.d.ts +0 -2
- package/dist/util/formUtil.js +0 -15
- package/dist/util/formUtil.js.map +0 -1
- package/dist/util/githubAuth.d.ts +0 -2
- package/dist/util/githubAuth.js +0 -82
- package/dist/util/githubAuth.js.map +0 -1
- package/dist/util/googleAuth.d.ts +0 -2
- package/dist/util/googleAuth.js +0 -85
- package/dist/util/googleAuth.js.map +0 -1
- package/dist/util/mailer.d.ts +0 -7
- package/dist/util/mailer.js +0 -98
- package/dist/util/mailer.js.map +0 -1
- package/dist/util/page-status-migration.d.ts +0 -23
- package/dist/util/page-status-migration.js +0 -48
- package/dist/util/page-status-migration.js.map +0 -1
- package/dist/util/ssr.d.ts +0 -3
- package/dist/util/ssr.js +0 -9
- package/dist/util/ssr.js.map +0 -1
- package/dist/util/view.d.ts +0 -10
- package/dist/util/view.js +0 -99
- package/dist/util/view.js.map +0 -1
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Markdown code-region segmentation for the body-rewrite migrations.
|
|
4
|
+
*
|
|
5
|
+
* `WIKILINK_DETECTION_REGEX` (and the sibling `files-url` / `html-recover`
|
|
6
|
+
* probes) scan a page's *raw* body with no Markdown awareness, so `</…>`
|
|
7
|
+
* tokens written as code examples — inside a ```` ``` ```` fence or `` `…` ``
|
|
8
|
+
* inline span — get misdetected as v1 wikilinks and rewritten, corrupting the
|
|
9
|
+
* code (e.g. ```` ```tsx\n</AppShell>\n``` ```` → `[[/AppShell]]`).
|
|
10
|
+
*
|
|
11
|
+
* The renderer already solves this at the AST level — `renderer/core/
|
|
12
|
+
* wikilinks.ts` skips `node.type === 'code' || 'inlineCode'`. The migration
|
|
13
|
+
* layer cannot import the renderer pipeline (jiti/ESM), so this is a
|
|
14
|
+
* string-level parallel of that intent: split the body into ordered
|
|
15
|
+
* `code` / non-`code` segments so callers can run their rewrite **only on
|
|
16
|
+
* the non-`code` segments** and re-join in original order.
|
|
17
|
+
*
|
|
18
|
+
* Why segmentation and NOT a same-length `\x00` fill + slice restore: a fill
|
|
19
|
+
* pass keeps the body length-invariant, but the rewrite step changes the
|
|
20
|
+
* length of the *non-code* text, so a positional restore drifts. Worse, three
|
|
21
|
+
* structural failures cause silent data loss — adjacent code regions whose
|
|
22
|
+
* fills touch merge into one `/\x00+/g` match (one region is dropped), a
|
|
23
|
+
* fence-first stash with text-order restore swaps two regions, and a `\x00`
|
|
24
|
+
* already present in pasted/binary content collides with the sentinel. By
|
|
25
|
+
* returning an ordered segment list with no restore step, all three are
|
|
26
|
+
* avoided *by construction*: adjacent regions are distinct segments (no
|
|
27
|
+
* merge), order is preserved by the list (no swap), and no sentinel is ever
|
|
28
|
+
* introduced (no collision).
|
|
29
|
+
*
|
|
30
|
+
* Coverage: fenced code blocks (CommonMark §4.5, backtick **and** tilde) and
|
|
31
|
+
* inline code spans (§6.1). Indented code blocks (4-space / 1-tab, §4.4) are
|
|
32
|
+
* deliberately NOT covered: a flat "4-space line = code" rule over-suppresses
|
|
33
|
+
* (mdast treats a 4-space paragraph/list continuation line as text/html, i.e.
|
|
34
|
+
* rewritable), so an indented-code `</…>` token stays rewritable — an accepted
|
|
35
|
+
* known divergence from the renderer (see the spec's "out of scope").
|
|
36
|
+
*/
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.splitCodeSegments = splitCodeSegments;
|
|
39
|
+
exports.rewriteOutsideCode = rewriteOutsideCode;
|
|
40
|
+
/** A fenced-code-block opener: ≥3 backticks or ≥3 tildes with 0–3 leading spaces. */
|
|
41
|
+
const FENCE_OPEN_REGEX = /^( {0,3})(`{3,}|~{3,})/;
|
|
42
|
+
/**
|
|
43
|
+
* Split `body` into ordered `code` / non-`code` segments.
|
|
44
|
+
*
|
|
45
|
+
* Fenced blocks are matched line-by-line (a fence runs to its closing fence of
|
|
46
|
+
* the same char, ≥ the opening length; an unclosed fence runs to EOF). Within
|
|
47
|
+
* non-fence text, inline code spans are matched by the CommonMark §6.1 rule: an
|
|
48
|
+
* opening run of N backticks closed by the next run of *exactly* N backticks.
|
|
49
|
+
* An unmatched backtick run is left as literal non-code text.
|
|
50
|
+
*
|
|
51
|
+
* Pure: no I/O, no mutation of inputs. Concatenating the returned segments'
|
|
52
|
+
* `text` reproduces `body` byte-for-byte.
|
|
53
|
+
*/
|
|
54
|
+
function splitCodeSegments(body) {
|
|
55
|
+
const segments = [];
|
|
56
|
+
// Buffer of pending non-code text; flushed (after inline-span extraction)
|
|
57
|
+
// whenever a fence boundary or EOF is reached.
|
|
58
|
+
let pendingText = '';
|
|
59
|
+
const flushPendingText = () => {
|
|
60
|
+
if (pendingText.length === 0)
|
|
61
|
+
return;
|
|
62
|
+
for (const seg of splitInlineCode(pendingText))
|
|
63
|
+
segments.push(seg);
|
|
64
|
+
pendingText = '';
|
|
65
|
+
};
|
|
66
|
+
// Walk the body line by line, preserving each line's trailing newline so the
|
|
67
|
+
// re-join is byte-identical. `lineStart` indexes the current line's first
|
|
68
|
+
// char in `body`.
|
|
69
|
+
let lineStart = 0;
|
|
70
|
+
while (lineStart < body.length) {
|
|
71
|
+
let lineEnd = body.indexOf('\n', lineStart);
|
|
72
|
+
if (lineEnd === -1)
|
|
73
|
+
lineEnd = body.length;
|
|
74
|
+
else
|
|
75
|
+
lineEnd += 1; // include the newline
|
|
76
|
+
const line = body.slice(lineStart, lineEnd);
|
|
77
|
+
// No `\r?\n` strip on the opener: `FENCE_OPEN_REGEX` is `^`-anchored and
|
|
78
|
+
// carries no end-of-line pattern, so a trailing newline never affects the
|
|
79
|
+
// match (unlike the closing-fence test below, where the strip is
|
|
80
|
+
// load-bearing — see `closeRegex.test(...)`).
|
|
81
|
+
const fenceMatch = FENCE_OPEN_REGEX.exec(line);
|
|
82
|
+
if (fenceMatch) {
|
|
83
|
+
// A fenced code block opens here. Flush text accumulated before it, then
|
|
84
|
+
// consume lines up to (and including) the matching closing fence or EOF.
|
|
85
|
+
flushPendingText();
|
|
86
|
+
// `fenceChar` is exactly one of `` ` `` / `~` because group 2 of
|
|
87
|
+
// `FENCE_OPEN_REGEX` is `` (`{3,}|~{3,}) ``, so it can be inlined into the
|
|
88
|
+
// close pattern verbatim (no per-char ternary needed).
|
|
89
|
+
const fenceChar = fenceMatch[2][0];
|
|
90
|
+
const fenceLen = fenceMatch[2].length;
|
|
91
|
+
const closeRegex = new RegExp(`^ {0,3}${fenceChar}{${fenceLen},}[ \\t]*$`);
|
|
92
|
+
// Consume lines up to (and including) the closing fence; an unclosed
|
|
93
|
+
// fence runs to EOF. Either way the whole span is one code segment.
|
|
94
|
+
let fenceText = line;
|
|
95
|
+
let cursor = lineEnd;
|
|
96
|
+
while (cursor < body.length) {
|
|
97
|
+
let nextEnd = body.indexOf('\n', cursor);
|
|
98
|
+
if (nextEnd === -1)
|
|
99
|
+
nextEnd = body.length;
|
|
100
|
+
else
|
|
101
|
+
nextEnd += 1;
|
|
102
|
+
const nextLine = body.slice(cursor, nextEnd);
|
|
103
|
+
fenceText += nextLine;
|
|
104
|
+
cursor = nextEnd;
|
|
105
|
+
// The `\r?\n` strip here is LOAD-BEARING — do NOT remove it. `closeRegex`
|
|
106
|
+
// ends in `[ \t]*$` and is built with no `m` flag, so its `$` anchors at
|
|
107
|
+
// end-of-string. `nextLine` still carries its trailing newline (we keep
|
|
108
|
+
// it for a byte-identical re-join), and `[ \t]*` cannot consume a `\n`,
|
|
109
|
+
// so without the strip the close test fails on every newline-terminated
|
|
110
|
+
// fence line (CRLF or LF). The fence would then run to EOF, wrongly
|
|
111
|
+
// swallowing text that follows the closing fence into the code segment.
|
|
112
|
+
// (An EOF-only fence happens to pass either way because `$` also matches
|
|
113
|
+
// end-of-string — which is why a content-after-close-fence test is what
|
|
114
|
+
// actually guards this. See code-mask.test.ts.)
|
|
115
|
+
if (closeRegex.test(nextLine.replace(/\r?\n$/, '')))
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
segments.push({ code: true, text: fenceText });
|
|
119
|
+
lineStart = cursor;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
pendingText += line;
|
|
123
|
+
lineStart = lineEnd;
|
|
124
|
+
}
|
|
125
|
+
flushPendingText();
|
|
126
|
+
// The common "no code at all" body yields exactly one `{ code: false }`
|
|
127
|
+
// segment (the whole body, via `splitInlineCode`'s trailing `pushPlain`), so
|
|
128
|
+
// the caller's by-reference cheap-skip still works on the re-join.
|
|
129
|
+
return segments;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Apply `fn` only to the non-code segments of `body`, re-joining in original
|
|
133
|
+
* order. Returns `body` BY REFERENCE when `fn` left every non-code segment
|
|
134
|
+
* unchanged (preserving the caller's `result === body` cheap-skip for
|
|
135
|
+
* isPending). Code regions (fenced + inline, per `splitCodeSegments`) are
|
|
136
|
+
* passed through byte-identical.
|
|
137
|
+
*
|
|
138
|
+
* `fn` may be impure (carry an accumulator in a closure) — e.g. a `body.replace`
|
|
139
|
+
* callback that pushes occurrences / bumps counts. It is invoked once per
|
|
140
|
+
* non-code segment in document order; the code segments between them are never
|
|
141
|
+
* passed to `fn`, so a token written as a code example stays untouched and is
|
|
142
|
+
* never misdetected.
|
|
143
|
+
*
|
|
144
|
+
* This is the shared entry point for all three body-rewrite migrations
|
|
145
|
+
* (`wikilink-format`, `files-url-to-attachments`, `wikilink-html-recover`); the
|
|
146
|
+
* segment-and-rewrite scheme (vs. a fill/restore one) is justified in this
|
|
147
|
+
* file's header. The by-reference cheap-skip is owned here, via per-segment
|
|
148
|
+
* `!==` identity tracking, so a caller that still keeps its own accumulator
|
|
149
|
+
* guard stays consistent (both agree on "changed").
|
|
150
|
+
*/
|
|
151
|
+
function rewriteOutsideCode(body, fn) {
|
|
152
|
+
let changed = false;
|
|
153
|
+
const out = splitCodeSegments(body).map((seg) => {
|
|
154
|
+
if (seg.code)
|
|
155
|
+
return seg.text;
|
|
156
|
+
const next = fn(seg.text);
|
|
157
|
+
if (next !== seg.text)
|
|
158
|
+
changed = true;
|
|
159
|
+
return next;
|
|
160
|
+
});
|
|
161
|
+
return changed ? out.join('') : body;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Split a run of non-fence text into inline-code (`code: true`) and plain
|
|
165
|
+
* (`code: false`) segments per CommonMark §6.1: an opening run of N backticks
|
|
166
|
+
* closed by the next run of *exactly* N backticks is a code span. An unmatched
|
|
167
|
+
* backtick run stays literal (folded into the surrounding plain segment).
|
|
168
|
+
*/
|
|
169
|
+
function splitInlineCode(text) {
|
|
170
|
+
const segments = [];
|
|
171
|
+
let plainStart = 0;
|
|
172
|
+
let i = 0;
|
|
173
|
+
const pushPlain = (end) => {
|
|
174
|
+
if (end > plainStart)
|
|
175
|
+
segments.push({ code: false, text: text.slice(plainStart, end) });
|
|
176
|
+
};
|
|
177
|
+
while (i < text.length) {
|
|
178
|
+
if (text[i] !== '`') {
|
|
179
|
+
i += 1;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
// Measure the opening backtick run length.
|
|
183
|
+
const openStart = i;
|
|
184
|
+
let runLen = 0;
|
|
185
|
+
while (i < text.length && text[i] === '`') {
|
|
186
|
+
runLen += 1;
|
|
187
|
+
i += 1;
|
|
188
|
+
}
|
|
189
|
+
// Look for a closing run of exactly `runLen` backticks.
|
|
190
|
+
let scan = i;
|
|
191
|
+
let closeStart = -1;
|
|
192
|
+
while (scan < text.length) {
|
|
193
|
+
if (text[scan] !== '`') {
|
|
194
|
+
scan += 1;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
let closeLen = 0;
|
|
198
|
+
const thisRunStart = scan;
|
|
199
|
+
while (scan < text.length && text[scan] === '`') {
|
|
200
|
+
closeLen += 1;
|
|
201
|
+
scan += 1;
|
|
202
|
+
}
|
|
203
|
+
if (closeLen === runLen) {
|
|
204
|
+
closeStart = thisRunStart;
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
// A run of a different length is not a valid closer; keep scanning.
|
|
208
|
+
}
|
|
209
|
+
if (closeStart === -1) {
|
|
210
|
+
// Unmatched opener — leave the backtick run as literal text and continue
|
|
211
|
+
// scanning from just after it (so a later valid span is still found).
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
// Emit the plain text before the span, then the span itself.
|
|
215
|
+
pushPlain(openStart);
|
|
216
|
+
const spanEnd = closeStart + runLen;
|
|
217
|
+
segments.push({ code: true, text: text.slice(openStart, spanEnd) });
|
|
218
|
+
plainStart = spanEnd;
|
|
219
|
+
i = spanEnd;
|
|
220
|
+
}
|
|
221
|
+
pushPlain(text.length);
|
|
222
|
+
return segments;
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=code-mask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-mask.js","sourceRoot":"","sources":["../../../src/migration/migrations/code-mask.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;;AAyBH,8CA4EC;AAsBD,gDASC;AA1HD,qFAAqF;AACrF,MAAM,gBAAgB,GAAG,wBAAwB,CAAC;AAElD;;;;;;;;;;;GAWG;AACH,SAAgB,iBAAiB,CAAC,IAAY;IAC5C,MAAM,QAAQ,GAAkB,EAAE,CAAC;IACnC,0EAA0E;IAC1E,+CAA+C;IAC/C,IAAI,WAAW,GAAG,EAAE,CAAC;IAErB,MAAM,gBAAgB,GAAG,GAAS,EAAE;QAClC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACrC,KAAK,MAAM,GAAG,IAAI,eAAe,CAAC,WAAW,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnE,WAAW,GAAG,EAAE,CAAC;IACnB,CAAC,CAAC;IAEF,6EAA6E;IAC7E,0EAA0E;IAC1E,kBAAkB;IAClB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,OAAO,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC/B,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC5C,IAAI,OAAO,KAAK,CAAC,CAAC;YAAE,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;;YACrC,OAAO,IAAI,CAAC,CAAC,CAAC,sBAAsB;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAE5C,yEAAyE;QACzE,0EAA0E;QAC1E,iEAAiE;QACjE,8CAA8C;QAC9C,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,UAAU,EAAE,CAAC;YACf,yEAAyE;YACzE,yEAAyE;YACzE,gBAAgB,EAAE,CAAC;YACnB,iEAAiE;YACjE,2EAA2E;YAC3E,uDAAuD;YACvD,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACtC,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,UAAU,SAAS,IAAI,QAAQ,YAAY,CAAC,CAAC;YAE3E,qEAAqE;YACrE,oEAAoE;YACpE,IAAI,SAAS,GAAG,IAAI,CAAC;YACrB,IAAI,MAAM,GAAG,OAAO,CAAC;YACrB,OAAO,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC5B,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBACzC,IAAI,OAAO,KAAK,CAAC,CAAC;oBAAE,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;;oBACrC,OAAO,IAAI,CAAC,CAAC;gBAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC7C,SAAS,IAAI,QAAQ,CAAC;gBACtB,MAAM,GAAG,OAAO,CAAC;gBACjB,0EAA0E;gBAC1E,yEAAyE;gBACzE,wEAAwE;gBACxE,wEAAwE;gBACxE,wEAAwE;gBACxE,oEAAoE;gBACpE,wEAAwE;gBACxE,yEAAyE;gBACzE,wEAAwE;gBACxE,gDAAgD;gBAChD,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;oBAAE,MAAM;YAC7D,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;YAC/C,SAAS,GAAG,MAAM,CAAC;YACnB,SAAS;QACX,CAAC;QAED,WAAW,IAAI,IAAI,CAAC;QACpB,SAAS,GAAG,OAAO,CAAC;IACtB,CAAC;IAED,gBAAgB,EAAE,CAAC;IAEnB,wEAAwE;IACxE,6EAA6E;IAC7E,mEAAmE;IACnE,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAgB,kBAAkB,CAAC,IAAY,EAAE,EAA4B;IAC3E,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC9C,IAAI,GAAG,CAAC,IAAI;YAAE,OAAO,GAAG,CAAC,IAAI,CAAC;QAC9B,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI;YAAE,OAAO,GAAG,IAAI,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACvC,CAAC;AAED;;;;;GAKG;AACH,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,QAAQ,GAAkB,EAAE,CAAC;IACnC,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,MAAM,SAAS,GAAG,CAAC,GAAW,EAAQ,EAAE;QACtC,IAAI,GAAG,GAAG,UAAU;YAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IAC1F,CAAC,CAAC;IAEF,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACpB,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACX,CAAC;QACD,2CAA2C;QAC3C,MAAM,SAAS,GAAG,CAAC,CAAC;QACpB,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YAC1C,MAAM,IAAI,CAAC,CAAC;YACZ,CAAC,IAAI,CAAC,CAAC;QACT,CAAC;QACD,wDAAwD;QACxD,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC;QACpB,OAAO,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAC1B,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;gBACvB,IAAI,IAAI,CAAC,CAAC;gBACV,SAAS;YACX,CAAC;YACD,IAAI,QAAQ,GAAG,CAAC,CAAC;YACjB,MAAM,YAAY,GAAG,IAAI,CAAC;YAC1B,OAAO,IAAI,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;gBAChD,QAAQ,IAAI,CAAC,CAAC;gBACd,IAAI,IAAI,CAAC,CAAC;YACZ,CAAC;YACD,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;gBACxB,UAAU,GAAG,YAAY,CAAC;gBAC1B,MAAM;YACR,CAAC;YACD,oEAAoE;QACtE,CAAC;QAED,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;YACtB,yEAAyE;YACzE,sEAAsE;YACtE,SAAS;QACX,CAAC;QAED,6DAA6D;QAC7D,SAAS,CAAC,SAAS,CAAC,CAAC;QACrB,MAAM,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;QACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACpE,UAAU,GAAG,OAAO,CAAC;QACrB,CAAC,GAAG,OAAO,CAAC;IACd,CAAC;IAED,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { MigrationContext } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Per-body breakdown of what a rewrite touched / skipped, returned alongside
|
|
4
|
+
* the rewritten body so callers walk the regex once.
|
|
5
|
+
* - `relative`: rule 1 (relative `/files/<id>`) rewrites.
|
|
6
|
+
* - `selfHostAbsolute`: rule 2 (self-host absolute) rewrites.
|
|
7
|
+
* - `externalSkipped`: rule 3 (external absolute) left untouched.
|
|
8
|
+
*/
|
|
9
|
+
export interface FilesUrlRewriteCounts {
|
|
10
|
+
relative: number;
|
|
11
|
+
selfHostAbsolute: number;
|
|
12
|
+
externalSkipped: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Single-pass detect-and-rewrite. Returns the rewritten body plus a count
|
|
16
|
+
* breakdown so callers don't walk the regex twice. Pure — no I/O. Returns
|
|
17
|
+
* `body` by reference when nothing changed (no rule-1/2 rewrite), letting
|
|
18
|
+
* callers cheap-skip via `result.body === body`.
|
|
19
|
+
*
|
|
20
|
+
* `origins` is the self-host allow-list (`getAppOrigins()`); pass `[]` to
|
|
21
|
+
* disable rule 2 (CLIENT_URL / BASE_URL unset).
|
|
22
|
+
*
|
|
23
|
+
* Code regions (fenced blocks + inline spans) are excluded via the shared
|
|
24
|
+
* `rewriteOutsideCode` primitive: a `/files/<id>` written as a code example is
|
|
25
|
+
* left byte-identical (never rewritten, never counted) so it cannot be
|
|
26
|
+
* corrupted, nor falsely report the migration as pending. Indented code is an
|
|
27
|
+
* accepted divergence (still rewritten). AD-2 (an `` whose alt text
|
|
28
|
+
* contains an inline-code span straddles a segment boundary, leaving its URL
|
|
29
|
+
* unrewritten) is documented in the spec — an accepted false-negative.
|
|
30
|
+
*/
|
|
31
|
+
export declare function rewriteFilesUrls(body: string, origins: readonly string[]): {
|
|
32
|
+
body: string;
|
|
33
|
+
counts: FilesUrlRewriteCounts;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* True iff `body` holds at least one *rewritable* v1 file URL — a relative
|
|
37
|
+
* `/files/<id>` or a self-host absolute one (external-only bodies report
|
|
38
|
+
* false). `/files/` is a cheap prefilter so bodies that can't contain one skip
|
|
39
|
+
* the regex; the verdict itself is the full rule (external skips don't count)
|
|
40
|
+
* so a body whose only `/files/<id>` is external correctly reports false.
|
|
41
|
+
* Shared by `isPending` and `collectRewritablePages`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function bodyHasRewritableFilesUrl(body: string, origins: readonly string[]): boolean;
|
|
44
|
+
export declare const filesUrlToAttachments: {
|
|
45
|
+
id: string;
|
|
46
|
+
fromVersion: string;
|
|
47
|
+
toVersion: string;
|
|
48
|
+
layer: "preflight";
|
|
49
|
+
severity: "cosmetic";
|
|
50
|
+
description: string;
|
|
51
|
+
/**
|
|
52
|
+
* Pending verdict = at least one published page whose **current** revision
|
|
53
|
+
* body still contains a rewritable v1 file URL. Mirrors `wikilink-format`:
|
|
54
|
+
*
|
|
55
|
+
* 1. The verdict uses the **full rule** (`bodyHasRewritableFilesUrl`), not
|
|
56
|
+
* the bare substring. `/files/` could appear in an external URL we leave
|
|
57
|
+
* alone (rule 3); counting that would report pending forever after apply
|
|
58
|
+
* (apply only rewrites self URLs), deadlocking boot under preflight +
|
|
59
|
+
* `block`. The full rule reports false once only external `/files/`
|
|
60
|
+
* references remain, so boot clears.
|
|
61
|
+
* 2. We scan only each page's **current** revision, never the whole
|
|
62
|
+
* `revisions` collection — historical revisions keep their original
|
|
63
|
+
* `/files/<id>` text forever (immutable), so a collection-wide scan
|
|
64
|
+
* would pend permanently after any such page ever existed.
|
|
65
|
+
*
|
|
66
|
+
* Short-circuits at the first rewritable page.
|
|
67
|
+
*/
|
|
68
|
+
isPending: (ctx: MigrationContext) => Promise<boolean>;
|
|
69
|
+
/**
|
|
70
|
+
* Full scan for `plan`: affected page count plus the rewrite breakdown
|
|
71
|
+
* (relative / self-host absolute rewrites + external skips, the last
|
|
72
|
+
* aggregated across every `/files/` page — see `scanFilesUrls`). Not called
|
|
73
|
+
* at boot.
|
|
74
|
+
*/
|
|
75
|
+
detect: (ctx: MigrationContext) => Promise<{
|
|
76
|
+
summary: string;
|
|
77
|
+
counts: {
|
|
78
|
+
pages: number;
|
|
79
|
+
rewrites: number;
|
|
80
|
+
relative: number;
|
|
81
|
+
selfHostAbsolute: number;
|
|
82
|
+
externalSkipped: number;
|
|
83
|
+
};
|
|
84
|
+
}>;
|
|
85
|
+
stages: {
|
|
86
|
+
name: string;
|
|
87
|
+
fn: (ctx: MigrationContext) => Promise<{
|
|
88
|
+
name: string;
|
|
89
|
+
transformed: number;
|
|
90
|
+
stats: {
|
|
91
|
+
wouldRewrite: number;
|
|
92
|
+
};
|
|
93
|
+
} | {
|
|
94
|
+
name: string;
|
|
95
|
+
transformed: number;
|
|
96
|
+
stats?: undefined;
|
|
97
|
+
}>;
|
|
98
|
+
}[];
|
|
99
|
+
};
|
|
@@ -0,0 +1,305 @@
|
|
|
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.filesUrlToAttachments = void 0;
|
|
7
|
+
exports.rewriteFilesUrls = rewriteFilesUrls;
|
|
8
|
+
exports.bodyHasRewritableFilesUrl = bodyHasRewritableFilesUrl;
|
|
9
|
+
const linkDetector_1 = __importDefault(require("../../util/linkDetector"));
|
|
10
|
+
const page_1 = require("../../models/page");
|
|
11
|
+
const helpers_1 = require("../helpers");
|
|
12
|
+
const types_1 = require("../types");
|
|
13
|
+
const code_mask_1 = require("./code-mask");
|
|
14
|
+
/**
|
|
15
|
+
* v1 → v2 — `files-url-to-attachments` (preflight layer).
|
|
16
|
+
*
|
|
17
|
+
* v1 embedded attachment / image references in page bodies as the v1 file
|
|
18
|
+
* URL `/files/<24hex>` (absolute `https://<host>/files/<id>` when the editor
|
|
19
|
+
* pasted a full URL, or relative `/files/<id>`). v2 serves attachments from a
|
|
20
|
+
* dedicated stream route at `/api/v2/attachments/<id>` and the legacy
|
|
21
|
+
* `/files/<id>` compat redirect was removed with the Express host (RFC-0006
|
|
22
|
+
* Phase 6 Sub-batch D), so those v1 URLs now 404 — every such image is
|
|
23
|
+
* broken. The id is identical in both forms (the same 24-hex `Attachment._id`;
|
|
24
|
+
* `attachment.ts` `ATTACHMENT_URI_RE` extracts the same id from either), so the
|
|
25
|
+
* fix is a pure URL rewrite — no id mapping.
|
|
26
|
+
*
|
|
27
|
+
* Modelled on `wikilink-format.ts` (the sibling v1→v2 body-rewrite preflight):
|
|
28
|
+
* walk published (+ legacy `null`) pages, rewrite each current-revision body
|
|
29
|
+
* with a single-pass detect-and-rewrite, route every write through
|
|
30
|
+
* `ctx.rewritePageBody` (the `updatePage`-equivalent path that nulls
|
|
31
|
+
* `yjsState` / `yjsCheckpointAt` so an active editor can't revert the rewrite
|
|
32
|
+
* from a stale `Y.Doc` — see wikilink-format §4.3.1), and use a cheap
|
|
33
|
+
* substring prefilter (`/files/`) before the detail regex in `isPending`.
|
|
34
|
+
*
|
|
35
|
+
* Rewrite rules (Markdown `` images and `[text](url)` links only —
|
|
36
|
+
* raw HTML `<img src>` / `<a href>` is out of scope; v1 emitted Markdown):
|
|
37
|
+
*
|
|
38
|
+
* 1. relative `/files/<id>` → `/api/v2/attachments/<id>`
|
|
39
|
+
* (unconditional — a root-relative path is always this site).
|
|
40
|
+
* 2. self-host absolute `https://<origin>/files/<id>`
|
|
41
|
+
* → `/api/v2/attachments/<id>`
|
|
42
|
+
* (relativised — drops the host so the URL is portable). `<origin>` must
|
|
43
|
+
* match `linkDetector.getAppOrigins()` (CLIENT_URL / BASE_URL).
|
|
44
|
+
* 3. external absolute `https://other/files/<id>` → left untouched
|
|
45
|
+
* (we must not rewrite an unrelated third-party `/files/<id>` image).
|
|
46
|
+
*
|
|
47
|
+
* Host moves (v1 domain ≠ v2 domain) are out of scope: the separate `replace
|
|
48
|
+
* url` admin-cli command rewrites the old host → new host first, after which
|
|
49
|
+
* the self-host absolute URLs match CLIENT_URL and rule 2 relativises them.
|
|
50
|
+
*
|
|
51
|
+
* Idempotent: the output `/api/v2/attachments/<id>` never matches the
|
|
52
|
+
* `/files/` regex, so a re-apply is a no-op (no double rewrite).
|
|
53
|
+
*
|
|
54
|
+
* CLIENT_URL / BASE_URL unset: `getAppOrigins()` returns `[]`, so the
|
|
55
|
+
* self-host alternation is empty and rule 2 is skipped — only relative
|
|
56
|
+
* `/files/<id>` (rule 1) is rewritten and absolute URLs are left alone.
|
|
57
|
+
*/
|
|
58
|
+
/** v2 attachment URL prefix the rewrite targets. */
|
|
59
|
+
const V2_ATTACHMENT_PREFIX = '/api/v2/attachments/';
|
|
60
|
+
/**
|
|
61
|
+
* Substring that necessarily precedes every rewritable v1 file URL: `/files/`.
|
|
62
|
+
* Cheapest probe guaranteed present whenever a real `/files/<id>` reference
|
|
63
|
+
* exists, so a body without it can skip the regex entirely (no false
|
|
64
|
+
* negatives). The actual verdict still applies the full detect rule — see
|
|
65
|
+
* `bodyHasRewritableFilesUrl`.
|
|
66
|
+
*/
|
|
67
|
+
const FILES_SUBSTRING_PROBE = '/files/';
|
|
68
|
+
const emptyCounts = () => ({ relative: 0, selfHostAbsolute: 0, externalSkipped: 0 });
|
|
69
|
+
/**
|
|
70
|
+
* Build the per-body rewrite regex. It matches a Markdown image/link whose URL
|
|
71
|
+
* payload points at `/files/<24hex>` in one of two forms:
|
|
72
|
+
*
|
|
73
|
+
* - relative: the URL part starts with `/files/<id>`
|
|
74
|
+
* - absolute: the URL part is `<scheme>://<host>.../files/<id>`
|
|
75
|
+
*
|
|
76
|
+
* The `![alt]` / `[text]` head and the trailing path/query/fragment after the
|
|
77
|
+
* id are captured verbatim and re-emitted unchanged; only the host + `/files/`
|
|
78
|
+
* → `/api/v2/attachments/` portion is rewritten. Self-host classification of
|
|
79
|
+
* absolute URLs is decided in the callback (not the regex) so external hosts
|
|
80
|
+
* fall through untouched.
|
|
81
|
+
*
|
|
82
|
+
* A fresh `RegExp` per call keeps `lastIndex` state local (the regex is `g`).
|
|
83
|
+
*/
|
|
84
|
+
function buildFilesUrlRegex() {
|
|
85
|
+
// Group layout:
|
|
86
|
+
// 1: the markdown head `![alt]` or `[text]` (incl. the leading `!` if image)
|
|
87
|
+
// 2: optional `<scheme>://<host>` for an absolute URL (undefined when relative)
|
|
88
|
+
// 3: the 24-hex attachment id
|
|
89
|
+
// 4: the trailing remainder inside the parens after the id (path/query/#),
|
|
90
|
+
// excluding the closing `)` and whitespace
|
|
91
|
+
return /(!?\[[^\]]*\])\((https?:\/\/[^\s)/]+)?\/files\/([0-9a-fA-F]{24})([^\s)]*)\)/g;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Decide whether an absolute URL's `<scheme>://<host>` prefix belongs to this
|
|
95
|
+
* Crowi instance. `origins` are the normalised `getAppOrigins()` values
|
|
96
|
+
* (trailing slash trimmed). A match means the URL is self-host and should be
|
|
97
|
+
* relativised (rule 2); a non-match is external and left untouched (rule 3).
|
|
98
|
+
*
|
|
99
|
+
* The match is exact against the captured `<scheme>://<host>` (no path), so
|
|
100
|
+
* `https://wiki.example.com` matches origin `https://wiki.example.com` but not
|
|
101
|
+
* `https://evil.example.com`.
|
|
102
|
+
*/
|
|
103
|
+
function isSelfHostOrigin(schemeAndHost, origins) {
|
|
104
|
+
return origins.includes(schemeAndHost);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Single-pass detect-and-rewrite. Returns the rewritten body plus a count
|
|
108
|
+
* breakdown so callers don't walk the regex twice. Pure — no I/O. Returns
|
|
109
|
+
* `body` by reference when nothing changed (no rule-1/2 rewrite), letting
|
|
110
|
+
* callers cheap-skip via `result.body === body`.
|
|
111
|
+
*
|
|
112
|
+
* `origins` is the self-host allow-list (`getAppOrigins()`); pass `[]` to
|
|
113
|
+
* disable rule 2 (CLIENT_URL / BASE_URL unset).
|
|
114
|
+
*
|
|
115
|
+
* Code regions (fenced blocks + inline spans) are excluded via the shared
|
|
116
|
+
* `rewriteOutsideCode` primitive: a `/files/<id>` written as a code example is
|
|
117
|
+
* left byte-identical (never rewritten, never counted) so it cannot be
|
|
118
|
+
* corrupted, nor falsely report the migration as pending. Indented code is an
|
|
119
|
+
* accepted divergence (still rewritten). AD-2 (an `` whose alt text
|
|
120
|
+
* contains an inline-code span straddles a segment boundary, leaving its URL
|
|
121
|
+
* unrewritten) is documented in the spec — an accepted false-negative.
|
|
122
|
+
*/
|
|
123
|
+
function rewriteFilesUrls(body, origins) {
|
|
124
|
+
const counts = emptyCounts();
|
|
125
|
+
const rewriteSegment = (text) => text.replace(buildFilesUrlRegex(), (whole, head, schemeAndHost, id, rest) => {
|
|
126
|
+
if (schemeAndHost === undefined) {
|
|
127
|
+
// Rule 1 — relative `/files/<id>` is unconditionally this site.
|
|
128
|
+
counts.relative += 1;
|
|
129
|
+
return `${head}(${V2_ATTACHMENT_PREFIX}${id}${rest})`;
|
|
130
|
+
}
|
|
131
|
+
if (isSelfHostOrigin(schemeAndHost, origins)) {
|
|
132
|
+
// Rule 2 — self-host absolute URL; relativise (drop the host).
|
|
133
|
+
counts.selfHostAbsolute += 1;
|
|
134
|
+
return `${head}(${V2_ATTACHMENT_PREFIX}${id}${rest})`;
|
|
135
|
+
}
|
|
136
|
+
// Rule 3 — external host; leave untouched.
|
|
137
|
+
counts.externalSkipped += 1;
|
|
138
|
+
return whole;
|
|
139
|
+
});
|
|
140
|
+
const rewritten = (0, code_mask_1.rewriteOutsideCode)(body, rewriteSegment);
|
|
141
|
+
const changed = counts.relative > 0 || counts.selfHostAbsolute > 0;
|
|
142
|
+
return { body: changed ? rewritten : body, counts };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* True iff `body` holds at least one *rewritable* v1 file URL — a relative
|
|
146
|
+
* `/files/<id>` or a self-host absolute one (external-only bodies report
|
|
147
|
+
* false). `/files/` is a cheap prefilter so bodies that can't contain one skip
|
|
148
|
+
* the regex; the verdict itself is the full rule (external skips don't count)
|
|
149
|
+
* so a body whose only `/files/<id>` is external correctly reports false.
|
|
150
|
+
* Shared by `isPending` and `collectRewritablePages`.
|
|
151
|
+
*/
|
|
152
|
+
function bodyHasRewritableFilesUrl(body, origins) {
|
|
153
|
+
if (!body.includes(FILES_SUBSTRING_PROBE))
|
|
154
|
+
return false;
|
|
155
|
+
const { counts } = rewriteFilesUrls(body, origins);
|
|
156
|
+
return counts.relative > 0 || counts.selfHostAbsolute > 0;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* The self-host origins for the current instance, via the same
|
|
160
|
+
* `linkDetector.getAppOrigins()` helper backlink classification uses
|
|
161
|
+
* (CLIENT_URL + BASE_URL, trailing slash trimmed, deduped). Returns `[]` when
|
|
162
|
+
* neither is configured — rule 2 is then disabled (relative-only rewrite).
|
|
163
|
+
*/
|
|
164
|
+
function resolveAppOrigins(ctx) {
|
|
165
|
+
return (0, linkDetector_1.default)(ctx.crowi).getAppOrigins();
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* One full scan of every published (+ legacy `null`) page (trash & deprecated
|
|
169
|
+
* are read-only fixtures — same scope as `wikilink-format`). Returns:
|
|
170
|
+
* - `rewritable`: the pages that actually change (≥1 relative / self-host
|
|
171
|
+
* rewrite), each with its rewritten body for `ctx.rewritePageBody`.
|
|
172
|
+
* - `totals`: the rewrite breakdown aggregated across **every** page with a
|
|
173
|
+
* `/files/` reference (so `externalSkipped` reflects external URLs even on
|
|
174
|
+
* pages with no rewritable URL — an operator signal for "why some /files/
|
|
175
|
+
* references remain").
|
|
176
|
+
* Stream-walks so memory stays constant on large installs.
|
|
177
|
+
*/
|
|
178
|
+
async function scanFilesUrls(ctx, origins) {
|
|
179
|
+
const Page = ctx.crowi.model('Page');
|
|
180
|
+
const Revision = ctx.crowi.model('Revision');
|
|
181
|
+
const rewritable = [];
|
|
182
|
+
const totals = emptyCounts();
|
|
183
|
+
const cursor = Page.find({ $or: [{ status: page_1.STATUS_PUBLISHED }, { status: null }] })
|
|
184
|
+
.select('_id revision')
|
|
185
|
+
.lean()
|
|
186
|
+
.cursor();
|
|
187
|
+
for await (const page of cursor) {
|
|
188
|
+
const pageDoc = page;
|
|
189
|
+
if (!pageDoc.revision)
|
|
190
|
+
continue;
|
|
191
|
+
const revision = await Revision.findById(pageDoc.revision).select('body').lean().exec();
|
|
192
|
+
const body = revision?.body;
|
|
193
|
+
if (typeof body !== 'string')
|
|
194
|
+
continue;
|
|
195
|
+
if (!body.includes(FILES_SUBSTRING_PROBE))
|
|
196
|
+
continue;
|
|
197
|
+
const result = rewriteFilesUrls(body, origins);
|
|
198
|
+
totals.relative += result.counts.relative;
|
|
199
|
+
totals.selfHostAbsolute += result.counts.selfHostAbsolute;
|
|
200
|
+
totals.externalSkipped += result.counts.externalSkipped;
|
|
201
|
+
if (result.body === body)
|
|
202
|
+
continue;
|
|
203
|
+
rewritable.push({ pageId: String(pageDoc._id), newBody: result.body, counts: result.counts });
|
|
204
|
+
}
|
|
205
|
+
return { rewritable, totals };
|
|
206
|
+
}
|
|
207
|
+
exports.filesUrlToAttachments = (0, types_1.defineMigration)({
|
|
208
|
+
id: 'files-url-to-attachments',
|
|
209
|
+
fromVersion: '1.x',
|
|
210
|
+
toVersion: '2.1',
|
|
211
|
+
layer: 'preflight',
|
|
212
|
+
// Body URL rewrite only; a `/files/<id>` → 302 fallback keeps pages working
|
|
213
|
+
// even unapplied. `isPending` scans the live corpus → re-triggers on new
|
|
214
|
+
// content. Cosmetic.
|
|
215
|
+
severity: 'cosmetic',
|
|
216
|
+
description: 'Rewrite v1 /files/<id> attachment URLs to v2 /api/v2/attachments/<id>',
|
|
217
|
+
/**
|
|
218
|
+
* Pending verdict = at least one published page whose **current** revision
|
|
219
|
+
* body still contains a rewritable v1 file URL. Mirrors `wikilink-format`:
|
|
220
|
+
*
|
|
221
|
+
* 1. The verdict uses the **full rule** (`bodyHasRewritableFilesUrl`), not
|
|
222
|
+
* the bare substring. `/files/` could appear in an external URL we leave
|
|
223
|
+
* alone (rule 3); counting that would report pending forever after apply
|
|
224
|
+
* (apply only rewrites self URLs), deadlocking boot under preflight +
|
|
225
|
+
* `block`. The full rule reports false once only external `/files/`
|
|
226
|
+
* references remain, so boot clears.
|
|
227
|
+
* 2. We scan only each page's **current** revision, never the whole
|
|
228
|
+
* `revisions` collection — historical revisions keep their original
|
|
229
|
+
* `/files/<id>` text forever (immutable), so a collection-wide scan
|
|
230
|
+
* would pend permanently after any such page ever existed.
|
|
231
|
+
*
|
|
232
|
+
* Short-circuits at the first rewritable page.
|
|
233
|
+
*/
|
|
234
|
+
isPending: async (ctx) => {
|
|
235
|
+
const origins = resolveAppOrigins(ctx);
|
|
236
|
+
const Page = ctx.crowi.model('Page');
|
|
237
|
+
const Revision = ctx.crowi.model('Revision');
|
|
238
|
+
const cursor = Page.find({ $or: [{ status: page_1.STATUS_PUBLISHED }, { status: null }] })
|
|
239
|
+
.select('_id revision')
|
|
240
|
+
.lean()
|
|
241
|
+
.cursor();
|
|
242
|
+
for await (const page of cursor) {
|
|
243
|
+
const revisionId = page.revision;
|
|
244
|
+
if (!revisionId)
|
|
245
|
+
continue;
|
|
246
|
+
const revision = await Revision.findById(revisionId).select('body').lean().exec();
|
|
247
|
+
const body = revision?.body;
|
|
248
|
+
if (typeof body === 'string' && bodyHasRewritableFilesUrl(body, origins)) {
|
|
249
|
+
await cursor.close();
|
|
250
|
+
return true;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return false;
|
|
254
|
+
},
|
|
255
|
+
/**
|
|
256
|
+
* Full scan for `plan`: affected page count plus the rewrite breakdown
|
|
257
|
+
* (relative / self-host absolute rewrites + external skips, the last
|
|
258
|
+
* aggregated across every `/files/` page — see `scanFilesUrls`). Not called
|
|
259
|
+
* at boot.
|
|
260
|
+
*/
|
|
261
|
+
detect: async (ctx) => {
|
|
262
|
+
const origins = resolveAppOrigins(ctx);
|
|
263
|
+
const { rewritable, totals } = await scanFilesUrls(ctx, origins);
|
|
264
|
+
const rewrites = totals.relative + totals.selfHostAbsolute;
|
|
265
|
+
return {
|
|
266
|
+
summary: `${rewritable.length} page(s) need a v1 /files/<id> rewrite (${rewrites} rewrite(s): ${totals.relative} relative, ${totals.selfHostAbsolute} self-host absolute; ${totals.externalSkipped} external skipped)`,
|
|
267
|
+
counts: {
|
|
268
|
+
pages: rewritable.length,
|
|
269
|
+
rewrites,
|
|
270
|
+
relative: totals.relative,
|
|
271
|
+
selfHostAbsolute: totals.selfHostAbsolute,
|
|
272
|
+
externalSkipped: totals.externalSkipped,
|
|
273
|
+
},
|
|
274
|
+
};
|
|
275
|
+
},
|
|
276
|
+
stages: [
|
|
277
|
+
{
|
|
278
|
+
name: 'rewrite-files-url',
|
|
279
|
+
fn: async (ctx) => {
|
|
280
|
+
const origins = resolveAppOrigins(ctx);
|
|
281
|
+
if (ctx.dryRun) {
|
|
282
|
+
const { rewritable } = await scanFilesUrls(ctx, origins);
|
|
283
|
+
return { name: 'rewrite-files-url', transformed: 0, stats: { wouldRewrite: rewritable.length } };
|
|
284
|
+
}
|
|
285
|
+
const actingUserId = await (0, helpers_1.resolveActingUserId)(ctx, 'files-url-to-attachments');
|
|
286
|
+
const { rewritable: pages } = await scanFilesUrls(ctx, origins);
|
|
287
|
+
ctx.progress.setTotal(pages.length);
|
|
288
|
+
let rewritten = 0;
|
|
289
|
+
// Serial walk through `ctx.rewritePageBody` (each call re-fetches the
|
|
290
|
+
// live page, prepares a revision, and pushes it via the updatePage
|
|
291
|
+
// path so yjsState / yjsCheckpointAt are nulled).
|
|
292
|
+
for (const page of pages) {
|
|
293
|
+
await ctx.rewritePageBody(page.pageId, page.newBody, { userId: actingUserId });
|
|
294
|
+
rewritten += 1;
|
|
295
|
+
ctx.progress.increment();
|
|
296
|
+
}
|
|
297
|
+
if (rewritten > 0) {
|
|
298
|
+
ctx.logger.info(`files-url-to-attachments: rewrote ${rewritten} page(s) via the updatePage path (yjsState invalidated)`);
|
|
299
|
+
}
|
|
300
|
+
return { name: 'rewrite-files-url', transformed: rewritten };
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
],
|
|
304
|
+
});
|
|
305
|
+
//# sourceMappingURL=files-url-to-attachments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files-url-to-attachments.js","sourceRoot":"","sources":["../../../src/migration/migrations/files-url-to-attachments.ts"],"names":[],"mappings":"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"}
|