emdash 0.29.0 → 0.30.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/dist/{adapters-DPAkL6QF.d.mts → adapters-C0ONzkUP.d.mts} +10 -1
- package/dist/adapters-C0ONzkUP.d.mts.map +1 -0
- package/dist/{allowed-origins-FXB-FplB.mjs → allowed-origins-CCEi9bPI.mjs} +2 -2
- package/dist/{allowed-origins-FXB-FplB.mjs.map → allowed-origins-CCEi9bPI.mjs.map} +1 -1
- package/dist/api/route-utils.d.mts +3 -3
- package/dist/api/route-utils.d.mts.map +1 -1
- package/dist/api/route-utils.mjs +19 -19
- package/dist/api/schemas/index.d.mts +2 -2
- package/dist/api/schemas/index.mjs +5 -4
- package/dist/{api-DVbHNApo.mjs → api-b8WIiGU4.mjs} +253 -153
- package/dist/api-b8WIiGU4.mjs.map +1 -0
- package/dist/api-tokens-Cvmixds7.mjs +3 -0
- package/dist/{api-tokens-UYBkl17d.mjs → api-tokens-uPt8UDpx.mjs} +2 -2
- package/dist/{api-tokens-UYBkl17d.mjs.map → api-tokens-uPt8UDpx.mjs.map} +1 -1
- package/dist/{apply-D23iUV4q.mjs → apply-CmIJK9j8.mjs} +34 -37
- package/dist/apply-CmIJK9j8.mjs.map +1 -0
- package/dist/astro/index.d.mts +12 -13
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +90 -11
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +10 -11
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +56 -107
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/redirect.mjs +7 -7
- package/dist/astro/middleware/request-context.mjs +4 -4
- package/dist/astro/middleware/request-context.mjs.map +1 -1
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts +47 -3
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +326 -110
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/routes/PluginRegistry.d.mts +5 -1
- package/dist/astro/routes/PluginRegistry.d.mts.map +1 -1
- package/dist/astro/routes/PluginRegistry.mjs +2 -1
- package/dist/astro/routes/PluginRegistry.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +9 -8
- package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs +9 -8
- package/dist/astro/routes/api/admin/allowed-domains/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/api-tokens/index.mjs +7 -7
- package/dist/astro/routes/api/admin/api-tokens/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +5 -5
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +10 -9
- package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/index.mjs +10 -9
- package/dist/astro/routes/api/admin/byline-fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +10 -9
- package/dist/astro/routes/api/admin/byline-fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +15 -14
- package/dist/astro/routes/api/admin/bylines/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +16 -21
- package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/admin/bylines/index.mjs +15 -14
- package/dist/astro/routes/api/admin/bylines/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs +13 -12
- package/dist/astro/routes/api/admin/comments/_id_/status.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/_id_.mjs +6 -6
- package/dist/astro/routes/api/admin/comments/bulk.mjs +11 -10
- package/dist/astro/routes/api/admin/comments/bulk.mjs.map +1 -1
- package/dist/astro/routes/api/admin/comments/counts.mjs +6 -6
- package/dist/astro/routes/api/admin/comments/index.mjs +11 -10
- package/dist/astro/routes/api/admin/comments/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +5 -5
- package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +4 -4
- package/dist/astro/routes/api/admin/media-usage/repair.mjs +12 -10
- package/dist/astro/routes/api/admin/media-usage/repair.mjs.map +1 -1
- package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +5 -5
- package/dist/astro/routes/api/admin/oauth-clients/index.mjs +5 -5
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +40 -39
- package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +40 -39
- package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +45 -39
- package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.d.mts +8 -0
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs +39 -0
- package/dist/astro/routes/api/admin/plugins/_id_/mcp.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.d.mts +9 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.d.mts.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs +78 -0
- package/dist/astro/routes/api/admin/plugins/_id_/settings.mjs.map +1 -0
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +39 -38
- package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +42 -39
- package/dist/astro/routes/api/admin/plugins/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/index.mjs +45 -39
- package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +4 -4
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +39 -38
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +45 -40
- package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +39 -38
- package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +39 -38
- package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +43 -40
- package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +39 -38
- package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.d.mts.map +1 -1
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs +44 -41
- package/dist/astro/routes/api/admin/plugins/registry/install.mjs.map +1 -1
- package/dist/astro/routes/api/admin/plugins/updates.mjs +40 -39
- package/dist/astro/routes/api/admin/plugins/updates.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +39 -38
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +4 -4
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +39 -38
- package/dist/astro/routes/api/admin/themes/marketplace/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/disable.mjs +4 -4
- package/dist/astro/routes/api/admin/users/_id_/enable.mjs +4 -4
- package/dist/astro/routes/api/admin/users/_id_/index.mjs +9 -8
- package/dist/astro/routes/api/admin/users/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +5 -5
- package/dist/astro/routes/api/admin/users/index.mjs +9 -8
- package/dist/astro/routes/api/admin/users/index.mjs.map +1 -1
- package/dist/astro/routes/api/auth/dev-bypass.mjs +7 -7
- package/dist/astro/routes/api/auth/invite/accept.mjs +4 -4
- package/dist/astro/routes/api/auth/invite/complete.mjs +13 -12
- package/dist/astro/routes/api/auth/invite/complete.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/index.mjs +10 -9
- package/dist/astro/routes/api/auth/invite/index.mjs.map +1 -1
- package/dist/astro/routes/api/auth/invite/register-options.mjs +12 -11
- package/dist/astro/routes/api/auth/invite/register-options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/logout.mjs +4 -4
- package/dist/astro/routes/api/auth/magic-link/send.mjs +12 -11
- package/dist/astro/routes/api/auth/magic-link/send.mjs.map +1 -1
- package/dist/astro/routes/api/auth/magic-link/verify.mjs +5 -5
- package/dist/astro/routes/api/auth/me.mjs +9 -8
- package/dist/astro/routes/api/auth/me.mjs.map +1 -1
- package/dist/astro/routes/api/auth/mode.d.mts.map +1 -1
- package/dist/astro/routes/api/auth/mode.mjs +6 -3
- package/dist/astro/routes/api/auth/mode.mjs.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs +15 -5
- package/dist/astro/routes/api/auth/oauth/_provider_/callback.mjs.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_.d.mts.map +1 -1
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs +11 -5
- package/dist/astro/routes/api/auth/oauth/_provider_.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/_id_.mjs +8 -7
- package/dist/astro/routes/api/auth/passkey/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/index.mjs +3 -3
- package/dist/astro/routes/api/auth/passkey/options.mjs +13 -12
- package/dist/astro/routes/api/auth/passkey/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/options.mjs +11 -10
- package/dist/astro/routes/api/auth/passkey/register/options.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs +12 -11
- package/dist/astro/routes/api/auth/passkey/register/verify.mjs.map +1 -1
- package/dist/astro/routes/api/auth/passkey/verify.mjs +12 -11
- package/dist/astro/routes/api/auth/passkey/verify.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/complete.mjs +13 -12
- package/dist/astro/routes/api/auth/signup/complete.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/request.mjs +12 -11
- package/dist/astro/routes/api/auth/signup/request.mjs.map +1 -1
- package/dist/astro/routes/api/auth/signup/verify.mjs +4 -4
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +14 -13
- package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs.map +1 -1
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +13 -12
- package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +5 -4
- package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +6 -5
- package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +13 -12
- package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +10 -8
- package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs +20 -19
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/children.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs +18 -17
- package/dist/astro/routes/api/content/_collection_/_id_/references/_relation_/parents.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +5 -4
- package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +10 -8
- package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +18 -17
- package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +5 -4
- package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/_id_.mjs +11 -9
- package/dist/astro/routes/api/content/_collection_/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/authors.mjs +5 -5
- package/dist/astro/routes/api/content/_collection_/authors.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/index.d.mts.map +1 -1
- package/dist/astro/routes/api/content/_collection_/index.mjs +12 -10
- package/dist/astro/routes/api/content/_collection_/index.mjs.map +1 -1
- package/dist/astro/routes/api/content/_collection_/trash.mjs +10 -9
- package/dist/astro/routes/api/content/_collection_/trash.mjs.map +1 -1
- package/dist/astro/routes/api/dashboard.mjs +8 -8
- package/dist/astro/routes/api/dev/emails.mjs +4 -4
- package/dist/astro/routes/api/import/probe.d.mts +3 -3
- package/dist/astro/routes/api/import/probe.mjs +17 -16
- package/dist/astro/routes/api/import/probe.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/analyze.mjs +4 -4
- package/dist/astro/routes/api/import/wordpress/execute.d.mts +11 -12
- package/dist/astro/routes/api/import/wordpress/execute.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/execute.mjs +12 -12
- package/dist/astro/routes/api/import/wordpress/media.d.mts +10 -11
- package/dist/astro/routes/api/import/wordpress/media.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/media.mjs +11 -10
- package/dist/astro/routes/api/import/wordpress/media.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/prepare.mjs +11 -10
- package/dist/astro/routes/api/import/wordpress/prepare.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts +11 -12
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +11 -10
- package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +17 -16
- package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/callback.mjs +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +11 -12
- package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts.map +1 -1
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +23 -22
- package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs.map +1 -1
- package/dist/astro/routes/api/manifest.mjs +7 -8
- package/dist/astro/routes/api/manifest.mjs.map +1 -1
- package/dist/astro/routes/api/mcp.d.mts.map +1 -1
- package/dist/astro/routes/api/mcp.mjs +149 -45
- package/dist/astro/routes/api/mcp.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/confirm.mjs +9 -8
- package/dist/astro/routes/api/media/_id_/confirm.mjs.map +1 -1
- package/dist/astro/routes/api/media/_id_/usage.d.mts +8 -0
- package/dist/astro/routes/api/media/_id_/usage.d.mts.map +1 -0
- package/dist/astro/routes/api/media/_id_/usage.mjs +37 -0
- package/dist/astro/routes/api/media/_id_/usage.mjs.map +1 -0
- package/dist/astro/routes/api/media/_id_.d.mts.map +1 -1
- package/dist/astro/routes/api/media/_id_.mjs +26 -10
- package/dist/astro/routes/api/media/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/media/file/_...key_.mjs +4 -3
- package/dist/astro/routes/api/media/file/_...key_.mjs.map +1 -1
- package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +4 -4
- package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +4 -4
- package/dist/astro/routes/api/media/providers/index.mjs +4 -4
- package/dist/astro/routes/api/media/upload-url.mjs +10 -9
- package/dist/astro/routes/api/media/upload-url.mjs.map +1 -1
- package/dist/astro/routes/api/media.d.mts.map +1 -1
- package/dist/astro/routes/api/media.mjs +31 -11
- package/dist/astro/routes/api/media.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/items/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/items.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/items.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/reorder.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_/translations.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/menus/_name_.mjs +10 -9
- package/dist/astro/routes/api/menus/_name_.mjs.map +1 -1
- package/dist/astro/routes/api/menus/index.mjs +10 -9
- package/dist/astro/routes/api/menus/index.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/authorize.d.mts.map +1 -1
- package/dist/astro/routes/api/oauth/authorize.mjs +7 -8
- package/dist/astro/routes/api/oauth/authorize.mjs.map +1 -1
- package/dist/astro/routes/api/oauth/device/authorize.mjs +7 -7
- package/dist/astro/routes/api/oauth/device/code.mjs +10 -10
- package/dist/astro/routes/api/oauth/device/token.mjs +9 -9
- package/dist/astro/routes/api/oauth/register.mjs +4 -4
- package/dist/astro/routes/api/oauth/token/refresh.mjs +7 -7
- package/dist/astro/routes/api/oauth/token/revoke.mjs +7 -7
- package/dist/astro/routes/api/oauth/token.mjs +7 -7
- package/dist/astro/routes/api/openapi.json.mjs +52 -24
- package/dist/astro/routes/api/openapi.json.mjs.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.d.mts.map +1 -1
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +20 -32
- package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/index.mjs +12 -11
- package/dist/astro/routes/api/redirects/404s/index.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/404s/summary.mjs +12 -11
- package/dist/astro/routes/api/redirects/404s/summary.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/_id_.mjs +13 -12
- package/dist/astro/routes/api/redirects/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/redirects/index.mjs +13 -12
- package/dist/astro/routes/api/redirects/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/_id_/index.mjs +16 -15
- package/dist/astro/routes/api/relations/_id_/index.mjs.map +1 -1
- package/dist/astro/routes/api/relations/_id_/translations.mjs +11 -11
- package/dist/astro/routes/api/relations/index.mjs +16 -15
- package/dist/astro/routes/api/relations/index.mjs.map +1 -1
- package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +4 -4
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +5 -4
- package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +39 -38
- package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +39 -38
- package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +39 -38
- package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +39 -38
- package/dist/astro/routes/api/schema/collections/_slug_/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/collections/index.mjs +39 -38
- package/dist/astro/routes/api/schema/collections/index.mjs.map +1 -1
- package/dist/astro/routes/api/schema/index.mjs +9 -9
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs +39 -38
- package/dist/astro/routes/api/schema/orphans/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/schema/orphans/index.mjs +39 -38
- package/dist/astro/routes/api/schema/orphans/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/enable.mjs +13 -12
- package/dist/astro/routes/api/search/enable.mjs.map +1 -1
- package/dist/astro/routes/api/search/index.mjs +12 -11
- package/dist/astro/routes/api/search/index.mjs.map +1 -1
- package/dist/astro/routes/api/search/rebuild.mjs +13 -12
- package/dist/astro/routes/api/search/rebuild.mjs.map +1 -1
- package/dist/astro/routes/api/search/stats.mjs +8 -8
- package/dist/astro/routes/api/search/suggest.mjs +12 -11
- package/dist/astro/routes/api/search/suggest.mjs.map +1 -1
- package/dist/astro/routes/api/sections/_slug_.mjs +12 -11
- package/dist/astro/routes/api/sections/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/sections/index.mjs +12 -11
- package/dist/astro/routes/api/sections/index.mjs.map +1 -1
- package/dist/astro/routes/api/settings/backups/archives/_name_.d.mts +9 -0
- package/dist/astro/routes/api/settings/backups/archives/_name_.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs +48 -0
- package/dist/astro/routes/api/settings/backups/archives/_name_.mjs.map +1 -0
- package/dist/astro/routes/api/settings/backups/archives/index.d.mts +8 -0
- package/dist/astro/routes/api/settings/backups/archives/index.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/archives/index.mjs +23 -0
- package/dist/astro/routes/api/settings/backups/archives/index.mjs.map +1 -0
- package/dist/astro/routes/api/settings/backups/export.d.mts +8 -0
- package/dist/astro/routes/api/settings/backups/export.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/export.mjs +35 -0
- package/dist/astro/routes/api/settings/backups/export.mjs.map +1 -0
- package/dist/astro/routes/api/settings/backups/index.d.mts +9 -0
- package/dist/astro/routes/api/settings/backups/index.d.mts.map +1 -0
- package/dist/astro/routes/api/settings/backups/index.mjs +52 -0
- package/dist/astro/routes/api/settings/backups/index.mjs.map +1 -0
- package/dist/astro/routes/api/settings/email.mjs +5 -5
- package/dist/astro/routes/api/settings.mjs +14 -13
- package/dist/astro/routes/api/settings.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin-verify.mjs +19 -15
- package/dist/astro/routes/api/setup/admin-verify.mjs.map +1 -1
- package/dist/astro/routes/api/setup/admin.mjs +18 -14
- package/dist/astro/routes/api/setup/admin.mjs.map +1 -1
- package/dist/astro/routes/api/setup/dev-bypass.mjs +26 -26
- package/dist/astro/routes/api/setup/dev-reset.mjs +3 -3
- package/dist/astro/routes/api/setup/index.mjs +28 -27
- package/dist/astro/routes/api/setup/index.mjs.map +1 -1
- package/dist/astro/routes/api/setup/status.mjs +5 -5
- package/dist/astro/routes/api/snapshot.mjs +8 -215
- package/dist/astro/routes/api/snapshot.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +14 -13
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +14 -13
- package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +14 -13
- package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs.map +1 -1
- package/dist/astro/routes/api/taxonomies/index.mjs +14 -13
- package/dist/astro/routes/api/taxonomies/index.mjs.map +1 -1
- package/dist/astro/routes/api/themes/preview.mjs +6 -6
- package/dist/astro/routes/api/typegen.mjs +6 -6
- package/dist/astro/routes/api/well-known/auth.mjs +1 -1
- package/dist/astro/routes/api/well-known/oauth-authorization-server.d.mts.map +1 -1
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs +4 -3
- package/dist/astro/routes/api/well-known/oauth-authorization-server.mjs.map +1 -1
- package/dist/astro/routes/api/well-known/oauth-protected-resource.d.mts.map +1 -1
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs +4 -3
- package/dist/astro/routes/api/well-known/oauth-protected-resource.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +9 -8
- package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +12 -11
- package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +12 -11
- package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs.map +1 -1
- package/dist/astro/routes/api/widget-areas/_name_.mjs +7 -7
- package/dist/astro/routes/api/widget-areas/index.mjs +12 -11
- package/dist/astro/routes/api/widget-areas/index.mjs.map +1 -1
- package/dist/astro/routes/api/widget-components.mjs +4 -4
- package/dist/astro/routes/robots.txt.mjs +7 -7
- package/dist/astro/routes/sitemap-_collection_.xml.mjs +9 -9
- package/dist/astro/routes/sitemap.xml.mjs +8 -8
- package/dist/astro/types.d.mts +38 -17
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/auth/providers/github.d.mts +1 -1
- package/dist/auth/providers/google.d.mts +1 -1
- package/dist/{authorize-BmCwQCib.mjs → authorize-WxsiePzy.mjs} +7 -4
- package/dist/authorize-WxsiePzy.mjs.map +1 -0
- package/dist/backup-S8kFWtwD.mjs +241 -0
- package/dist/backup-S8kFWtwD.mjs.map +1 -0
- package/dist/{base64-C74Msx8h.mjs → base64-B-PsqheR.mjs} +8 -4
- package/dist/base64-B-PsqheR.mjs.map +1 -0
- package/dist/{byline-BWb5H-65.mjs → byline-XEjchwzZ.mjs} +6 -6
- package/dist/{byline-BWb5H-65.mjs.map → byline-XEjchwzZ.mjs.map} +1 -1
- package/dist/{byline-fields-DO6bAYK8.mjs → byline-fields-CdU_LTF1.mjs} +1 -1
- package/dist/{byline-fields-DO6bAYK8.mjs.map → byline-fields-CdU_LTF1.mjs.map} +1 -1
- package/dist/{bylines-BGuKFaBy.mjs → bylines-BJbT4gKS.mjs} +4 -4
- package/dist/{bylines-BGuKFaBy.mjs.map → bylines-BJbT4gKS.mjs.map} +1 -1
- package/dist/{bylines-CHojDMpj.mjs → bylines-czseViYo.mjs} +6 -6
- package/dist/{bylines-CHojDMpj.mjs.map → bylines-czseViYo.mjs.map} +1 -1
- package/dist/{cache-BeR7RfN8.mjs → cache-CGCd6AVM.mjs} +2 -2
- package/dist/{cache-BeR7RfN8.mjs.map → cache-CGCd6AVM.mjs.map} +1 -1
- package/dist/{challenge-store-B426wQ6O.mjs → challenge-store-BFzgFRog.mjs} +1 -1
- package/dist/{challenge-store-B426wQ6O.mjs.map → challenge-store-BFzgFRog.mjs.map} +1 -1
- package/dist/{chunks-BU5_nrAC.mjs → chunks-BxXyunY-.mjs} +2 -2
- package/dist/{chunks-BU5_nrAC.mjs.map → chunks-BxXyunY-.mjs.map} +1 -1
- package/dist/cli/index.mjs +138 -31
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +54 -3
- package/dist/client/index.d.mts.map +1 -1
- package/dist/client/index.mjs +16 -4
- package/dist/client/index.mjs.map +1 -1
- package/dist/{comment-SWh31kS0.mjs → comment-DPT0WKyd.mjs} +2 -2
- package/dist/{comment-SWh31kS0.mjs.map → comment-DPT0WKyd.mjs.map} +1 -1
- package/dist/{comment-reaction-DgcpziXI.mjs → comment-reaction-C65MldIB.mjs} +2 -2
- package/dist/{comment-reaction-DgcpziXI.mjs.map → comment-reaction-C65MldIB.mjs.map} +1 -1
- package/dist/{comments-kZYGppMS.mjs → comments-Bz6sCbgD.mjs} +3 -3
- package/dist/{comments-kZYGppMS.mjs.map → comments-Bz6sCbgD.mjs.map} +1 -1
- package/dist/{components-CliOkZAs.mjs → components-DZkL4Fx0.mjs} +1 -1
- package/dist/{components-CliOkZAs.mjs.map → components-DZkL4Fx0.mjs.map} +1 -1
- package/dist/{content-BO61Sx4j.mjs → content-Ci04z2z-.mjs} +53 -19
- package/dist/content-Ci04z2z-.mjs.map +1 -0
- package/dist/{content-refresh-BkkApzeS.mjs → content-refresh-D4khvC0R.mjs} +95 -3
- package/dist/content-refresh-D4khvC0R.mjs.map +1 -0
- package/dist/{context-DtSFYFuS.mjs → context-B6hc7zJL.mjs} +97 -74
- package/dist/context-B6hc7zJL.mjs.map +1 -0
- package/dist/{cron-YFJ7uNVA.mjs → cron-BlKIMD_e.mjs} +1 -1
- package/dist/{cron-YFJ7uNVA.mjs.map → cron-BlKIMD_e.mjs.map} +1 -1
- package/dist/{dashboard-xo_gPs_D.mjs → dashboard-C5NkXFbi.mjs} +4 -4
- package/dist/{dashboard-xo_gPs_D.mjs.map → dashboard-C5NkXFbi.mjs.map} +1 -1
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +2 -2
- package/dist/db/index.mjs.map +1 -1
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{db-errors-BKuXh_fi.mjs → db-errors-CcWLaRiR.mjs} +4 -2
- package/dist/db-errors-CcWLaRiR.mjs.map +1 -0
- package/dist/{default-DY5ovGUG.mjs → default-C4v9KP56.mjs} +1 -1
- package/dist/{default-DY5ovGUG.mjs.map → default-C4v9KP56.mjs.map} +1 -1
- package/dist/{device-flow-CPXQ_QfW.mjs → device-flow-BeA6lUS1.mjs} +5 -6
- package/dist/device-flow-BeA6lUS1.mjs.map +1 -0
- package/dist/{dialect-helpers-Cue7QQOR.mjs → dialect-helpers-HxEQGl_1.mjs} +57 -11
- package/dist/{dialect-helpers-Cue7QQOR.mjs.map → dialect-helpers-HxEQGl_1.mjs.map} +1 -1
- package/dist/{email-console-CjkQc7oY.mjs → email-console-C-9Ng8DM.mjs} +1 -1
- package/dist/{email-console-CjkQc7oY.mjs.map → email-console-C-9Ng8DM.mjs.map} +1 -1
- package/dist/error-CEGF6UZb.mjs +90 -0
- package/dist/error-CEGF6UZb.mjs.map +1 -0
- package/dist/{error-CfJMLSkd.mjs → errors-DtEXIQQV.mjs} +15 -84
- package/dist/errors-DtEXIQQV.mjs.map +1 -0
- package/dist/{escape-r8_GbEU2.mjs → escape-CFedIB1C.mjs} +1 -1
- package/dist/{escape-r8_GbEU2.mjs.map → escape-CFedIB1C.mjs.map} +1 -1
- package/dist/{field-defs-cache-BVrNCgSj.mjs → field-defs-cache-DvmlgP-D.mjs} +2 -2
- package/dist/{field-defs-cache-BVrNCgSj.mjs.map → field-defs-cache-DvmlgP-D.mjs.map} +1 -1
- package/dist/{fts-manager-BD9s77qh.mjs → fts-manager-DzqIBrrW.mjs} +3 -3
- package/dist/{fts-manager-BD9s77qh.mjs.map → fts-manager-DzqIBrrW.mjs.map} +1 -1
- package/dist/{hreflang-CgIxhH4k.d.mts → hreflang-CIxH_LKz.d.mts} +2 -2
- package/dist/{hreflang-CgIxhH4k.d.mts.map → hreflang-CIxH_LKz.d.mts.map} +1 -1
- package/dist/{hreflang-pAWUiPd_.mjs → hreflang-db2Tpb2o.mjs} +5 -5
- package/dist/{hreflang-pAWUiPd_.mjs.map → hreflang-db2Tpb2o.mjs.map} +1 -1
- package/dist/{import-2jHtLzsO.mjs → import-Dmkm8S1W.mjs} +4 -4
- package/dist/{import-2jHtLzsO.mjs.map → import-Dmkm8S1W.mjs.map} +1 -1
- package/dist/{index-DxjWLKGT.d.mts → index-BEui-cRd.d.mts} +3 -3
- package/dist/{index-DxjWLKGT.d.mts.map → index-BEui-cRd.d.mts.map} +1 -1
- package/dist/{index-BXOCyLj0.d.mts → index-wYnC6u4o.d.mts} +780 -15
- package/dist/index-wYnC6u4o.d.mts.map +1 -0
- package/dist/index.d.mts +18 -19
- package/dist/index.mjs +59 -58
- package/dist/{load-DgoWMdRX.mjs → load-Cx27ki1l.mjs} +2 -2
- package/dist/{load-DgoWMdRX.mjs.map → load-Cx27ki1l.mjs.map} +1 -1
- package/dist/{loader-Rb8QlGZp.mjs → loader-Be3ouI5L.mjs} +170 -6
- package/dist/loader-Be3ouI5L.mjs.map +1 -0
- package/dist/{manifest-schema-DeGNma2O.mjs → manifest-schema-bCq54i7F.mjs} +16 -2
- package/dist/manifest-schema-bCq54i7F.mjs.map +1 -0
- package/dist/media/image-endpoint.d.mts +30 -2
- package/dist/media/image-endpoint.d.mts.map +1 -1
- package/dist/media/image-endpoint.mjs +29 -3
- package/dist/media/image-endpoint.mjs.map +1 -1
- package/dist/media/index.d.mts +1 -1
- package/dist/media/local-runtime.d.mts +12 -13
- package/dist/media/local-runtime.d.mts.map +1 -1
- package/dist/media/local-runtime.mjs +6 -6
- package/dist/{media-D2ZFowpn.mjs → media-BjhhENaJ.mjs} +2 -2
- package/dist/{media-D2ZFowpn.mjs.map → media-BjhhENaJ.mjs.map} +1 -1
- package/dist/{media-allowlist-Dc05vKtt.mjs → media-allowlist-jUppPWFy.mjs} +1 -1
- package/dist/{media-allowlist-Dc05vKtt.mjs.map → media-allowlist-jUppPWFy.mjs.map} +1 -1
- package/dist/media-kIV1IxFf.mjs +243 -0
- package/dist/media-kIV1IxFf.mjs.map +1 -0
- package/dist/media-upload-D2wk3EIt.mjs +145 -0
- package/dist/media-upload-D2wk3EIt.mjs.map +1 -0
- package/dist/{media-url-DgIEYZr4.mjs → media-url-BCm5vBn6.mjs} +1 -1
- package/dist/{media-url-DgIEYZr4.mjs.map → media-url-BCm5vBn6.mjs.map} +1 -1
- package/dist/{media-usage-B__v9NMm.mjs → media-usage-CljdO1mc.mjs} +138 -5
- package/dist/{media-usage-B__v9NMm.mjs.map → media-usage-CljdO1mc.mjs.map} +1 -1
- package/dist/{menus-BtvH7Z7t.mjs → menus-BcyElFtI.mjs} +155 -12
- package/dist/menus-BcyElFtI.mjs.map +1 -0
- package/dist/{menus-BpfevlJD.mjs → menus-CZyG6rvx.mjs} +2 -2
- package/dist/{menus-BpfevlJD.mjs.map → menus-CZyG6rvx.mjs.map} +1 -1
- package/dist/{mode-BVnhGZ2o.mjs → mode-fiXRMfeA.mjs} +1 -1
- package/dist/{mode-BVnhGZ2o.mjs.map → mode-fiXRMfeA.mjs.map} +1 -1
- package/dist/{oauth-authorization-BWqWTHBK.mjs → oauth-authorization-oqfbBuMH.mjs} +5 -6
- package/dist/oauth-authorization-oqfbBuMH.mjs.map +1 -0
- package/dist/{oauth-clients-43_XADoa.mjs → oauth-clients-BlrUHAsf.mjs} +1 -1
- package/dist/{oauth-clients-43_XADoa.mjs.map → oauth-clients-BlrUHAsf.mjs.map} +1 -1
- package/dist/{oauth-state-store-BRSUEkmx.mjs → oauth-state-store-DnvjRMy6.mjs} +2 -1
- package/dist/{oauth-state-store-BRSUEkmx.mjs.map → oauth-state-store-DnvjRMy6.mjs.map} +1 -1
- package/dist/{oauth-user-lookup-Ctgemb0k.mjs → oauth-user-lookup-oUllxvAv.mjs} +1 -1
- package/dist/{oauth-user-lookup-Ctgemb0k.mjs.map → oauth-user-lookup-oUllxvAv.mjs.map} +1 -1
- package/dist/object-cache/memory.d.mts +1 -1
- package/dist/{options-COXGTtqd.d.mts → options-BqMkWfYa.d.mts} +6 -6
- package/dist/{options-COXGTtqd.d.mts.map → options-BqMkWfYa.d.mts.map} +1 -1
- package/dist/page/index.d.mts +2 -2
- package/dist/page/index.d.mts.map +1 -1
- package/dist/page/index.mjs.map +1 -1
- package/dist/{parse-GLksnn-B.mjs → parse-C_-6klII.mjs} +4 -12
- package/dist/{parse-GLksnn-B.mjs.map → parse-C_-6klII.mjs.map} +1 -1
- package/dist/{passkey-config-CjA1UbDj.mjs → passkey-config-C-SKpc0-.mjs} +1 -1
- package/dist/{passkey-config-CjA1UbDj.mjs.map → passkey-config-C-SKpc0-.mjs.map} +1 -1
- package/dist/{placeholder-DR-eeZr-.d.mts → placeholder-Dop47JMM.d.mts} +1 -1
- package/dist/{placeholder-DR-eeZr-.d.mts.map → placeholder-Dop47JMM.d.mts.map} +1 -1
- package/dist/plugin-types.d.mts +21 -2
- package/dist/plugin-types.d.mts.map +1 -1
- package/dist/plugin-utils.d.mts +18 -17
- package/dist/plugin-utils.d.mts.map +1 -1
- package/dist/plugin-utils.mjs +8 -6
- package/dist/plugin-utils.mjs.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.d.mts +10 -11
- package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.mjs +15 -3
- package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
- package/dist/{portable-text-BAkgEKcv.mjs → portable-text-sDj92Kxv.mjs} +1 -1
- package/dist/{portable-text-BAkgEKcv.mjs.map → portable-text-sDj92Kxv.mjs.map} +1 -1
- package/dist/{preview-Rloa09Wp.mjs → preview-D4Jnbfx7.mjs} +2 -2
- package/dist/{preview-Rloa09Wp.mjs.map → preview-D4Jnbfx7.mjs.map} +1 -1
- package/dist/{public-url-C0cEvrRu.mjs → public-url-DSGTnJFw.mjs} +5 -3
- package/dist/public-url-DSGTnJFw.mjs.map +1 -0
- package/dist/{query-ZzvXyxWq.mjs → query-DR73ZNfm.mjs} +14 -14
- package/dist/{query-ZzvXyxWq.mjs.map → query-DR73ZNfm.mjs.map} +1 -1
- package/dist/{query-BxT95opY.mjs → query-Di7DOmPV.mjs} +3 -3
- package/dist/{query-BxT95opY.mjs.map → query-Di7DOmPV.mjs.map} +1 -1
- package/dist/{rate-limit-Cg4Rvc_-.mjs → rate-limit-CMj83JNW.mjs} +2 -2
- package/dist/{rate-limit-Cg4Rvc_-.mjs.map → rate-limit-CMj83JNW.mjs.map} +1 -1
- package/dist/{redirect-Ce_6Yb6z.mjs → redirect-Botom7X6.mjs} +1 -1
- package/dist/{redirect-Ce_6Yb6z.mjs.map → redirect-Botom7X6.mjs.map} +1 -1
- package/dist/{redirect-Ch3E98qZ.mjs → redirect-CgLPYflR.mjs} +10 -4
- package/dist/redirect-CgLPYflR.mjs.map +1 -0
- package/dist/{redirects-CXmVGRNZ.mjs → redirects-B7t9bKsL.mjs} +4 -4
- package/dist/{redirects-CXmVGRNZ.mjs.map → redirects-B7t9bKsL.mjs.map} +1 -1
- package/dist/{redirects-CeD7K7EX.mjs → redirects-BBq3n2Rj.mjs} +4 -175
- package/dist/redirects-BBq3n2Rj.mjs.map +1 -0
- package/dist/{registry-CyIXPi4E.mjs → registry-FV15nLge.mjs} +97 -8
- package/dist/registry-FV15nLge.mjs.map +1 -0
- package/dist/{relation-Ba68Tm4Z.mjs → relation-9M9j_UWo.mjs} +3 -3
- package/dist/{relation-Ba68Tm4Z.mjs.map → relation-9M9j_UWo.mjs.map} +1 -1
- package/dist/{relations-BmBmX4Eb.mjs → relations-5_avdrN_.mjs} +2 -2
- package/dist/{relations-BmBmX4Eb.mjs.map → relations-5_avdrN_.mjs.map} +1 -1
- package/dist/{relations-C8hVyEy0.mjs → relations-BKvO39-9.mjs} +5 -5
- package/dist/{relations-C8hVyEy0.mjs.map → relations-BKvO39-9.mjs.map} +1 -1
- package/dist/{relations-CbBpoOys.d.mts → relations-Bh8jlFsU.d.mts} +306 -4
- package/dist/relations-Bh8jlFsU.d.mts.map +1 -0
- package/dist/{request-meta-DCwktC5P.mjs → request-meta-DzXYYI-n.mjs} +2 -2
- package/dist/{request-meta-DCwktC5P.mjs.map → request-meta-DzXYYI-n.mjs.map} +1 -1
- package/dist/{runner-CiNdIk3y.d.mts → runner-Dd8m8k9F.d.mts} +2 -2
- package/dist/{runner-CiNdIk3y.d.mts.map → runner-Dd8m8k9F.d.mts.map} +1 -1
- package/dist/{runner-jt65bF7F.mjs → runner-DfnZ5eUr.mjs} +333 -199
- package/dist/runner-DfnZ5eUr.mjs.map +1 -0
- package/dist/runtime.d.mts +11 -12
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +4 -4
- package/dist/{schema-DwjufZ1S.mjs → schema-BXxlHeAf.mjs} +3 -3
- package/dist/{schema-DwjufZ1S.mjs.map → schema-BXxlHeAf.mjs.map} +1 -1
- package/dist/scopes-Bl4IwHA-.mjs +27 -0
- package/dist/scopes-Bl4IwHA-.mjs.map +1 -0
- package/dist/{search-Cl875CVE.mjs → search-Bff-7jFt.mjs} +5 -5
- package/dist/{search-Cl875CVE.mjs.map → search-Bff-7jFt.mjs.map} +1 -1
- package/dist/{secrets-CO_bEmII.mjs → secrets-CSwQIl4q.mjs} +3 -3
- package/dist/{secrets-CO_bEmII.mjs.map → secrets-CSwQIl4q.mjs.map} +1 -1
- package/dist/{sections-DTKzgoiS.mjs → sections-CwW4s1al.mjs} +3 -3
- package/dist/{sections-DTKzgoiS.mjs.map → sections-CwW4s1al.mjs.map} +1 -1
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +20 -20
- package/dist/seo/index.d.mts +14 -3
- package/dist/seo/index.d.mts.map +1 -1
- package/dist/seo/index.mjs +16 -16
- package/dist/seo/index.mjs.map +1 -1
- package/dist/{seo-BLm6SXzS.mjs → seo-2cmFHZns.mjs} +2 -2
- package/dist/{seo-BLm6SXzS.mjs.map → seo-2cmFHZns.mjs.map} +1 -1
- package/dist/{seo-BjrbXAd_.mjs → seo-C3GDfT0V.mjs} +1 -1
- package/dist/{seo-BjrbXAd_.mjs.map → seo-C3GDfT0V.mjs.map} +1 -1
- package/dist/{service-D6zDmKXy.mjs → service-DkGTWGIi.mjs} +3 -3
- package/dist/{service-D6zDmKXy.mjs.map → service-DkGTWGIi.mjs.map} +1 -1
- package/dist/{session-user-DoSs6YM8.mjs → session-user-DbHqKDKe.mjs} +1 -1
- package/dist/{session-user-DoSs6YM8.mjs.map → session-user-DbHqKDKe.mjs.map} +1 -1
- package/dist/{settings-CmS3TwXf.mjs → settings-C4s8hFQm.mjs} +3 -3
- package/dist/{settings-CmS3TwXf.mjs.map → settings-C4s8hFQm.mjs.map} +1 -1
- package/dist/{settings-BuQYvLfy.mjs → settings-CpA4lQFt.mjs} +4 -4
- package/dist/{settings-BuQYvLfy.mjs.map → settings-CpA4lQFt.mjs.map} +1 -1
- package/dist/{setup-complete-BPNgLHlU.mjs → setup-complete-CdIlqloh.mjs} +1 -1
- package/dist/{setup-complete-BPNgLHlU.mjs.map → setup-complete-CdIlqloh.mjs.map} +1 -1
- package/dist/{setup-nonce-DEPZX96T.mjs → setup-nonce-DqiIPr-J.mjs} +1 -1
- package/dist/{setup-nonce-DEPZX96T.mjs.map → setup-nonce-DqiIPr-J.mjs.map} +1 -1
- package/dist/{single-flight-cache-DEtW-OEG.mjs → single-flight-cache-C2exrGAi.mjs} +1 -1
- package/dist/{single-flight-cache-DEtW-OEG.mjs.map → single-flight-cache-C2exrGAi.mjs.map} +1 -1
- package/dist/{site-url-CcLy5D5s.mjs → site-url-NGJT6NTU.mjs} +1 -1
- package/dist/{site-url-CcLy5D5s.mjs.map → site-url-NGJT6NTU.mjs.map} +1 -1
- package/dist/snapshot-BdpUJKD-.mjs +216 -0
- package/dist/snapshot-BdpUJKD-.mjs.map +1 -0
- package/dist/{ssrf-TrKYJAy0.mjs → ssrf-CviKqWmq.mjs} +1 -1
- package/dist/{ssrf-TrKYJAy0.mjs.map → ssrf-CviKqWmq.mjs.map} +1 -1
- package/dist/state-xxv6ZTMv.mjs +128 -0
- package/dist/state-xxv6ZTMv.mjs.map +1 -0
- package/dist/{status-D3Gy1Zc6.mjs → status-COfycGIU.mjs} +1 -1
- package/dist/{status-D3Gy1Zc6.mjs.map → status-COfycGIU.mjs.map} +1 -1
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.mjs +1 -1
- package/dist/{taxonomies-ClS4RKaZ.mjs → taxonomies-Ce49uIzY.mjs} +4 -4
- package/dist/{taxonomies-ClS4RKaZ.mjs.map → taxonomies-Ce49uIzY.mjs.map} +1 -1
- package/dist/{taxonomies-pUkuD6nj.mjs → taxonomies-DjSKBZpq.mjs} +7 -7
- package/dist/{taxonomies-pUkuD6nj.mjs.map → taxonomies-DjSKBZpq.mjs.map} +1 -1
- package/dist/{taxonomy-BkxbUMSw.mjs → taxonomy-DfVooU4W.mjs} +51 -13
- package/dist/taxonomy-DfVooU4W.mjs.map +1 -0
- package/dist/{tokens-BV6fgl5A.mjs → tokens-DVltpO2D.mjs} +2 -2
- package/dist/{tokens-BV6fgl5A.mjs.map → tokens-DVltpO2D.mjs.map} +1 -1
- package/dist/{transport-DTFhhPOg.mjs → transport-CKrlqSpD.mjs} +1 -1
- package/dist/{transport-DTFhhPOg.mjs.map → transport-CKrlqSpD.mjs.map} +1 -1
- package/dist/{transport-DmlmzD2U.d.mts → transport-Vd7VdqHv.d.mts} +1 -1
- package/dist/{transport-DmlmzD2U.d.mts.map → transport-Vd7VdqHv.d.mts.map} +1 -1
- package/dist/{trusted-proxy-CSgZVESw.mjs → trusted-proxy-CwjQj0YG.mjs} +1 -1
- package/dist/{trusted-proxy-CSgZVESw.mjs.map → trusted-proxy-CwjQj0YG.mjs.map} +1 -1
- package/dist/{types-B6-N9cBB.d.mts → types-B4vm81VH.d.mts} +1 -1
- package/dist/{types-B6-N9cBB.d.mts.map → types-B4vm81VH.d.mts.map} +1 -1
- package/dist/{types-Cm4Cz-8M.d.mts → types-B97jg3aW.d.mts} +6 -1
- package/dist/{types-Cm4Cz-8M.d.mts.map → types-B97jg3aW.d.mts.map} +1 -1
- package/dist/{types-BNZsPL9z.mjs → types-BD40g7zz.mjs} +1 -1
- package/dist/{types-BNZsPL9z.mjs.map → types-BD40g7zz.mjs.map} +1 -1
- package/dist/{types-QnlQIyPE.d.mts → types-BNfPHfay.d.mts} +1 -1
- package/dist/{types-QnlQIyPE.d.mts.map → types-BNfPHfay.d.mts.map} +1 -1
- package/dist/{types-DLIrNtv5.d.mts → types-BfYUPJdP.d.mts} +2 -2
- package/dist/{types-DLIrNtv5.d.mts.map → types-BfYUPJdP.d.mts.map} +1 -1
- package/dist/{types-CtDVagM4.d.mts → types-BvB7gDOD.d.mts} +38 -4
- package/dist/types-BvB7gDOD.d.mts.map +1 -0
- package/dist/{types-B_pmP7Yq.d.mts → types-C7U0HlEr.d.mts} +1 -1
- package/dist/{types-B_pmP7Yq.d.mts.map → types-C7U0HlEr.d.mts.map} +1 -1
- package/dist/{types-Ch8pFMEm.mjs → types-D1iJ3DpO.mjs} +3 -3
- package/dist/{types-Ch8pFMEm.mjs.map → types-D1iJ3DpO.mjs.map} +1 -1
- package/dist/{types-momGysZk.d.mts → types-DPKhI5ib.d.mts} +9 -1
- package/dist/types-DPKhI5ib.d.mts.map +1 -0
- package/dist/{types-BCVuUPrL.d.mts → types-Kmaxdarz.d.mts} +1 -1
- package/dist/{types-BCVuUPrL.d.mts.map → types-Kmaxdarz.d.mts.map} +1 -1
- package/dist/{types-qljd1hsL.d.mts → types-iVeZ5g6N.d.mts} +1 -1
- package/dist/{types-qljd1hsL.d.mts.map → types-iVeZ5g6N.d.mts.map} +1 -1
- package/dist/{user-DTxX_Fha.mjs → user-Bh-L1qo6.mjs} +3 -3
- package/dist/{user-DTxX_Fha.mjs.map → user-Bh-L1qo6.mjs.map} +1 -1
- package/dist/{utils-Cz8PVrl4.mjs → utils-BbUgmeZG.mjs} +1 -1
- package/dist/{utils-Cz8PVrl4.mjs.map → utils-BbUgmeZG.mjs.map} +1 -1
- package/dist/{validate-9jLuE301.d.mts → validate-DULfgpJP.d.mts} +5 -5
- package/dist/{validate-9jLuE301.d.mts.map → validate-DULfgpJP.d.mts.map} +1 -1
- package/dist/{validate-C3CpWlNt.mjs → validate-V9nCwq_-.mjs} +2 -2
- package/dist/{validate-C3CpWlNt.mjs.map → validate-V9nCwq_-.mjs.map} +1 -1
- package/dist/{validation-DM2K_NJC.mjs → validation-BsVUJfsP.mjs} +10 -10
- package/dist/{validation-DM2K_NJC.mjs.map → validation-BsVUJfsP.mjs.map} +1 -1
- package/dist/version-907opKac.mjs +7 -0
- package/dist/{version-BlIJvNAZ.mjs.map → version-907opKac.mjs.map} +1 -1
- package/dist/{widgets-B_X6_UXJ.mjs → widgets-DGv1Z04V.mjs} +3 -3
- package/dist/{widgets-B_X6_UXJ.mjs.map → widgets-DGv1Z04V.mjs.map} +1 -1
- package/dist/{wxr-taxonomies-tADW4KTa.d.mts → wxr-taxonomies-B4tMuN5T.d.mts} +1 -1
- package/dist/{wxr-taxonomies-tADW4KTa.d.mts.map → wxr-taxonomies-B4tMuN5T.d.mts.map} +1 -1
- package/dist/{wxr-taxonomies-oNJB2S81.mjs → wxr-taxonomies-Cs1N6O8z.mjs} +3 -3
- package/dist/{wxr-taxonomies-oNJB2S81.mjs.map → wxr-taxonomies-Cs1N6O8z.mjs.map} +1 -1
- package/dist/{zod-generator-CrfV79De.mjs → zod-generator-B5prQ5M4.mjs} +2 -2
- package/dist/{zod-generator-CrfV79De.mjs.map → zod-generator-B5prQ5M4.mjs.map} +1 -1
- package/package.json +8 -8
- package/src/api/authorize.ts +10 -1
- package/src/api/error.ts +5 -5
- package/src/api/errors.ts +14 -0
- package/src/api/handlers/backup.ts +312 -0
- package/src/api/handlers/content.ts +36 -2
- package/src/api/handlers/device-flow.ts +2 -3
- package/src/api/handlers/index.ts +16 -0
- package/src/api/handlers/marketplace.ts +38 -0
- package/src/api/handlers/media-upload.ts +210 -0
- package/src/api/handlers/media-usage.ts +211 -2
- package/src/api/handlers/oauth-authorization.ts +2 -6
- package/src/api/handlers/plugin-settings.ts +218 -0
- package/src/api/handlers/plugins.ts +41 -0
- package/src/api/handlers/registry.ts +39 -0
- package/src/api/handlers/snapshot.ts +21 -3
- package/src/api/openapi/document.ts +48 -6
- package/src/api/parse.ts +1 -15
- package/src/api/public-url.ts +4 -2
- package/src/api/schemas/common.ts +6 -2
- package/src/api/schemas/media-usage.ts +72 -0
- package/src/api/schemas/media.ts +32 -1
- package/src/astro/integration/index.ts +38 -0
- package/src/astro/integration/routes.ts +35 -0
- package/src/astro/integration/runtime.ts +6 -0
- package/src/astro/integration/virtual-modules.ts +41 -7
- package/src/astro/integration/vite-config.ts +17 -1
- package/src/astro/middleware/auth.ts +70 -78
- package/src/astro/middleware/csp.ts +5 -2
- package/src/astro/middleware.ts +86 -31
- package/src/astro/public-plugin-api-routes.ts +2 -1
- package/src/astro/routes/PluginRegistry.tsx +5 -2
- package/src/astro/routes/admin.astro +56 -16
- package/src/astro/routes/api/admin/api-tokens/index.ts +2 -2
- package/src/astro/routes/api/admin/bylines/[id]/translations.ts +2 -5
- package/src/astro/routes/api/admin/plugins/[id]/index.ts +6 -0
- package/src/astro/routes/api/admin/plugins/[id]/mcp.ts +42 -0
- package/src/astro/routes/api/admin/plugins/[id]/settings.ts +80 -0
- package/src/astro/routes/api/admin/plugins/[id]/update.ts +2 -0
- package/src/astro/routes/api/admin/plugins/index.ts +9 -0
- package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +2 -0
- package/src/astro/routes/api/admin/plugins/registry/[id]/update.ts +2 -0
- package/src/astro/routes/api/admin/plugins/registry/install.ts +2 -0
- package/src/astro/routes/api/admin/plugins/updates.ts +2 -4
- package/src/astro/routes/api/auth/mode.ts +6 -14
- package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +21 -4
- package/src/astro/routes/api/auth/oauth/[provider].ts +24 -6
- package/src/astro/routes/api/content/[collection]/[id]/compare.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +2 -3
- package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +2 -3
- package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/children.ts +4 -6
- package/src/astro/routes/api/content/[collection]/[id]/references/[relation]/parents.ts +2 -3
- package/src/astro/routes/api/content/[collection]/[id]/revisions.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +4 -6
- package/src/astro/routes/api/content/[collection]/[id]/translations.ts +3 -4
- package/src/astro/routes/api/content/[collection]/[id].ts +3 -4
- package/src/astro/routes/api/content/[collection]/authors.ts +2 -3
- package/src/astro/routes/api/content/[collection]/index.ts +6 -8
- package/src/astro/routes/api/content/[collection]/trash.ts +2 -3
- package/src/astro/routes/api/manifest.ts +2 -9
- package/src/astro/routes/api/mcp.ts +2 -1
- package/src/astro/routes/api/media/[id]/usage.ts +30 -0
- package/src/astro/routes/api/media/[id].ts +17 -6
- package/src/astro/routes/api/media/file/[...key].ts +8 -0
- package/src/astro/routes/api/media.ts +21 -2
- package/src/astro/routes/api/oauth/authorize.ts +2 -6
- package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +17 -3
- package/src/astro/routes/api/settings/backups/archives/[name].ts +78 -0
- package/src/astro/routes/api/settings/backups/archives/index.ts +33 -0
- package/src/astro/routes/api/settings/backups/export.ts +43 -0
- package/src/astro/routes/api/settings/backups/index.ts +76 -0
- package/src/astro/routes/api/setup/admin-verify.ts +8 -4
- package/src/astro/routes/api/setup/admin.ts +11 -4
- package/src/astro/routes/api/well-known/oauth-authorization-server.ts +4 -1
- package/src/astro/routes/api/well-known/oauth-protected-resource.ts +5 -1
- package/src/astro/types.ts +48 -2
- package/src/auth/api-tokens.ts +1 -0
- package/src/auth/oauth-state-store.ts +3 -0
- package/src/auth/providers/github-admin.tsx +5 -6
- package/src/auth/providers/google-admin.tsx +5 -6
- package/src/auth/scopes.ts +3 -9
- package/src/cli/client-factory.ts +0 -1
- package/src/cli/commands/bundle-utils.ts +50 -1
- package/src/cli/commands/bundle.ts +9 -2
- package/src/cli/commands/media.ts +127 -0
- package/src/client/index.ts +84 -2
- package/src/client/transport.ts +1 -1
- package/src/components/EmDashHead.astro +4 -8
- package/src/components/InlinePortableTextEditor.tsx +56 -35
- package/src/components/marks/Link.astro +5 -1
- package/src/database/dialect-helpers.ts +77 -3
- package/src/database/migrations/051_content_taxonomies_denorm.ts +120 -0
- package/src/database/migrations/052_media_usage_read_index.ts +26 -0
- package/src/database/migrations/053_plugin_mcp_tools.ts +21 -0
- package/src/database/migrations/runner.ts +6 -0
- package/src/database/repositories/audit.ts +2 -1
- package/src/database/repositories/content.ts +98 -16
- package/src/database/repositories/media-usage.ts +250 -1
- package/src/database/repositories/plugin-storage.ts +29 -32
- package/src/database/repositories/redirect.ts +14 -2
- package/src/database/repositories/taxonomy.ts +57 -8
- package/src/database/types.ts +23 -0
- package/src/db/adapters.ts +9 -0
- package/src/emdash-runtime.ts +310 -66
- package/src/loader.ts +292 -1
- package/src/mcp/server.ts +222 -5
- package/src/media/image-endpoint.ts +38 -2
- package/src/page/metadata.ts +27 -0
- package/src/plugin-types.ts +19 -0
- package/src/plugin-utils.ts +8 -6
- package/src/plugins/adapt-sandbox-entry.ts +30 -1
- package/src/plugins/context.ts +7 -0
- package/src/plugins/define-plugin.ts +16 -0
- package/src/plugins/manifest-schema.ts +28 -1
- package/src/plugins/routes.ts +27 -1
- package/src/plugins/sandbox/runner-options.ts +16 -0
- package/src/plugins/sandbox/types.ts +6 -1
- package/src/plugins/state.ts +17 -1
- package/src/plugins/storage-query.ts +67 -33
- package/src/plugins/types.ts +41 -0
- package/src/schema/registry.ts +141 -5
- package/src/seed/apply.ts +28 -29
- package/src/seo/index.ts +19 -4
- package/src/storage/types.ts +6 -0
- package/src/utils/base64.ts +7 -2
- package/src/utils/db-errors.ts +3 -1
- package/src/virtual-modules.d.ts +13 -0
- package/src/visual-editing/toolbar.ts +1 -1
- package/dist/adapters-DPAkL6QF.d.mts.map +0 -1
- package/dist/api-DVbHNApo.mjs.map +0 -1
- package/dist/api-tokens-Dk2GrJMY.mjs +0 -3
- package/dist/apply-D23iUV4q.mjs.map +0 -1
- package/dist/authorize-BmCwQCib.mjs.map +0 -1
- package/dist/base64-C74Msx8h.mjs.map +0 -1
- package/dist/content-BO61Sx4j.mjs.map +0 -1
- package/dist/content-refresh-BkkApzeS.mjs.map +0 -1
- package/dist/context-DtSFYFuS.mjs.map +0 -1
- package/dist/db-errors-BKuXh_fi.mjs.map +0 -1
- package/dist/device-flow-CPXQ_QfW.mjs.map +0 -1
- package/dist/error-CfJMLSkd.mjs.map +0 -1
- package/dist/index-BXOCyLj0.d.mts.map +0 -1
- package/dist/loader-Rb8QlGZp.mjs.map +0 -1
- package/dist/manifest-schema-DeGNma2O.mjs.map +0 -1
- package/dist/menus-BtvH7Z7t.mjs.map +0 -1
- package/dist/oauth-authorization-BWqWTHBK.mjs.map +0 -1
- package/dist/public-url-C0cEvrRu.mjs.map +0 -1
- package/dist/redirect-Ch3E98qZ.mjs.map +0 -1
- package/dist/redirects-CeD7K7EX.mjs.map +0 -1
- package/dist/registry-CyIXPi4E.mjs.map +0 -1
- package/dist/relations-CbBpoOys.d.mts.map +0 -1
- package/dist/runner-jt65bF7F.mjs.map +0 -1
- package/dist/scheduled-publish-DlJHGcuL.d.mts +0 -11
- package/dist/scheduled-publish-DlJHGcuL.d.mts.map +0 -1
- package/dist/taxonomy-BkxbUMSw.mjs.map +0 -1
- package/dist/types-CtDVagM4.d.mts.map +0 -1
- package/dist/types-momGysZk.d.mts.map +0 -1
- package/dist/version-BlIJvNAZ.mjs +0 -7
- /package/dist/{ssrf-B5DOv5E5.mjs → ssrf-BB__xfNM.mjs} +0 -0
- /package/dist/{types-DeCZBZxn.mjs → types-CK0LxPUQ.mjs} +0 -0
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import "../../../../../options-
|
|
2
|
-
import "../../../../../types-
|
|
3
|
-
import "../../../../../types-
|
|
4
|
-
import "../../../../../relations-
|
|
5
|
-
import "../../../../../index-
|
|
6
|
-
import "../../../../../runner-
|
|
7
|
-
import "../../../../../index-
|
|
8
|
-
import "../../../../../
|
|
9
|
-
import "../../../../../
|
|
10
|
-
import "../../../../../
|
|
11
|
-
import "../../../../../validate-9jLuE301.mjs";
|
|
1
|
+
import "../../../../../options-BqMkWfYa.mjs";
|
|
2
|
+
import "../../../../../types-DPKhI5ib.mjs";
|
|
3
|
+
import "../../../../../types-BvB7gDOD.mjs";
|
|
4
|
+
import "../../../../../relations-Bh8jlFsU.mjs";
|
|
5
|
+
import "../../../../../index-wYnC6u4o.mjs";
|
|
6
|
+
import "../../../../../runner-Dd8m8k9F.mjs";
|
|
7
|
+
import "../../../../../index-BEui-cRd.mjs";
|
|
8
|
+
import "../../../../../types-C7U0HlEr.mjs";
|
|
9
|
+
import "../../../../../hreflang-CIxH_LKz.mjs";
|
|
10
|
+
import "../../../../../validate-DULfgpJP.mjs";
|
|
12
11
|
import { EmDashHandlers } from "../../../../types.mjs";
|
|
13
12
|
import { AttachmentInfo } from "./analyze.mjs";
|
|
14
13
|
import { APIRoute } from "astro";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media.d.mts","names":[],"sources":["../../../../../../src/astro/routes/api/import/wordpress/media.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"media.d.mts","names":[],"sources":["../../../../../../src/astro/routes/api/import/wordpress/media.ts"],"mappings":";;;;;;;;;;;;;;;cA2Ba,SAAA;;UAGI,mBAAA;EAChB,IAAA;EACA,OAAA;EACA,KAAA;EACA,QAAA;EACA,MAAA;EACA,KAAA;AAAA;;UAIgB,iBAAA;EAChB,IAAA;EATA;EAWA,QAAA,EAAU,KAAA;IACT,IAAA;IACA,WAAA;IACA,MAAA;IACA,OAAA;EAAA;EAPe;EAUhB,MAAA,EAAQ,KAAA;IACP,IAAA;IACA,WAAA;IACA,KAAA;EAAA;EAGa;EAAd,MAAA,EAAQ,MAAA;AAAA;AAAA,cAGI,IAAA,EAAM,QAAA;AAAA,iBAqEG,uBAAA,CACrB,WAAA,EAAa,cAAA,IACb,EAAA,EAAI,WAAA,CAAY,cAAA,SAChB,OAAA,EAAS,WAAA,CAAY,cAAA,cACrB,UAAA,GAAa,QAAA,EAAU,mBAAA,YACrB,OAAA,CAAQ,iBAAA"}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import "../../../../../base64-
|
|
2
|
-
import "../../../../../types-
|
|
1
|
+
import "../../../../../base64-B-PsqheR.mjs";
|
|
2
|
+
import "../../../../../types-D1iJ3DpO.mjs";
|
|
3
3
|
import { t as enrichImageMetadata } from "../../../../../enrich-CFJJgxs_.mjs";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { n as parseBody, t as isParseError } from "../../../../../parse-
|
|
7
|
-
import "../../../../../
|
|
8
|
-
import
|
|
9
|
-
import "../../../../../
|
|
4
|
+
import { a as validateExternalUrl, r as ssrfSafeFetch, t as SsrfError } from "../../../../../ssrf-CviKqWmq.mjs";
|
|
5
|
+
import { n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-CEGF6UZb.mjs";
|
|
6
|
+
import { n as parseBody, t as isParseError } from "../../../../../parse-C_-6klII.mjs";
|
|
7
|
+
import "../../../../../media-kIV1IxFf.mjs";
|
|
8
|
+
import "../../../../../redirects-BBq3n2Rj.mjs";
|
|
9
|
+
import { C as wpMediaImportBody } from "../../../../../relations-5_avdrN_.mjs";
|
|
10
|
+
import "../../../../../status-COfycGIU.mjs";
|
|
10
11
|
import "../../../../../api/schemas/index.mjs";
|
|
11
|
-
import "../../../../../ssrf-
|
|
12
|
-
import {
|
|
12
|
+
import "../../../../../ssrf-BB__xfNM.mjs";
|
|
13
|
+
import { r as requirePerm } from "../../../../../authorize-WxsiePzy.mjs";
|
|
13
14
|
import { ulid } from "ulidx";
|
|
14
15
|
import mime from "mime/lite";
|
|
15
16
|
import * as path from "node:path";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/import/wordpress/media.ts"],"sourcesContent":["/**\n * WordPress media import endpoint\n *\n * POST /_emdash/api/import/wordpress/media\n *\n * Downloads media attachments from WordPress URLs and uploads to EmDash storage.\n * Streams progress updates as newline-delimited JSON (NDJSON).\n * Each line is either a progress update or the final result.\n */\n\nimport * as path from \"node:path\";\n\nimport type { APIRoute } from \"astro\";\nimport { MediaRepository, computeContentHash } from \"emdash\";\nimport mime from \"mime/lite\";\nimport { ulid } from \"ulidx\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { wpMediaImportBody } from \"#api/schemas.js\";\nimport { validateExternalUrl, ssrfSafeFetch, SsrfError } from \"#import/ssrf.js\";\nimport { enrichImageMetadata } from \"#media/enrich.js\";\nimport type { EmDashHandlers } from \"#types\";\n\nimport type { AttachmentInfo } from \"./analyze.js\";\n\nexport const prerender = false;\n\n/** Progress update sent during streaming */\nexport interface MediaImportProgress {\n\ttype: \"progress\";\n\tcurrent: number;\n\ttotal: number;\n\tfilename?: string;\n\tstatus: \"downloading\" | \"uploading\" | \"done\" | \"skipped\" | \"failed\";\n\terror?: string;\n}\n\n/** Final result sent at end of stream */\nexport interface MediaImportResult {\n\ttype?: \"result\";\n\t/** Successfully imported items */\n\timported: Array<{\n\t\twpId?: number;\n\t\toriginalUrl: string;\n\t\tnewUrl: string;\n\t\tmediaId: string;\n\t}>;\n\t/** Failed items */\n\tfailed: Array<{\n\t\twpId?: number;\n\t\toriginalUrl: string;\n\t\terror: string;\n\t}>;\n\t/** Map of old URLs to new URLs (for content rewriting) */\n\turlMap: Record<string, string>;\n}\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tconst denied = requirePerm(user, \"import:execute\");\n\tif (denied) return denied;\n\n\tif (!emdash?.storage) {\n\t\treturn apiError(\"NO_STORAGE\", \"Storage not configured. Media import requires storage.\", 501);\n\t}\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NO_DB\", \"Database not initialized\", 500);\n\t}\n\n\ttry {\n\t\tconst body = await parseBody(request, wpMediaImportBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst attachments = body.attachments as AttachmentInfo[];\n\n\t\t// Check if streaming is requested (default: true)\n\t\tconst shouldStream = body.stream !== false;\n\n\t\tif (shouldStream) {\n\t\t\t// Stream progress updates as NDJSON\n\t\t\tconst stream = new ReadableStream({\n\t\t\t\tasync start(controller) {\n\t\t\t\t\tconst encoder = new TextEncoder();\n\t\t\t\t\tconst sendProgress = (progress: MediaImportProgress) => {\n\t\t\t\t\t\tcontroller.enqueue(encoder.encode(JSON.stringify(progress) + \"\\n\"));\n\t\t\t\t\t};\n\n\t\t\t\t\tconst result = await importMediaWithProgress(\n\t\t\t\t\t\tattachments,\n\t\t\t\t\t\temdash.db,\n\t\t\t\t\t\temdash.storage,\n\t\t\t\t\t\tsendProgress,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Send final result\n\t\t\t\t\tcontroller.enqueue(encoder.encode(JSON.stringify({ ...result, type: \"result\" }) + \"\\n\"));\n\t\t\t\t\tcontroller.close();\n\t\t\t\t},\n\t\t\t});\n\n\t\t\treturn new Response(stream, {\n\t\t\t\tstatus: 200,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/x-ndjson\",\n\t\t\t\t\t\"Cache-Control\": \"private, no-store\",\n\t\t\t\t\t\"Transfer-Encoding\": \"chunked\",\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\t// Non-streaming mode\n\t\tconst result = await importMediaWithProgress(\n\t\t\tattachments,\n\t\t\temdash.db,\n\t\t\temdash.storage,\n\t\t\t() => {}, // No-op progress callback\n\t\t);\n\n\t\treturn apiSuccess(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to import media\", \"IMPORT_ERROR\");\n\t}\n};\n\nexport async function importMediaWithProgress(\n\tattachments: AttachmentInfo[],\n\tdb: NonNullable<EmDashHandlers[\"db\"]>,\n\tstorage: NonNullable<EmDashHandlers[\"storage\"]>,\n\tonProgress: (progress: MediaImportProgress) => void,\n): Promise<MediaImportResult> {\n\tconst repo = new MediaRepository(db);\n\tconst total = attachments.length;\n\n\tconst result: MediaImportResult = {\n\t\timported: [],\n\t\tfailed: [],\n\t\turlMap: {},\n\t};\n\n\tfor (let i = 0; i < attachments.length; i++) {\n\t\tconst attachment = attachments[i];\n\t\tconst current = i + 1;\n\t\tconst filename = attachment.filename || `file-${attachment.id}`;\n\n\t\tif (!attachment.url) {\n\t\t\tresult.failed.push({\n\t\t\t\twpId: attachment.id,\n\t\t\t\toriginalUrl: \"\",\n\t\t\t\terror: \"No URL provided\",\n\t\t\t});\n\t\t\tonProgress({\n\t\t\t\ttype: \"progress\",\n\t\t\t\tcurrent,\n\t\t\t\ttotal,\n\t\t\t\tfilename,\n\t\t\t\tstatus: \"failed\",\n\t\t\t\terror: \"No URL provided\",\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\ttry {\n\t\t\t// SSRF: validate URL before fetching\n\t\t\ttry {\n\t\t\t\tvalidateExternalUrl(attachment.url);\n\t\t\t} catch (e) {\n\t\t\t\tconst msg = e instanceof SsrfError ? e.message : \"Invalid URL\";\n\t\t\t\tresult.failed.push({\n\t\t\t\t\twpId: attachment.id,\n\t\t\t\t\toriginalUrl: attachment.url,\n\t\t\t\t\terror: `Blocked: ${msg}`,\n\t\t\t\t});\n\t\t\t\tonProgress({\n\t\t\t\t\ttype: \"progress\",\n\t\t\t\t\tcurrent,\n\t\t\t\t\ttotal,\n\t\t\t\t\tfilename,\n\t\t\t\t\tstatus: \"failed\",\n\t\t\t\t\terror: `Blocked: ${msg}`,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Report downloading\n\t\t\tonProgress({\n\t\t\t\ttype: \"progress\",\n\t\t\t\tcurrent,\n\t\t\t\ttotal,\n\t\t\t\tfilename,\n\t\t\t\tstatus: \"downloading\",\n\t\t\t});\n\n\t\t\t// Download from WordPress (ssrfSafeFetch re-validates redirect targets)\n\t\t\tconst response = await ssrfSafeFetch(attachment.url, {\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": \"EmDash-Importer/1.0\",\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tresult.failed.push({\n\t\t\t\t\twpId: attachment.id,\n\t\t\t\t\toriginalUrl: attachment.url,\n\t\t\t\t\terror: `HTTP ${response.status}: ${response.statusText}`,\n\t\t\t\t});\n\t\t\t\tonProgress({\n\t\t\t\t\ttype: \"progress\",\n\t\t\t\t\tcurrent,\n\t\t\t\t\ttotal,\n\t\t\t\t\tfilename,\n\t\t\t\t\tstatus: \"failed\",\n\t\t\t\t\terror: `HTTP ${response.status}`,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Get content type from response or guess from filename\n\t\t\tconst contentType =\n\t\t\t\tresponse.headers.get(\"content-type\") || attachment.mimeType || \"application/octet-stream\";\n\n\t\t\t// Get the file data\n\t\t\tconst buffer = await response.arrayBuffer();\n\t\t\tconst size = buffer.byteLength;\n\n\t\t\t// Compute content hash for deduplication\n\t\t\tconst contentHash = await computeContentHash(buffer);\n\n\t\t\t// Check if we already have this exact content\n\t\t\tconst existing = await repo.findByContentHash(contentHash);\n\t\t\tif (existing) {\n\t\t\t\t// Same content already exists - reuse it\n\t\t\t\tconst existingUrl = `/_emdash/api/media/file/${existing.storageKey}`;\n\t\t\t\tresult.urlMap[attachment.url] = existingUrl;\n\t\t\t\tresult.imported.push({\n\t\t\t\t\twpId: attachment.id,\n\t\t\t\t\toriginalUrl: attachment.url,\n\t\t\t\t\tnewUrl: existingUrl,\n\t\t\t\t\tmediaId: existing.id,\n\t\t\t\t});\n\t\t\t\tonProgress({\n\t\t\t\t\ttype: \"progress\",\n\t\t\t\t\tcurrent,\n\t\t\t\t\ttotal,\n\t\t\t\t\tfilename,\n\t\t\t\t\tstatus: \"skipped\",\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Report uploading\n\t\t\tonProgress({\n\t\t\t\ttype: \"progress\",\n\t\t\t\tcurrent,\n\t\t\t\ttotal,\n\t\t\t\tfilename,\n\t\t\t\tstatus: \"uploading\",\n\t\t\t});\n\n\t\t\t// Generate storage key\n\t\t\tconst id = ulid();\n\t\t\tconst ext = attachment.filename\n\t\t\t\t? path.extname(attachment.filename)\n\t\t\t\t: getExtensionFromMimeType(contentType);\n\t\t\tconst storageKey = `${id}${ext}`;\n\n\t\t\t// Upload to storage\n\t\t\tawait storage.upload({\n\t\t\t\tkey: storageKey,\n\t\t\t\tbody: new Uint8Array(buffer),\n\t\t\t\tcontentType,\n\t\t\t});\n\n\t\t\t// Derive dimensions + LQIP placeholders (no-op for non-images).\n\t\t\tconst enriched = await enrichImageMetadata(new Uint8Array(buffer), contentType);\n\n\t\t\t// Create media record with content hash\n\t\t\tconst mediaItem = await repo.create({\n\t\t\t\tfilename: attachment.filename || `media-${attachment.id}${ext}`,\n\t\t\t\tmimeType: contentType,\n\t\t\t\tsize,\n\t\t\t\tstorageKey,\n\t\t\t\tcontentHash,\n\t\t\t\twidth: enriched.width,\n\t\t\t\theight: enriched.height,\n\t\t\t\tblurhash: enriched.blurhash,\n\t\t\t\tdominantColor: enriched.dominantColor,\n\t\t\t});\n\n\t\t\t// Build the new URL\n\t\t\tconst newUrl = `/_emdash/api/media/file/${storageKey}`;\n\n\t\t\tresult.imported.push({\n\t\t\t\twpId: attachment.id,\n\t\t\t\toriginalUrl: attachment.url,\n\t\t\t\tnewUrl,\n\t\t\t\tmediaId: mediaItem.id,\n\t\t\t});\n\n\t\t\t// Add to URL map\n\t\t\tresult.urlMap[attachment.url] = newUrl;\n\n\t\t\t// Report done\n\t\t\tonProgress({\n\t\t\t\ttype: \"progress\",\n\t\t\t\tcurrent,\n\t\t\t\ttotal,\n\t\t\t\tfilename,\n\t\t\t\tstatus: \"done\",\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error(`Media import error for \"${filename}\":`, error);\n\t\t\tconst errorMsg = \"Failed to import media\";\n\t\t\tresult.failed.push({\n\t\t\t\twpId: attachment.id,\n\t\t\t\toriginalUrl: attachment.url,\n\t\t\t\terror: errorMsg,\n\t\t\t});\n\t\t\tonProgress({\n\t\t\t\ttype: \"progress\",\n\t\t\t\tcurrent,\n\t\t\t\ttotal,\n\t\t\t\tfilename,\n\t\t\t\tstatus: \"failed\",\n\t\t\t\terror: errorMsg,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn result;\n}\n\nfunction getExtensionFromMimeType(mimeType: string): string {\n\tconst ext = mime.getExtension(mimeType);\n\treturn ext ? `.${ext}` : \"\";\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"media.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/import/wordpress/media.ts"],"sourcesContent":["/**\n * WordPress media import endpoint\n *\n * POST /_emdash/api/import/wordpress/media\n *\n * Downloads media attachments from WordPress URLs and uploads to EmDash storage.\n * Streams progress updates as newline-delimited JSON (NDJSON).\n * Each line is either a progress update or the final result.\n */\n\nimport * as path from \"node:path\";\n\nimport type { APIRoute } from \"astro\";\nimport { MediaRepository, computeContentHash } from \"emdash\";\nimport mime from \"mime/lite\";\nimport { ulid } from \"ulidx\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { wpMediaImportBody } from \"#api/schemas.js\";\nimport { validateExternalUrl, ssrfSafeFetch, SsrfError } from \"#import/ssrf.js\";\nimport { enrichImageMetadata } from \"#media/enrich.js\";\nimport type { EmDashHandlers } from \"#types\";\n\nimport type { AttachmentInfo } from \"./analyze.js\";\n\nexport const prerender = false;\n\n/** Progress update sent during streaming */\nexport interface MediaImportProgress {\n\ttype: \"progress\";\n\tcurrent: number;\n\ttotal: number;\n\tfilename?: string;\n\tstatus: \"downloading\" | \"uploading\" | \"done\" | \"skipped\" | \"failed\";\n\terror?: string;\n}\n\n/** Final result sent at end of stream */\nexport interface MediaImportResult {\n\ttype?: \"result\";\n\t/** Successfully imported items */\n\timported: Array<{\n\t\twpId?: number;\n\t\toriginalUrl: string;\n\t\tnewUrl: string;\n\t\tmediaId: string;\n\t}>;\n\t/** Failed items */\n\tfailed: Array<{\n\t\twpId?: number;\n\t\toriginalUrl: string;\n\t\terror: string;\n\t}>;\n\t/** Map of old URLs to new URLs (for content rewriting) */\n\turlMap: Record<string, string>;\n}\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tconst denied = requirePerm(user, \"import:execute\");\n\tif (denied) return denied;\n\n\tif (!emdash?.storage) {\n\t\treturn apiError(\"NO_STORAGE\", \"Storage not configured. Media import requires storage.\", 501);\n\t}\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NO_DB\", \"Database not initialized\", 500);\n\t}\n\n\ttry {\n\t\tconst body = await parseBody(request, wpMediaImportBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst attachments = body.attachments as AttachmentInfo[];\n\n\t\t// Check if streaming is requested (default: true)\n\t\tconst shouldStream = body.stream !== false;\n\n\t\tif (shouldStream) {\n\t\t\t// Stream progress updates as NDJSON\n\t\t\tconst stream = new ReadableStream({\n\t\t\t\tasync start(controller) {\n\t\t\t\t\tconst encoder = new TextEncoder();\n\t\t\t\t\tconst sendProgress = (progress: MediaImportProgress) => {\n\t\t\t\t\t\tcontroller.enqueue(encoder.encode(JSON.stringify(progress) + \"\\n\"));\n\t\t\t\t\t};\n\n\t\t\t\t\tconst result = await importMediaWithProgress(\n\t\t\t\t\t\tattachments,\n\t\t\t\t\t\temdash.db,\n\t\t\t\t\t\temdash.storage,\n\t\t\t\t\t\tsendProgress,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Send final result\n\t\t\t\t\tcontroller.enqueue(encoder.encode(JSON.stringify({ ...result, type: \"result\" }) + \"\\n\"));\n\t\t\t\t\tcontroller.close();\n\t\t\t\t},\n\t\t\t});\n\n\t\t\treturn new Response(stream, {\n\t\t\t\tstatus: 200,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/x-ndjson\",\n\t\t\t\t\t\"Cache-Control\": \"private, no-store\",\n\t\t\t\t\t\"Transfer-Encoding\": \"chunked\",\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\t// Non-streaming mode\n\t\tconst result = await importMediaWithProgress(\n\t\t\tattachments,\n\t\t\temdash.db,\n\t\t\temdash.storage,\n\t\t\t() => {}, // No-op progress callback\n\t\t);\n\n\t\treturn apiSuccess(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to import media\", \"IMPORT_ERROR\");\n\t}\n};\n\nexport async function importMediaWithProgress(\n\tattachments: AttachmentInfo[],\n\tdb: NonNullable<EmDashHandlers[\"db\"]>,\n\tstorage: NonNullable<EmDashHandlers[\"storage\"]>,\n\tonProgress: (progress: MediaImportProgress) => void,\n): Promise<MediaImportResult> {\n\tconst repo = new MediaRepository(db);\n\tconst total = attachments.length;\n\n\tconst result: MediaImportResult = {\n\t\timported: [],\n\t\tfailed: [],\n\t\turlMap: {},\n\t};\n\n\tfor (let i = 0; i < attachments.length; i++) {\n\t\tconst attachment = attachments[i];\n\t\tconst current = i + 1;\n\t\tconst filename = attachment.filename || `file-${attachment.id}`;\n\n\t\tif (!attachment.url) {\n\t\t\tresult.failed.push({\n\t\t\t\twpId: attachment.id,\n\t\t\t\toriginalUrl: \"\",\n\t\t\t\terror: \"No URL provided\",\n\t\t\t});\n\t\t\tonProgress({\n\t\t\t\ttype: \"progress\",\n\t\t\t\tcurrent,\n\t\t\t\ttotal,\n\t\t\t\tfilename,\n\t\t\t\tstatus: \"failed\",\n\t\t\t\terror: \"No URL provided\",\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\ttry {\n\t\t\t// SSRF: validate URL before fetching\n\t\t\ttry {\n\t\t\t\tvalidateExternalUrl(attachment.url);\n\t\t\t} catch (e) {\n\t\t\t\tconst msg = e instanceof SsrfError ? e.message : \"Invalid URL\";\n\t\t\t\tresult.failed.push({\n\t\t\t\t\twpId: attachment.id,\n\t\t\t\t\toriginalUrl: attachment.url,\n\t\t\t\t\terror: `Blocked: ${msg}`,\n\t\t\t\t});\n\t\t\t\tonProgress({\n\t\t\t\t\ttype: \"progress\",\n\t\t\t\t\tcurrent,\n\t\t\t\t\ttotal,\n\t\t\t\t\tfilename,\n\t\t\t\t\tstatus: \"failed\",\n\t\t\t\t\terror: `Blocked: ${msg}`,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Report downloading\n\t\t\tonProgress({\n\t\t\t\ttype: \"progress\",\n\t\t\t\tcurrent,\n\t\t\t\ttotal,\n\t\t\t\tfilename,\n\t\t\t\tstatus: \"downloading\",\n\t\t\t});\n\n\t\t\t// Download from WordPress (ssrfSafeFetch re-validates redirect targets)\n\t\t\tconst response = await ssrfSafeFetch(attachment.url, {\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": \"EmDash-Importer/1.0\",\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tresult.failed.push({\n\t\t\t\t\twpId: attachment.id,\n\t\t\t\t\toriginalUrl: attachment.url,\n\t\t\t\t\terror: `HTTP ${response.status}: ${response.statusText}`,\n\t\t\t\t});\n\t\t\t\tonProgress({\n\t\t\t\t\ttype: \"progress\",\n\t\t\t\t\tcurrent,\n\t\t\t\t\ttotal,\n\t\t\t\t\tfilename,\n\t\t\t\t\tstatus: \"failed\",\n\t\t\t\t\terror: `HTTP ${response.status}`,\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Get content type from response or guess from filename\n\t\t\tconst contentType =\n\t\t\t\tresponse.headers.get(\"content-type\") || attachment.mimeType || \"application/octet-stream\";\n\n\t\t\t// Get the file data\n\t\t\tconst buffer = await response.arrayBuffer();\n\t\t\tconst size = buffer.byteLength;\n\n\t\t\t// Compute content hash for deduplication\n\t\t\tconst contentHash = await computeContentHash(buffer);\n\n\t\t\t// Check if we already have this exact content\n\t\t\tconst existing = await repo.findByContentHash(contentHash);\n\t\t\tif (existing) {\n\t\t\t\t// Same content already exists - reuse it\n\t\t\t\tconst existingUrl = `/_emdash/api/media/file/${existing.storageKey}`;\n\t\t\t\tresult.urlMap[attachment.url] = existingUrl;\n\t\t\t\tresult.imported.push({\n\t\t\t\t\twpId: attachment.id,\n\t\t\t\t\toriginalUrl: attachment.url,\n\t\t\t\t\tnewUrl: existingUrl,\n\t\t\t\t\tmediaId: existing.id,\n\t\t\t\t});\n\t\t\t\tonProgress({\n\t\t\t\t\ttype: \"progress\",\n\t\t\t\t\tcurrent,\n\t\t\t\t\ttotal,\n\t\t\t\t\tfilename,\n\t\t\t\t\tstatus: \"skipped\",\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Report uploading\n\t\t\tonProgress({\n\t\t\t\ttype: \"progress\",\n\t\t\t\tcurrent,\n\t\t\t\ttotal,\n\t\t\t\tfilename,\n\t\t\t\tstatus: \"uploading\",\n\t\t\t});\n\n\t\t\t// Generate storage key\n\t\t\tconst id = ulid();\n\t\t\tconst ext = attachment.filename\n\t\t\t\t? path.extname(attachment.filename)\n\t\t\t\t: getExtensionFromMimeType(contentType);\n\t\t\tconst storageKey = `${id}${ext}`;\n\n\t\t\t// Upload to storage\n\t\t\tawait storage.upload({\n\t\t\t\tkey: storageKey,\n\t\t\t\tbody: new Uint8Array(buffer),\n\t\t\t\tcontentType,\n\t\t\t});\n\n\t\t\t// Derive dimensions + LQIP placeholders (no-op for non-images).\n\t\t\tconst enriched = await enrichImageMetadata(new Uint8Array(buffer), contentType);\n\n\t\t\t// Create media record with content hash\n\t\t\tconst mediaItem = await repo.create({\n\t\t\t\tfilename: attachment.filename || `media-${attachment.id}${ext}`,\n\t\t\t\tmimeType: contentType,\n\t\t\t\tsize,\n\t\t\t\tstorageKey,\n\t\t\t\tcontentHash,\n\t\t\t\twidth: enriched.width,\n\t\t\t\theight: enriched.height,\n\t\t\t\tblurhash: enriched.blurhash,\n\t\t\t\tdominantColor: enriched.dominantColor,\n\t\t\t});\n\n\t\t\t// Build the new URL\n\t\t\tconst newUrl = `/_emdash/api/media/file/${storageKey}`;\n\n\t\t\tresult.imported.push({\n\t\t\t\twpId: attachment.id,\n\t\t\t\toriginalUrl: attachment.url,\n\t\t\t\tnewUrl,\n\t\t\t\tmediaId: mediaItem.id,\n\t\t\t});\n\n\t\t\t// Add to URL map\n\t\t\tresult.urlMap[attachment.url] = newUrl;\n\n\t\t\t// Report done\n\t\t\tonProgress({\n\t\t\t\ttype: \"progress\",\n\t\t\t\tcurrent,\n\t\t\t\ttotal,\n\t\t\t\tfilename,\n\t\t\t\tstatus: \"done\",\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error(`Media import error for \"${filename}\":`, error);\n\t\t\tconst errorMsg = \"Failed to import media\";\n\t\t\tresult.failed.push({\n\t\t\t\twpId: attachment.id,\n\t\t\t\toriginalUrl: attachment.url,\n\t\t\t\terror: errorMsg,\n\t\t\t});\n\t\t\tonProgress({\n\t\t\t\ttype: \"progress\",\n\t\t\t\tcurrent,\n\t\t\t\ttotal,\n\t\t\t\tfilename,\n\t\t\t\tstatus: \"failed\",\n\t\t\t\terror: errorMsg,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn result;\n}\n\nfunction getExtensionFromMimeType(mimeType: string): string {\n\tconst ext = mime.getExtension(mimeType);\n\treturn ext ? `.${ext}` : \"\";\n}\n"],"mappings":"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"}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import "../../../../../base64-
|
|
2
|
-
import "../../../../../types-
|
|
1
|
+
import "../../../../../base64-B-PsqheR.mjs";
|
|
2
|
+
import "../../../../../types-D1iJ3DpO.mjs";
|
|
3
3
|
import { n as FIELD_TYPES } from "../../../../../types-o7xo7VgH.mjs";
|
|
4
|
-
import { n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-
|
|
5
|
-
import { n as parseBody, t as isParseError } from "../../../../../parse-
|
|
6
|
-
import "../../../../../
|
|
7
|
-
import
|
|
8
|
-
import "../../../../../
|
|
4
|
+
import { n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-CEGF6UZb.mjs";
|
|
5
|
+
import { n as parseBody, t as isParseError } from "../../../../../parse-C_-6klII.mjs";
|
|
6
|
+
import "../../../../../media-kIV1IxFf.mjs";
|
|
7
|
+
import "../../../../../redirects-BBq3n2Rj.mjs";
|
|
8
|
+
import { E as wpPrepareBody } from "../../../../../relations-5_avdrN_.mjs";
|
|
9
|
+
import "../../../../../status-COfycGIU.mjs";
|
|
9
10
|
import "../../../../../api/schemas/index.mjs";
|
|
10
|
-
import {
|
|
11
|
+
import { r as requirePerm } from "../../../../../authorize-WxsiePzy.mjs";
|
|
11
12
|
import { capitalize, sanitizeSlug, singularize } from "./analyze.mjs";
|
|
12
13
|
|
|
13
14
|
//#region src/astro/routes/api/import/wordpress/prepare.ts
|
|
@@ -32,7 +33,7 @@ const POST = async ({ request, locals }) => {
|
|
|
32
33
|
}
|
|
33
34
|
};
|
|
34
35
|
async function prepareImport(db, request) {
|
|
35
|
-
const { SchemaRegistry } = await import("../../../../../registry-
|
|
36
|
+
const { SchemaRegistry } = await import("../../../../../registry-FV15nLge.mjs").then((n) => n.r);
|
|
36
37
|
const registry = new SchemaRegistry(db);
|
|
37
38
|
const result = {
|
|
38
39
|
success: true,
|
|
@@ -98,7 +99,7 @@ async function prepareImport(db, request) {
|
|
|
98
99
|
"post",
|
|
99
100
|
"page"
|
|
100
101
|
].includes(collectionSlug)) {
|
|
101
|
-
const { FTSManager } = await import("../../../../../fts-manager-
|
|
102
|
+
const { FTSManager } = await import("../../../../../fts-manager-DzqIBrrW.mjs").then((n) => n.n);
|
|
102
103
|
const ftsManager = new FTSManager(db);
|
|
103
104
|
if ((await ftsManager.getSearchableFields(collectionSlug)).length > 0) try {
|
|
104
105
|
await ftsManager.enableSearch(collectionSlug);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepare.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/import/wordpress/prepare.ts"],"sourcesContent":["/**\n * WordPress import prepare endpoint\n *\n * POST /_emdash/api/import/wordpress/prepare\n *\n * Creates collections and fields needed for import.\n * This is called after analyze, before execute.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { wpPrepareBody } from \"#api/schemas.js\";\nimport { FIELD_TYPES, type FieldType } from \"#schema/types.js\";\nimport type { EmDashHandlers } from \"#types\";\n\nimport { capitalize, sanitizeSlug, singularize, type ImportFieldDef } from \"./analyze.js\";\n\n/** Validate that a string is a known FieldType, returning undefined if not */\nfunction asFieldType(value: string): FieldType | undefined {\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- validated by includes check\n\treturn (FIELD_TYPES as readonly string[]).includes(value) ? (value as FieldType) : undefined;\n}\n\nexport const prerender = false;\n\ninterface PrepareRequest {\n\tpostTypes: Array<{\n\t\tname: string;\n\t\tcollection: string;\n\t\tfields: ImportFieldDef[];\n\t}>;\n}\n\nexport interface PrepareResult {\n\tsuccess: boolean;\n\tcollectionsCreated: string[];\n\tfieldsCreated: Array<{ collection: string; field: string }>;\n\terrors: Array<{ collection: string; error: string }>;\n}\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash not configured\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"import:execute\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst body = await parseBody(request, wpPrepareBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- Zod schema output narrowed to PrepareRequest\n\t\tconst result = await prepareImport(emdash.db, body as PrepareRequest);\n\n\t\t// Invalidate the URL pattern cache when prepare adds new collections so\n\t\t// public routing picks up their patterns immediately. The manifest\n\t\t// itself is built fresh per admin request, so cross-request\n\t\t// staleness (the original failure mode in #747) is no longer\n\t\t// possible — the execute step always reads live schema.\n\t\tif (result.collectionsCreated.length > 0) {\n\t\t\temdash.invalidateUrlPatternCache();\n\t\t}\n\n\t\treturn apiSuccess(result, result.success ? 200 : 400);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to prepare import\", \"WXR_PREPARE_ERROR\");\n\t}\n};\n\nasync function prepareImport(\n\tdb: NonNullable<EmDashHandlers[\"db\"]>,\n\trequest: PrepareRequest,\n): Promise<PrepareResult> {\n\tconst { SchemaRegistry } = await import(\"#schema/registry.js\");\n\tconst registry = new SchemaRegistry(db);\n\n\tconst result: PrepareResult = {\n\t\tsuccess: true,\n\t\tcollectionsCreated: [],\n\t\tfieldsCreated: [],\n\t\terrors: [],\n\t};\n\n\tfor (const postType of request.postTypes) {\n\t\tconst collectionSlug = sanitizeSlug(postType.collection);\n\n\t\ttry {\n\t\t\t// Check if collection exists\n\t\t\tlet collection = await registry.getCollection(collectionSlug);\n\n\t\t\tif (!collection) {\n\t\t\t\t// Create the collection\n\t\t\t\tconst label = capitalize(collectionSlug);\n\t\t\t\tconst labelSingular = capitalize(singularize(collectionSlug));\n\n\t\t\t\t// Enable search by default for posts and pages\n\t\t\t\tconst isSearchable = [\"posts\", \"pages\", \"post\", \"page\"].includes(collectionSlug);\n\t\t\t\tconst supports: (\"revisions\" | \"drafts\" | \"search\")[] = [\"revisions\", \"drafts\"];\n\t\t\t\tif (isSearchable) {\n\t\t\t\t\tsupports.push(\"search\");\n\t\t\t\t}\n\n\t\t\t\t// Default URL patterns for known post types\n\t\t\t\tconst urlPattern =\n\t\t\t\t\tcollectionSlug === \"pages\"\n\t\t\t\t\t\t? \"/{slug}\"\n\t\t\t\t\t\t: collectionSlug === \"posts\"\n\t\t\t\t\t\t\t? \"/blog/{slug}\"\n\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\tcollection = await registry.createCollection({\n\t\t\t\t\tslug: collectionSlug,\n\t\t\t\t\tlabel,\n\t\t\t\t\tlabelSingular,\n\t\t\t\t\tdescription: `Imported from WordPress post type: ${postType.name}`,\n\t\t\t\t\tsupports,\n\t\t\t\t\turlPattern,\n\t\t\t\t});\n\n\t\t\t\tresult.collectionsCreated.push(collectionSlug);\n\t\t\t}\n\n\t\t\t// Create missing fields\n\t\t\tconst existingFields = await registry.listFields(collection.id);\n\t\t\tconst existingFieldSlugs = new Set(existingFields.map((f) => f.slug));\n\n\t\t\tfor (const field of postType.fields) {\n\t\t\t\tif (existingFieldSlugs.has(field.slug)) {\n\t\t\t\t\t// Field already exists - skip\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst fieldType = asFieldType(field.type);\n\t\t\t\tif (!fieldType) {\n\t\t\t\t\tresult.errors.push({\n\t\t\t\t\t\tcollection: collectionSlug,\n\t\t\t\t\t\terror: `Unknown field type \"${field.type}\" for field \"${field.slug}\"`,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tawait registry.createField(collectionSlug, {\n\t\t\t\t\tslug: field.slug,\n\t\t\t\t\tlabel: field.label,\n\t\t\t\t\ttype: fieldType,\n\t\t\t\t\trequired: field.required,\n\t\t\t\t\tunique: false,\n\t\t\t\t\tsearchable: field.searchable ?? false,\n\t\t\t\t\tsortOrder: existingFields.length + result.fieldsCreated.length,\n\t\t\t\t});\n\n\t\t\t\tresult.fieldsCreated.push({\n\t\t\t\t\tcollection: collectionSlug,\n\t\t\t\t\tfield: field.slug,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Enable search if collection supports it and has searchable fields\n\t\t\tconst isSearchable = [\"posts\", \"pages\", \"post\", \"page\"].includes(collectionSlug);\n\t\t\tif (isSearchable) {\n\t\t\t\tconst { FTSManager } = await import(\"#search/fts-manager.js\");\n\t\t\t\tconst ftsManager = new FTSManager(db);\n\n\t\t\t\tconst searchableFields = await ftsManager.getSearchableFields(collectionSlug);\n\t\t\t\tif (searchableFields.length > 0) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait ftsManager.enableSearch(collectionSlug);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Ignore - search can be enabled manually later\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(`Prepare error for collection \"${collectionSlug}\":`, error);\n\t\t\tresult.success = false;\n\t\t\tresult.errors.push({\n\t\t\t\tcollection: collectionSlug,\n\t\t\t\terror: \"Failed to prepare collection\",\n\t\t\t});\n\t\t}\n\t}\n\n\treturn result;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"prepare.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/import/wordpress/prepare.ts"],"sourcesContent":["/**\n * WordPress import prepare endpoint\n *\n * POST /_emdash/api/import/wordpress/prepare\n *\n * Creates collections and fields needed for import.\n * This is called after analyze, before execute.\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { wpPrepareBody } from \"#api/schemas.js\";\nimport { FIELD_TYPES, type FieldType } from \"#schema/types.js\";\nimport type { EmDashHandlers } from \"#types\";\n\nimport { capitalize, sanitizeSlug, singularize, type ImportFieldDef } from \"./analyze.js\";\n\n/** Validate that a string is a known FieldType, returning undefined if not */\nfunction asFieldType(value: string): FieldType | undefined {\n\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- validated by includes check\n\treturn (FIELD_TYPES as readonly string[]).includes(value) ? (value as FieldType) : undefined;\n}\n\nexport const prerender = false;\n\ninterface PrepareRequest {\n\tpostTypes: Array<{\n\t\tname: string;\n\t\tcollection: string;\n\t\tfields: ImportFieldDef[];\n\t}>;\n}\n\nexport interface PrepareResult {\n\tsuccess: boolean;\n\tcollectionsCreated: string[];\n\tfieldsCreated: Array<{ collection: string; field: string }>;\n\terrors: Array<{ collection: string; error: string }>;\n}\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash not configured\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"import:execute\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst body = await parseBody(request, wpPrepareBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- Zod schema output narrowed to PrepareRequest\n\t\tconst result = await prepareImport(emdash.db, body as PrepareRequest);\n\n\t\t// Invalidate the URL pattern cache when prepare adds new collections so\n\t\t// public routing picks up their patterns immediately. The manifest\n\t\t// itself is built fresh per admin request, so cross-request\n\t\t// staleness (the original failure mode in #747) is no longer\n\t\t// possible — the execute step always reads live schema.\n\t\tif (result.collectionsCreated.length > 0) {\n\t\t\temdash.invalidateUrlPatternCache();\n\t\t}\n\n\t\treturn apiSuccess(result, result.success ? 200 : 400);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to prepare import\", \"WXR_PREPARE_ERROR\");\n\t}\n};\n\nasync function prepareImport(\n\tdb: NonNullable<EmDashHandlers[\"db\"]>,\n\trequest: PrepareRequest,\n): Promise<PrepareResult> {\n\tconst { SchemaRegistry } = await import(\"#schema/registry.js\");\n\tconst registry = new SchemaRegistry(db);\n\n\tconst result: PrepareResult = {\n\t\tsuccess: true,\n\t\tcollectionsCreated: [],\n\t\tfieldsCreated: [],\n\t\terrors: [],\n\t};\n\n\tfor (const postType of request.postTypes) {\n\t\tconst collectionSlug = sanitizeSlug(postType.collection);\n\n\t\ttry {\n\t\t\t// Check if collection exists\n\t\t\tlet collection = await registry.getCollection(collectionSlug);\n\n\t\t\tif (!collection) {\n\t\t\t\t// Create the collection\n\t\t\t\tconst label = capitalize(collectionSlug);\n\t\t\t\tconst labelSingular = capitalize(singularize(collectionSlug));\n\n\t\t\t\t// Enable search by default for posts and pages\n\t\t\t\tconst isSearchable = [\"posts\", \"pages\", \"post\", \"page\"].includes(collectionSlug);\n\t\t\t\tconst supports: (\"revisions\" | \"drafts\" | \"search\")[] = [\"revisions\", \"drafts\"];\n\t\t\t\tif (isSearchable) {\n\t\t\t\t\tsupports.push(\"search\");\n\t\t\t\t}\n\n\t\t\t\t// Default URL patterns for known post types\n\t\t\t\tconst urlPattern =\n\t\t\t\t\tcollectionSlug === \"pages\"\n\t\t\t\t\t\t? \"/{slug}\"\n\t\t\t\t\t\t: collectionSlug === \"posts\"\n\t\t\t\t\t\t\t? \"/blog/{slug}\"\n\t\t\t\t\t\t\t: undefined;\n\n\t\t\t\tcollection = await registry.createCollection({\n\t\t\t\t\tslug: collectionSlug,\n\t\t\t\t\tlabel,\n\t\t\t\t\tlabelSingular,\n\t\t\t\t\tdescription: `Imported from WordPress post type: ${postType.name}`,\n\t\t\t\t\tsupports,\n\t\t\t\t\turlPattern,\n\t\t\t\t});\n\n\t\t\t\tresult.collectionsCreated.push(collectionSlug);\n\t\t\t}\n\n\t\t\t// Create missing fields\n\t\t\tconst existingFields = await registry.listFields(collection.id);\n\t\t\tconst existingFieldSlugs = new Set(existingFields.map((f) => f.slug));\n\n\t\t\tfor (const field of postType.fields) {\n\t\t\t\tif (existingFieldSlugs.has(field.slug)) {\n\t\t\t\t\t// Field already exists - skip\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst fieldType = asFieldType(field.type);\n\t\t\t\tif (!fieldType) {\n\t\t\t\t\tresult.errors.push({\n\t\t\t\t\t\tcollection: collectionSlug,\n\t\t\t\t\t\terror: `Unknown field type \"${field.type}\" for field \"${field.slug}\"`,\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tawait registry.createField(collectionSlug, {\n\t\t\t\t\tslug: field.slug,\n\t\t\t\t\tlabel: field.label,\n\t\t\t\t\ttype: fieldType,\n\t\t\t\t\trequired: field.required,\n\t\t\t\t\tunique: false,\n\t\t\t\t\tsearchable: field.searchable ?? false,\n\t\t\t\t\tsortOrder: existingFields.length + result.fieldsCreated.length,\n\t\t\t\t});\n\n\t\t\t\tresult.fieldsCreated.push({\n\t\t\t\t\tcollection: collectionSlug,\n\t\t\t\t\tfield: field.slug,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Enable search if collection supports it and has searchable fields\n\t\t\tconst isSearchable = [\"posts\", \"pages\", \"post\", \"page\"].includes(collectionSlug);\n\t\t\tif (isSearchable) {\n\t\t\t\tconst { FTSManager } = await import(\"#search/fts-manager.js\");\n\t\t\t\tconst ftsManager = new FTSManager(db);\n\n\t\t\t\tconst searchableFields = await ftsManager.getSearchableFields(collectionSlug);\n\t\t\t\tif (searchableFields.length > 0) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait ftsManager.enableSearch(collectionSlug);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Ignore - search can be enabled manually later\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(`Prepare error for collection \"${collectionSlug}\":`, error);\n\t\t\tresult.success = false;\n\t\t\tresult.errors.push({\n\t\t\t\tcollection: collectionSlug,\n\t\t\t\terror: \"Failed to prepare collection\",\n\t\t\t});\n\t\t}\n\t}\n\n\treturn result;\n}\n"],"mappings":"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"}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import "../../../../../options-
|
|
2
|
-
import "../../../../../types-
|
|
3
|
-
import "../../../../../types-
|
|
4
|
-
import "../../../../../relations-
|
|
5
|
-
import { f as MediaProvider } from "../../../../../placeholder-
|
|
6
|
-
import {
|
|
7
|
-
import "../../../../../runner-
|
|
8
|
-
import "../../../../../index-
|
|
9
|
-
import "../../../../../
|
|
10
|
-
import "../../../../../
|
|
11
|
-
import "../../../../../
|
|
12
|
-
import "../../../../../validate-9jLuE301.mjs";
|
|
1
|
+
import "../../../../../options-BqMkWfYa.mjs";
|
|
2
|
+
import "../../../../../types-DPKhI5ib.mjs";
|
|
3
|
+
import "../../../../../types-BvB7gDOD.mjs";
|
|
4
|
+
import "../../../../../relations-Bh8jlFsU.mjs";
|
|
5
|
+
import { f as MediaProvider } from "../../../../../placeholder-Dop47JMM.mjs";
|
|
6
|
+
import { wr as markContentMediaUsageCollectionStaleSafely } from "../../../../../index-wYnC6u4o.mjs";
|
|
7
|
+
import "../../../../../runner-Dd8m8k9F.mjs";
|
|
8
|
+
import "../../../../../index-BEui-cRd.mjs";
|
|
9
|
+
import "../../../../../types-C7U0HlEr.mjs";
|
|
10
|
+
import "../../../../../hreflang-CIxH_LKz.mjs";
|
|
11
|
+
import "../../../../../validate-DULfgpJP.mjs";
|
|
13
12
|
import { EmDashHandlers } from "../../../../types.mjs";
|
|
14
13
|
import { APIRoute } from "astro";
|
|
15
14
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rewrite-urls.d.mts","names":[],"sources":["../../../../../../src/astro/routes/api/import/wordpress/rewrite-urls.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"rewrite-urls.d.mts","names":[],"sources":["../../../../../../src/astro/routes/api/import/wordpress/rewrite-urls.ts"],"mappings":";;;;;;;;;;;;;;;UAkCiB,iBAAA;EAAiB;EAEjC,OAAA;EAMa;EAJb,YAAA,EAAc,MAAA;EAAd;EAEA,aAAA;EAAA;EAEA,MAAA,EAAQ,KAAA;IAAQ,UAAA;IAAoB,EAAA;IAAY,KAAA;EAAA;AAAA;AAAA,cAGpC,SAAA;AAAA,cAEA,IAAA,EAAM,QAAA;AAAA,iBAiCG,WAAA,CACrB,EAAA,EAAI,WAAA,CAAY,cAAA,SAChB,MAAA,EAAQ,MAAA,kBACR,WAAA,GAAc,EAAA,aAAe,aAAA,cAC7B,WAAA,aACA,wBAAA,UAAiC,0CAAA,GAC/B,OAAA,CAAQ,iBAAA"}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { t as validateIdentifier } from "../../../../../validate-VPnKoIzW.mjs";
|
|
2
|
-
import "../../../../../base64-
|
|
3
|
-
import "../../../../../types-
|
|
2
|
+
import "../../../../../base64-B-PsqheR.mjs";
|
|
3
|
+
import "../../../../../types-D1iJ3DpO.mjs";
|
|
4
4
|
import { n as normalizeMediaValue } from "../../../../../normalize-C-SHXmra.mjs";
|
|
5
|
-
import { s as markContentMediaUsageCollectionStaleSafely } from "../../../../../content-refresh-
|
|
6
|
-
import { n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-
|
|
7
|
-
import { n as parseBody, t as isParseError } from "../../../../../parse-
|
|
8
|
-
import "../../../../../
|
|
9
|
-
import
|
|
10
|
-
import "../../../../../
|
|
5
|
+
import { s as markContentMediaUsageCollectionStaleSafely } from "../../../../../content-refresh-D4khvC0R.mjs";
|
|
6
|
+
import { n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-CEGF6UZb.mjs";
|
|
7
|
+
import { n as parseBody, t as isParseError } from "../../../../../parse-C_-6klII.mjs";
|
|
8
|
+
import "../../../../../media-kIV1IxFf.mjs";
|
|
9
|
+
import "../../../../../redirects-BBq3n2Rj.mjs";
|
|
10
|
+
import { D as wpRewriteUrlsBody } from "../../../../../relations-5_avdrN_.mjs";
|
|
11
|
+
import "../../../../../status-COfycGIU.mjs";
|
|
11
12
|
import "../../../../../api/schemas/index.mjs";
|
|
12
|
-
import {
|
|
13
|
+
import { r as requirePerm } from "../../../../../authorize-WxsiePzy.mjs";
|
|
13
14
|
import { buildBaseUrlMap, extractMediaUrl, findMatchingUrl, rewritePortableTextUrls, rewriteStringUrls } from "./rewrite-url-helpers.mjs";
|
|
14
15
|
import { sql } from "kysely";
|
|
15
16
|
|
|
@@ -36,7 +37,7 @@ const POST = async ({ request, locals }) => {
|
|
|
36
37
|
}
|
|
37
38
|
};
|
|
38
39
|
async function rewriteUrls(db, urlMap, getProvider, collections, markUsageCollectionStale = markContentMediaUsageCollectionStaleSafely) {
|
|
39
|
-
const { SchemaRegistry } = await import("../../../../../registry-
|
|
40
|
+
const { SchemaRegistry } = await import("../../../../../registry-FV15nLge.mjs").then((n) => n.r);
|
|
40
41
|
const registry = new SchemaRegistry(db);
|
|
41
42
|
const result = {
|
|
42
43
|
updated: 0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rewrite-urls.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/import/wordpress/rewrite-urls.ts"],"sourcesContent":["/**\n * WordPress URL rewrite endpoint\n *\n * POST /_emdash/api/import/wordpress/rewrite-urls\n *\n * Rewrites old WordPress media URLs in Portable Text content\n * to point to newly imported EmDash media URLs.\n *\n * Handles URL variants (e.g., image.jpg vs image.jpg?w=200) by matching\n * on the base URL path without query parameters.\n */\n\nimport type { APIRoute } from \"astro\";\nimport { sql } from \"kysely\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { wpRewriteUrlsBody } from \"#api/schemas.js\";\nimport { validateIdentifier } from \"#db/validate.js\";\nimport { normalizeMediaValue } from \"#media/normalize.js\";\nimport type { MediaProvider } from \"#media/types.js\";\nimport { markContentMediaUsageCollectionStaleSafely } from \"#media/usage/content-refresh.js\";\nimport type { EmDashHandlers } from \"#types\";\n\nimport {\n\tbuildBaseUrlMap,\n\textractMediaUrl,\n\tfindMatchingUrl,\n\trewritePortableTextUrls,\n\trewriteStringUrls,\n} from \"./rewrite-url-helpers.js\";\nimport type { PortableTextBlock } from \"./rewrite-url-helpers.js\";\n\nexport interface RewriteUrlsResult {\n\t/** Total items updated */\n\tupdated: number;\n\t/** Updates by collection */\n\tbyCollection: Record<string, number>;\n\t/** URLs that were rewritten */\n\turlsRewritten: number;\n\t/** Any errors encountered */\n\terrors: Array<{ collection: string; id: string; error: string }>;\n}\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NO_DB\", \"Database not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"import:execute\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst body = await parseBody(request, wpRewriteUrlsBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst urlEntries = Object.entries(body.urlMap);\n\t\tif (urlEntries.length === 0) {\n\t\t\treturn apiSuccess({\n\t\t\t\tupdated: 0,\n\t\t\t\tbyCollection: {},\n\t\t\t\turlsRewritten: 0,\n\t\t\t\terrors: [],\n\t\t\t});\n\t\t}\n\n\t\tconst getProvider = (id: string) => emdash.getMediaProvider(id);\n\t\tconst result = await rewriteUrls(emdash.db, body.urlMap, getProvider, body.collections);\n\n\t\treturn apiSuccess(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to rewrite URLs\", \"REWRITE_ERROR\");\n\t}\n};\n\nexport async function rewriteUrls(\n\tdb: NonNullable<EmDashHandlers[\"db\"]>,\n\turlMap: Record<string, string>,\n\tgetProvider: (id: string) => MediaProvider | undefined,\n\tcollections?: string[],\n\tmarkUsageCollectionStale: typeof markContentMediaUsageCollectionStaleSafely = markContentMediaUsageCollectionStaleSafely,\n): Promise<RewriteUrlsResult> {\n\tconst { SchemaRegistry } = await import(\"#schema/registry.js\");\n\tconst registry = new SchemaRegistry(db);\n\n\tconst result: RewriteUrlsResult = {\n\t\tupdated: 0,\n\t\tbyCollection: {},\n\t\turlsRewritten: 0,\n\t\terrors: [],\n\t};\n\tconst staleMarkedCollections = new Set<string>();\n\tconst staleMarkFailedCollections = new Set<string>();\n\tconst markCollectionStale = async (collectionSlug: string): Promise<void> => {\n\t\tif (staleMarkedCollections.has(collectionSlug)) return;\n\t\tconst marked = await markUsageCollectionStale(db, collectionSlug, \"CONTENT_USAGE_STALE\");\n\t\tif (marked) {\n\t\t\tstaleMarkedCollections.add(collectionSlug);\n\t\t\tstaleMarkFailedCollections.delete(collectionSlug);\n\t\t} else {\n\t\t\tstaleMarkFailedCollections.add(collectionSlug);\n\t\t}\n\t};\n\n\t// Build base URL map for flexible matching\n\tconst baseMap = buildBaseUrlMap(urlMap);\n\n\t// Get all collections or filter to specified ones\n\tconst allCollections = await registry.listCollections();\n\tconst targetCollections = collections?.length\n\t\t? allCollections.filter((c) => collections.includes(c.slug))\n\t\t: allCollections;\n\n\ttry {\n\t\tfor (const collection of targetCollections) {\n\t\t\t// Get fields that might contain URLs\n\t\t\tconst fields = await registry.listFields(collection.id);\n\t\t\tconst portableTextFields = fields.filter((f) => f.type === \"portableText\");\n\t\t\tconst stringFields = fields.filter((f) => [\"text\", \"string\"].includes(f.type));\n\t\t\t// Image and file fields store URLs directly as TEXT\n\t\t\tconst mediaFields = fields.filter((f) => [\"image\", \"file\"].includes(f.type));\n\n\t\t\tif (portableTextFields.length === 0 && stringFields.length === 0 && mediaFields.length === 0)\n\t\t\t\tcontinue;\n\n\t\t\t// Get table name\n\t\t\tvalidateIdentifier(collection.slug, \"collection slug\");\n\t\t\tconst tableName = `ec_${collection.slug}`;\n\n\t\t\ttry {\n\t\t\t\t// Query all rows\n\t\t\t\tconst rows = await sql<{ id: string; [key: string]: unknown }>`\n\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\tWHERE deleted_at IS NULL\n\t\t\t`.execute(db);\n\n\t\t\t\tfor (const row of rows.rows) {\n\t\t\t\t\tlet rowUpdated = false;\n\t\t\t\t\tconst updates: Record<string, unknown> = {};\n\t\t\t\t\tlet rowUrlsRewritten = 0;\n\n\t\t\t\t\t// Handle Portable Text fields - parse JSON and rewrite URLs in blocks\n\t\t\t\t\tfor (const field of portableTextFields) {\n\t\t\t\t\t\tconst value = row[field.slug];\n\t\t\t\t\t\tif (!value || typeof value !== \"string\") continue;\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- JSON.parse returns unknown; validated by Array.isArray below\n\t\t\t\t\t\t\tconst blocks = JSON.parse(value) as PortableTextBlock[];\n\t\t\t\t\t\t\tif (!Array.isArray(blocks)) continue;\n\n\t\t\t\t\t\t\tconst rewriteResult = rewritePortableTextUrls(blocks, urlMap, baseMap);\n\n\t\t\t\t\t\t\tif (rewriteResult.changed) {\n\t\t\t\t\t\t\t\tupdates[field.slug] = JSON.stringify(blocks);\n\t\t\t\t\t\t\t\trowUpdated = true;\n\t\t\t\t\t\t\t\trowUrlsRewritten += rewriteResult.urlsRewritten;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Not valid JSON, try string replacement as fallback\n\t\t\t\t\t\t\tconst stringResult = rewriteStringUrls(value, urlMap, baseMap);\n\t\t\t\t\t\t\tif (stringResult.changed) {\n\t\t\t\t\t\t\t\tupdates[field.slug] = stringResult.newValue;\n\t\t\t\t\t\t\t\trowUpdated = true;\n\t\t\t\t\t\t\t\trowUrlsRewritten += stringResult.urlsRewritten;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Handle string/text fields - simple string replacement\n\t\t\t\t\tfor (const field of stringFields) {\n\t\t\t\t\t\tconst value = row[field.slug];\n\t\t\t\t\t\tif (!value || typeof value !== \"string\") continue;\n\n\t\t\t\t\t\tconst stringResult = rewriteStringUrls(value, urlMap, baseMap);\n\t\t\t\t\t\tif (stringResult.changed) {\n\t\t\t\t\t\t\tupdates[field.slug] = stringResult.newValue;\n\t\t\t\t\t\t\trowUpdated = true;\n\t\t\t\t\t\t\trowUrlsRewritten += stringResult.urlsRewritten;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Handle image/file fields - normalize to MediaValue objects\n\t\t\t\t\tfor (const field of mediaFields) {\n\t\t\t\t\t\tconst value = row[field.slug];\n\t\t\t\t\t\tif (!value || typeof value !== \"string\") continue;\n\n\t\t\t\t\t\t// Values are stored as JSON MediaValue objects (e.g. featured_image from\n\t\t\t\t\t\t// import normalizes to {\"provider\":\"external\",\"src\":\"<wp url>\"}). Match on the\n\t\t\t\t\t\t// inner `src`, falling back to the raw value for legacy bare-URL rows.\n\t\t\t\t\t\tconst newUrl = findMatchingUrl(extractMediaUrl(value), urlMap, baseMap);\n\t\t\t\t\t\tif (newUrl) {\n\t\t\t\t\t\t\t// Normalize into a proper MediaValue instead of storing a bare URL\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst normalized = await normalizeMediaValue(newUrl, getProvider);\n\t\t\t\t\t\t\t\tupdates[field.slug] = normalized ? JSON.stringify(normalized) : newUrl;\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\tupdates[field.slug] = newUrl;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\trowUpdated = true;\n\t\t\t\t\t\t\trowUrlsRewritten++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (rowUpdated) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Build update query dynamically\n\t\t\t\t\t\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- Kysely dynamic table requires type assertion\n\t\t\t\t\t\t\tlet query = db.updateTable(tableName as any).where(\"id\", \"=\", row.id);\n\n\t\t\t\t\t\t\tfor (const [key, value] of Object.entries(updates)) {\n\t\t\t\t\t\t\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- Kysely dynamic column update requires type assertion\n\t\t\t\t\t\t\t\tquery = query.set({ [key]: value } as any);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tawait query.execute();\n\n\t\t\t\t\t\t\tresult.updated++;\n\t\t\t\t\t\t\tresult.urlsRewritten += rowUrlsRewritten;\n\t\t\t\t\t\t\tresult.byCollection[collection.slug] =\n\t\t\t\t\t\t\t\t(result.byCollection[collection.slug] || 0) + 1;\n\t\t\t\t\t\t\tawait markCollectionStale(collection.slug);\n\t\t\t\t\t\t} catch (updateError) {\n\t\t\t\t\t\t\tresult.errors.push({\n\t\t\t\t\t\t\t\tcollection: collection.slug,\n\t\t\t\t\t\t\t\tid: row.id,\n\t\t\t\t\t\t\t\terror: updateError instanceof Error ? updateError.message : \"Update failed\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (queryError) {\n\t\t\t\tresult.errors.push({\n\t\t\t\t\tcollection: collection.slug,\n\t\t\t\t\tid: \"*\",\n\t\t\t\t\terror: queryError instanceof Error ? queryError.message : \"Query failed for collection\",\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t} finally {\n\t\tfor (const collectionSlug of staleMarkFailedCollections) {\n\t\t\tif (staleMarkedCollections.has(collectionSlug)) continue;\n\t\t\tconst marked = await markUsageCollectionStale(db, collectionSlug, \"CONTENT_USAGE_STALE\");\n\t\t\tif (marked) staleMarkedCollections.add(collectionSlug);\n\t\t}\n\t}\n\n\treturn result;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"rewrite-urls.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/import/wordpress/rewrite-urls.ts"],"sourcesContent":["/**\n * WordPress URL rewrite endpoint\n *\n * POST /_emdash/api/import/wordpress/rewrite-urls\n *\n * Rewrites old WordPress media URLs in Portable Text content\n * to point to newly imported EmDash media URLs.\n *\n * Handles URL variants (e.g., image.jpg vs image.jpg?w=200) by matching\n * on the base URL path without query parameters.\n */\n\nimport type { APIRoute } from \"astro\";\nimport { sql } from \"kysely\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { wpRewriteUrlsBody } from \"#api/schemas.js\";\nimport { validateIdentifier } from \"#db/validate.js\";\nimport { normalizeMediaValue } from \"#media/normalize.js\";\nimport type { MediaProvider } from \"#media/types.js\";\nimport { markContentMediaUsageCollectionStaleSafely } from \"#media/usage/content-refresh.js\";\nimport type { EmDashHandlers } from \"#types\";\n\nimport {\n\tbuildBaseUrlMap,\n\textractMediaUrl,\n\tfindMatchingUrl,\n\trewritePortableTextUrls,\n\trewriteStringUrls,\n} from \"./rewrite-url-helpers.js\";\nimport type { PortableTextBlock } from \"./rewrite-url-helpers.js\";\n\nexport interface RewriteUrlsResult {\n\t/** Total items updated */\n\tupdated: number;\n\t/** Updates by collection */\n\tbyCollection: Record<string, number>;\n\t/** URLs that were rewritten */\n\turlsRewritten: number;\n\t/** Any errors encountered */\n\terrors: Array<{ collection: string; id: string; error: string }>;\n}\n\nexport const prerender = false;\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tif (!emdash?.db) {\n\t\treturn apiError(\"NO_DB\", \"Database not initialized\", 500);\n\t}\n\n\tconst denied = requirePerm(user, \"import:execute\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst body = await parseBody(request, wpRewriteUrlsBody);\n\t\tif (isParseError(body)) return body;\n\n\t\tconst urlEntries = Object.entries(body.urlMap);\n\t\tif (urlEntries.length === 0) {\n\t\t\treturn apiSuccess({\n\t\t\t\tupdated: 0,\n\t\t\t\tbyCollection: {},\n\t\t\t\turlsRewritten: 0,\n\t\t\t\terrors: [],\n\t\t\t});\n\t\t}\n\n\t\tconst getProvider = (id: string) => emdash.getMediaProvider(id);\n\t\tconst result = await rewriteUrls(emdash.db, body.urlMap, getProvider, body.collections);\n\n\t\treturn apiSuccess(result);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to rewrite URLs\", \"REWRITE_ERROR\");\n\t}\n};\n\nexport async function rewriteUrls(\n\tdb: NonNullable<EmDashHandlers[\"db\"]>,\n\turlMap: Record<string, string>,\n\tgetProvider: (id: string) => MediaProvider | undefined,\n\tcollections?: string[],\n\tmarkUsageCollectionStale: typeof markContentMediaUsageCollectionStaleSafely = markContentMediaUsageCollectionStaleSafely,\n): Promise<RewriteUrlsResult> {\n\tconst { SchemaRegistry } = await import(\"#schema/registry.js\");\n\tconst registry = new SchemaRegistry(db);\n\n\tconst result: RewriteUrlsResult = {\n\t\tupdated: 0,\n\t\tbyCollection: {},\n\t\turlsRewritten: 0,\n\t\terrors: [],\n\t};\n\tconst staleMarkedCollections = new Set<string>();\n\tconst staleMarkFailedCollections = new Set<string>();\n\tconst markCollectionStale = async (collectionSlug: string): Promise<void> => {\n\t\tif (staleMarkedCollections.has(collectionSlug)) return;\n\t\tconst marked = await markUsageCollectionStale(db, collectionSlug, \"CONTENT_USAGE_STALE\");\n\t\tif (marked) {\n\t\t\tstaleMarkedCollections.add(collectionSlug);\n\t\t\tstaleMarkFailedCollections.delete(collectionSlug);\n\t\t} else {\n\t\t\tstaleMarkFailedCollections.add(collectionSlug);\n\t\t}\n\t};\n\n\t// Build base URL map for flexible matching\n\tconst baseMap = buildBaseUrlMap(urlMap);\n\n\t// Get all collections or filter to specified ones\n\tconst allCollections = await registry.listCollections();\n\tconst targetCollections = collections?.length\n\t\t? allCollections.filter((c) => collections.includes(c.slug))\n\t\t: allCollections;\n\n\ttry {\n\t\tfor (const collection of targetCollections) {\n\t\t\t// Get fields that might contain URLs\n\t\t\tconst fields = await registry.listFields(collection.id);\n\t\t\tconst portableTextFields = fields.filter((f) => f.type === \"portableText\");\n\t\t\tconst stringFields = fields.filter((f) => [\"text\", \"string\"].includes(f.type));\n\t\t\t// Image and file fields store URLs directly as TEXT\n\t\t\tconst mediaFields = fields.filter((f) => [\"image\", \"file\"].includes(f.type));\n\n\t\t\tif (portableTextFields.length === 0 && stringFields.length === 0 && mediaFields.length === 0)\n\t\t\t\tcontinue;\n\n\t\t\t// Get table name\n\t\t\tvalidateIdentifier(collection.slug, \"collection slug\");\n\t\t\tconst tableName = `ec_${collection.slug}`;\n\n\t\t\ttry {\n\t\t\t\t// Query all rows\n\t\t\t\tconst rows = await sql<{ id: string; [key: string]: unknown }>`\n\t\t\t\tSELECT * FROM ${sql.ref(tableName)}\n\t\t\t\tWHERE deleted_at IS NULL\n\t\t\t`.execute(db);\n\n\t\t\t\tfor (const row of rows.rows) {\n\t\t\t\t\tlet rowUpdated = false;\n\t\t\t\t\tconst updates: Record<string, unknown> = {};\n\t\t\t\t\tlet rowUrlsRewritten = 0;\n\n\t\t\t\t\t// Handle Portable Text fields - parse JSON and rewrite URLs in blocks\n\t\t\t\t\tfor (const field of portableTextFields) {\n\t\t\t\t\t\tconst value = row[field.slug];\n\t\t\t\t\t\tif (!value || typeof value !== \"string\") continue;\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- JSON.parse returns unknown; validated by Array.isArray below\n\t\t\t\t\t\t\tconst blocks = JSON.parse(value) as PortableTextBlock[];\n\t\t\t\t\t\t\tif (!Array.isArray(blocks)) continue;\n\n\t\t\t\t\t\t\tconst rewriteResult = rewritePortableTextUrls(blocks, urlMap, baseMap);\n\n\t\t\t\t\t\t\tif (rewriteResult.changed) {\n\t\t\t\t\t\t\t\tupdates[field.slug] = JSON.stringify(blocks);\n\t\t\t\t\t\t\t\trowUpdated = true;\n\t\t\t\t\t\t\t\trowUrlsRewritten += rewriteResult.urlsRewritten;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Not valid JSON, try string replacement as fallback\n\t\t\t\t\t\t\tconst stringResult = rewriteStringUrls(value, urlMap, baseMap);\n\t\t\t\t\t\t\tif (stringResult.changed) {\n\t\t\t\t\t\t\t\tupdates[field.slug] = stringResult.newValue;\n\t\t\t\t\t\t\t\trowUpdated = true;\n\t\t\t\t\t\t\t\trowUrlsRewritten += stringResult.urlsRewritten;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Handle string/text fields - simple string replacement\n\t\t\t\t\tfor (const field of stringFields) {\n\t\t\t\t\t\tconst value = row[field.slug];\n\t\t\t\t\t\tif (!value || typeof value !== \"string\") continue;\n\n\t\t\t\t\t\tconst stringResult = rewriteStringUrls(value, urlMap, baseMap);\n\t\t\t\t\t\tif (stringResult.changed) {\n\t\t\t\t\t\t\tupdates[field.slug] = stringResult.newValue;\n\t\t\t\t\t\t\trowUpdated = true;\n\t\t\t\t\t\t\trowUrlsRewritten += stringResult.urlsRewritten;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Handle image/file fields - normalize to MediaValue objects\n\t\t\t\t\tfor (const field of mediaFields) {\n\t\t\t\t\t\tconst value = row[field.slug];\n\t\t\t\t\t\tif (!value || typeof value !== \"string\") continue;\n\n\t\t\t\t\t\t// Values are stored as JSON MediaValue objects (e.g. featured_image from\n\t\t\t\t\t\t// import normalizes to {\"provider\":\"external\",\"src\":\"<wp url>\"}). Match on the\n\t\t\t\t\t\t// inner `src`, falling back to the raw value for legacy bare-URL rows.\n\t\t\t\t\t\tconst newUrl = findMatchingUrl(extractMediaUrl(value), urlMap, baseMap);\n\t\t\t\t\t\tif (newUrl) {\n\t\t\t\t\t\t\t// Normalize into a proper MediaValue instead of storing a bare URL\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst normalized = await normalizeMediaValue(newUrl, getProvider);\n\t\t\t\t\t\t\t\tupdates[field.slug] = normalized ? JSON.stringify(normalized) : newUrl;\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\tupdates[field.slug] = newUrl;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\trowUpdated = true;\n\t\t\t\t\t\t\trowUrlsRewritten++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (rowUpdated) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Build update query dynamically\n\t\t\t\t\t\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- Kysely dynamic table requires type assertion\n\t\t\t\t\t\t\tlet query = db.updateTable(tableName as any).where(\"id\", \"=\", row.id);\n\n\t\t\t\t\t\t\tfor (const [key, value] of Object.entries(updates)) {\n\t\t\t\t\t\t\t\t// eslint-disable-next-line typescript/no-unsafe-type-assertion -- Kysely dynamic column update requires type assertion\n\t\t\t\t\t\t\t\tquery = query.set({ [key]: value } as any);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tawait query.execute();\n\n\t\t\t\t\t\t\tresult.updated++;\n\t\t\t\t\t\t\tresult.urlsRewritten += rowUrlsRewritten;\n\t\t\t\t\t\t\tresult.byCollection[collection.slug] =\n\t\t\t\t\t\t\t\t(result.byCollection[collection.slug] || 0) + 1;\n\t\t\t\t\t\t\tawait markCollectionStale(collection.slug);\n\t\t\t\t\t\t} catch (updateError) {\n\t\t\t\t\t\t\tresult.errors.push({\n\t\t\t\t\t\t\t\tcollection: collection.slug,\n\t\t\t\t\t\t\t\tid: row.id,\n\t\t\t\t\t\t\t\terror: updateError instanceof Error ? updateError.message : \"Update failed\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (queryError) {\n\t\t\t\tresult.errors.push({\n\t\t\t\t\tcollection: collection.slug,\n\t\t\t\t\tid: \"*\",\n\t\t\t\t\terror: queryError instanceof Error ? queryError.message : \"Query failed for collection\",\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t} finally {\n\t\tfor (const collectionSlug of staleMarkFailedCollections) {\n\t\t\tif (staleMarkedCollections.has(collectionSlug)) continue;\n\t\t\tconst marked = await markUsageCollectionStale(db, collectionSlug, \"CONTENT_USAGE_STALE\");\n\t\t\tif (marked) staleMarkedCollections.add(collectionSlug);\n\t\t}\n\t}\n\n\treturn result;\n}\n"],"mappings":"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"}
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
import "../../../../../dialect-helpers-
|
|
1
|
+
import "../../../../../dialect-helpers-HxEQGl_1.mjs";
|
|
2
2
|
import "../../../../../after-B1IIdH3Y.mjs";
|
|
3
3
|
import "../../../../../object-cache-Bok5j2ae.mjs";
|
|
4
|
-
import "../../../../../base64-
|
|
5
|
-
import "../../../../../types-
|
|
6
|
-
import "../../../../../media-
|
|
4
|
+
import "../../../../../base64-B-PsqheR.mjs";
|
|
5
|
+
import "../../../../../types-D1iJ3DpO.mjs";
|
|
6
|
+
import "../../../../../media-BjhhENaJ.mjs";
|
|
7
7
|
import "../../../../../options-BlmBHTvX.mjs";
|
|
8
8
|
import "../../../../../request-cache-BSUptuJR.mjs";
|
|
9
|
-
import "../../../../../loader-
|
|
10
|
-
import
|
|
11
|
-
import "../../../../../
|
|
12
|
-
import { n as
|
|
13
|
-
import { n as parseBody, t as isParseError } from "../../../../../parse-
|
|
14
|
-
import "../../../../../
|
|
15
|
-
import
|
|
16
|
-
import "../../../../../
|
|
9
|
+
import "../../../../../loader-Be3ouI5L.mjs";
|
|
10
|
+
import "../../../../../settings-CpA4lQFt.mjs";
|
|
11
|
+
import { n as resolveAndValidateExternalUrl, t as SsrfError } from "../../../../../ssrf-CviKqWmq.mjs";
|
|
12
|
+
import { n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-CEGF6UZb.mjs";
|
|
13
|
+
import { n as parseBody, t as isParseError } from "../../../../../parse-C_-6klII.mjs";
|
|
14
|
+
import "../../../../../media-kIV1IxFf.mjs";
|
|
15
|
+
import "../../../../../redirects-BBq3n2Rj.mjs";
|
|
16
|
+
import { w as wpPluginAnalyzeBody } from "../../../../../relations-5_avdrN_.mjs";
|
|
17
|
+
import "../../../../../status-COfycGIU.mjs";
|
|
17
18
|
import "../../../../../api/schemas/index.mjs";
|
|
18
|
-
import { p as getSource } from "../../../../../import-
|
|
19
|
-
import "../../../../../ssrf-
|
|
20
|
-
import "../../../../../utils-
|
|
21
|
-
import {
|
|
19
|
+
import { p as getSource } from "../../../../../import-Dmkm8S1W.mjs";
|
|
20
|
+
import "../../../../../ssrf-BB__xfNM.mjs";
|
|
21
|
+
import "../../../../../utils-BbUgmeZG.mjs";
|
|
22
|
+
import { r as requirePerm } from "../../../../../authorize-WxsiePzy.mjs";
|
|
22
23
|
import { SchemaRegistry } from "emdash";
|
|
23
24
|
|
|
24
25
|
//#region src/astro/routes/api/import/wordpress-plugin/analyze.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyze.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/import/wordpress-plugin/analyze.ts"],"sourcesContent":["/**\n * WordPress Plugin analyze endpoint\n *\n * POST /_emdash/api/import/wordpress-plugin/analyze\n *\n * Analyzes a WordPress site with EmDash Exporter plugin installed.\n * Returns content counts, schema compatibility, etc.\n */\n\nimport type { APIRoute } from \"astro\";\nimport { SchemaRegistry } from \"emdash\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { wpPluginAnalyzeBody } from \"#api/schemas.js\";\nimport { getSource } from \"#import/index.js\";\nimport { resolveAndValidateExternalUrl, SsrfError } from \"#import/ssrf.js\";\nimport type { ImportAnalysis } from \"#import/types.js\";\nimport type { EmDashHandlers } from \"#types\";\n\nexport const prerender = false;\n\nexport interface WpPluginAnalyzeResponse {\n\tsuccess: boolean;\n\tanalysis?: ImportAnalysis;\n\terror?: { message: string };\n}\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tconst denied = requirePerm(user, \"import:execute\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst body = await parseBody(request, wpPluginAnalyzeBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// SSRF: reject internal/private network targets. Uses DNS resolution\n\t\t// to catch hostnames that resolve to private addresses.\n\t\ttry {\n\t\t\tawait resolveAndValidateExternalUrl(body.url);\n\t\t} catch (e) {\n\t\t\tconst msg = e instanceof SsrfError ? e.message : \"Invalid URL\";\n\t\t\treturn apiError(\"SSRF_BLOCKED\", msg, 400);\n\t\t}\n\n\t\t// Get the WordPress plugin source\n\t\tconst source = getSource(\"wordpress-plugin\");\n\t\tif (!source) {\n\t\t\treturn apiError(\"NOT_CONFIGURED\", \"WordPress plugin source not available\", 500);\n\t\t}\n\n\t\t// Build context with existing collections info\n\t\tconst existingCollections = await fetchExistingCollections(emdash?.db);\n\n\t\t// Analyze the site\n\t\tconst analysis = await source.analyze(\n\t\t\t{ type: \"url\", url: body.url, token: body.token },\n\t\t\t{\n\t\t\t\tdb: emdash?.db,\n\t\t\t\tgetExistingCollections: async () => existingCollections,\n\t\t\t},\n\t\t);\n\n\t\treturn apiSuccess({\n\t\t\tsuccess: true,\n\t\t\tanalysis,\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to analyze WordPress site\", \"WP_PLUGIN_ANALYZE_ERROR\");\n\t}\n};\n\n/** Existing collection info from schema registry */\ninterface ExistingCollection {\n\tslug: string;\n\tfields: Map<string, { type: string }>;\n}\n\n/** Fetch collections and their fields from schema registry */\nasync function fetchExistingCollections(\n\tdb: EmDashHandlers[\"db\"] | undefined,\n): Promise<Map<string, ExistingCollection>> {\n\tconst result = new Map<string, ExistingCollection>();\n\n\tif (!db) return result;\n\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst collections = await registry.listCollections();\n\n\t\tfor (const collection of collections) {\n\t\t\tconst fields = await registry.listFields(collection.id);\n\t\t\tconst fieldMap = new Map<string, { type: string }>();\n\n\t\t\tfor (const field of fields) {\n\t\t\t\tfieldMap.set(field.slug, { type: field.type });\n\t\t\t}\n\n\t\t\tresult.set(collection.slug, {\n\t\t\t\tslug: collection.slug,\n\t\t\t\tfields: fieldMap,\n\t\t\t});\n\t\t}\n\t} catch (error) {\n\t\tconsole.warn(\"Could not fetch schema registry:\", error);\n\t}\n\n\treturn result;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"analyze.mjs","names":[],"sources":["../../../../../../src/astro/routes/api/import/wordpress-plugin/analyze.ts"],"sourcesContent":["/**\n * WordPress Plugin analyze endpoint\n *\n * POST /_emdash/api/import/wordpress-plugin/analyze\n *\n * Analyzes a WordPress site with EmDash Exporter plugin installed.\n * Returns content counts, schema compatibility, etc.\n */\n\nimport type { APIRoute } from \"astro\";\nimport { SchemaRegistry } from \"emdash\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\nimport { isParseError, parseBody } from \"#api/parse.js\";\nimport { wpPluginAnalyzeBody } from \"#api/schemas.js\";\nimport { getSource } from \"#import/index.js\";\nimport { resolveAndValidateExternalUrl, SsrfError } from \"#import/ssrf.js\";\nimport type { ImportAnalysis } from \"#import/types.js\";\nimport type { EmDashHandlers } from \"#types\";\n\nexport const prerender = false;\n\nexport interface WpPluginAnalyzeResponse {\n\tsuccess: boolean;\n\tanalysis?: ImportAnalysis;\n\terror?: { message: string };\n}\n\nexport const POST: APIRoute = async ({ request, locals }) => {\n\tconst { emdash, user } = locals;\n\n\tconst denied = requirePerm(user, \"import:execute\");\n\tif (denied) return denied;\n\n\ttry {\n\t\tconst body = await parseBody(request, wpPluginAnalyzeBody);\n\t\tif (isParseError(body)) return body;\n\n\t\t// SSRF: reject internal/private network targets. Uses DNS resolution\n\t\t// to catch hostnames that resolve to private addresses.\n\t\ttry {\n\t\t\tawait resolveAndValidateExternalUrl(body.url);\n\t\t} catch (e) {\n\t\t\tconst msg = e instanceof SsrfError ? e.message : \"Invalid URL\";\n\t\t\treturn apiError(\"SSRF_BLOCKED\", msg, 400);\n\t\t}\n\n\t\t// Get the WordPress plugin source\n\t\tconst source = getSource(\"wordpress-plugin\");\n\t\tif (!source) {\n\t\t\treturn apiError(\"NOT_CONFIGURED\", \"WordPress plugin source not available\", 500);\n\t\t}\n\n\t\t// Build context with existing collections info\n\t\tconst existingCollections = await fetchExistingCollections(emdash?.db);\n\n\t\t// Analyze the site\n\t\tconst analysis = await source.analyze(\n\t\t\t{ type: \"url\", url: body.url, token: body.token },\n\t\t\t{\n\t\t\t\tdb: emdash?.db,\n\t\t\t\tgetExistingCollections: async () => existingCollections,\n\t\t\t},\n\t\t);\n\n\t\treturn apiSuccess({\n\t\t\tsuccess: true,\n\t\t\tanalysis,\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to analyze WordPress site\", \"WP_PLUGIN_ANALYZE_ERROR\");\n\t}\n};\n\n/** Existing collection info from schema registry */\ninterface ExistingCollection {\n\tslug: string;\n\tfields: Map<string, { type: string }>;\n}\n\n/** Fetch collections and their fields from schema registry */\nasync function fetchExistingCollections(\n\tdb: EmDashHandlers[\"db\"] | undefined,\n): Promise<Map<string, ExistingCollection>> {\n\tconst result = new Map<string, ExistingCollection>();\n\n\tif (!db) return result;\n\n\ttry {\n\t\tconst registry = new SchemaRegistry(db);\n\t\tconst collections = await registry.listCollections();\n\n\t\tfor (const collection of collections) {\n\t\t\tconst fields = await registry.listFields(collection.id);\n\t\t\tconst fieldMap = new Map<string, { type: string }>();\n\n\t\t\tfor (const field of fields) {\n\t\t\t\tfieldMap.set(field.slug, { type: field.type });\n\t\t\t}\n\n\t\t\tresult.set(collection.slug, {\n\t\t\t\tslug: collection.slug,\n\t\t\t\tfields: fieldMap,\n\t\t\t});\n\t\t}\n\t} catch (error) {\n\t\tconsole.warn(\"Could not fetch schema registry:\", error);\n\t}\n\n\treturn result;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAqBA,MAAa,YAAY;AAQzB,MAAa,OAAiB,OAAO,EAAE,SAAS,aAAa;CAC5D,MAAM,EAAE,QAAQ,SAAS;CAEzB,MAAM,SAAS,YAAY,MAAM,iBAAiB;AAClD,KAAI,OAAQ,QAAO;AAEnB,KAAI;EACH,MAAM,OAAO,MAAM,UAAU,SAAS,oBAAoB;AAC1D,MAAI,aAAa,KAAK,CAAE,QAAO;AAI/B,MAAI;AACH,SAAM,8BAA8B,KAAK,IAAI;WACrC,GAAG;AAEX,UAAO,SAAS,gBADJ,aAAa,YAAY,EAAE,UAAU,eACZ,IAAI;;EAI1C,MAAM,SAAS,UAAU,mBAAmB;AAC5C,MAAI,CAAC,OACJ,QAAO,SAAS,kBAAkB,yCAAyC,IAAI;EAIhF,MAAM,sBAAsB,MAAM,yBAAyB,QAAQ,GAAG;AAWtE,SAAO,WAAW;GACjB,SAAS;GACT,UAVgB,MAAM,OAAO,QAC7B;IAAE,MAAM;IAAO,KAAK,KAAK;IAAK,OAAO,KAAK;IAAO,EACjD;IACC,IAAI,QAAQ;IACZ,wBAAwB,YAAY;IACpC,CACD;GAKA,CAAC;UACM,OAAO;AACf,SAAO,YAAY,OAAO,oCAAoC,0BAA0B;;;;AAW1F,eAAe,yBACd,IAC2C;CAC3C,MAAM,yBAAS,IAAI,KAAiC;AAEpD,KAAI,CAAC,GAAI,QAAO;AAEhB,KAAI;EACH,MAAM,WAAW,IAAI,eAAe,GAAG;EACvC,MAAM,cAAc,MAAM,SAAS,iBAAiB;AAEpD,OAAK,MAAM,cAAc,aAAa;GACrC,MAAM,SAAS,MAAM,SAAS,WAAW,WAAW,GAAG;GACvD,MAAM,2BAAW,IAAI,KAA+B;AAEpD,QAAK,MAAM,SAAS,OACnB,UAAS,IAAI,MAAM,MAAM,EAAE,MAAM,MAAM,MAAM,CAAC;AAG/C,UAAO,IAAI,WAAW,MAAM;IAC3B,MAAM,WAAW;IACjB,QAAQ;IACR,CAAC;;UAEK,OAAO;AACf,UAAQ,KAAK,oCAAoC,MAAM;;AAGxD,QAAO"}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import "../../../../../options-
|
|
2
|
-
import "../../../../../types-
|
|
3
|
-
import "../../../../../types-
|
|
4
|
-
import "../../../../../relations-
|
|
5
|
-
import "../../../../../index-
|
|
6
|
-
import "../../../../../runner-
|
|
7
|
-
import { t as fetchPluginTaxonomies } from "../../../../../index-
|
|
8
|
-
import "../../../../../
|
|
9
|
-
import
|
|
10
|
-
import "../../../../../
|
|
11
|
-
import "../../../../../validate-9jLuE301.mjs";
|
|
1
|
+
import "../../../../../options-BqMkWfYa.mjs";
|
|
2
|
+
import "../../../../../types-DPKhI5ib.mjs";
|
|
3
|
+
import "../../../../../types-BvB7gDOD.mjs";
|
|
4
|
+
import "../../../../../relations-Bh8jlFsU.mjs";
|
|
5
|
+
import "../../../../../index-wYnC6u4o.mjs";
|
|
6
|
+
import "../../../../../runner-Dd8m8k9F.mjs";
|
|
7
|
+
import { t as fetchPluginTaxonomies } from "../../../../../index-BEui-cRd.mjs";
|
|
8
|
+
import { f as NormalizedItem, s as ImportConfig, u as ImportResult } from "../../../../../types-C7U0HlEr.mjs";
|
|
9
|
+
import "../../../../../hreflang-CIxH_LKz.mjs";
|
|
10
|
+
import "../../../../../validate-DULfgpJP.mjs";
|
|
12
11
|
import { EmDashHandlers, EmDashManifest } from "../../../../types.mjs";
|
|
13
|
-
import { t as TaxonomyImportPlan } from "../../../../../wxr-taxonomies-
|
|
12
|
+
import { t as TaxonomyImportPlan } from "../../../../../wxr-taxonomies-B4tMuN5T.mjs";
|
|
14
13
|
import { APIRoute } from "astro";
|
|
15
14
|
|
|
16
15
|
//#region src/astro/routes/api/import/wordpress-plugin/execute.d.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.d.mts","names":[],"sources":["../../../../../../src/astro/routes/api/import/wordpress-plugin/execute.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"execute.d.mts","names":[],"sources":["../../../../../../src/astro/routes/api/import/wordpress-plugin/execute.ts"],"mappings":";;;;;;;;;;;;;;;cAoDa,SAAA;AAAA,UAEI,oBAAA,SAA6B,YAAA;;EAE7C,cAAA,GAAiB,MAAA;EAJI;EAMrB,WAAA;EACA,eAAA;EACA,UAAA;EACA,SAAA;AAAA;AAAA,UAGgB,sBAAA;EAChB,OAAA;EACA,MAAA,GAAS,YAAA;EACT,KAAA;IAAU,OAAA;EAAA;AAAA;AAAA,cAoEE,IAAA,EAAM,QAAA;;;;AAvEnB;;;iBAidgB,iBAAA,CAAkB,KAAA,WAAgB,SAAA;;;;;;;;AA1YlD;iBA4dsB,wBAAA,CACrB,EAAA,EAAI,cAAA,QACJ,UAAA,EAAY,OAAA,CAAQ,UAAA,QAAkB,qBAAA,IACtC,MAAA,EAAQ,oBAAA,GACN,OAAA;;iBA+JmB,aAAA,CACrB,KAAA,EAAO,aAAA,CAAc,cAAA,IAAkB,QAAA,CAAS,cAAA,GAChD,MAAA,EAAQ,oBAAA,EACR,MAAA,EAAQ,cAAA,EACR,QAAA,EAAU,cAAA,EACV,YAAA,EAAc,kBAAA,cACd,qBAAA,GAAwB,GAAA,mBACtB,OAAA;EACF,MAAA,EAAQ,YAAA;EACR,YAAA,EAAc,GAAA;EACd,gBAAA,EAAkB,GAAA;AAAA"}
|
|
@@ -1,34 +1,35 @@
|
|
|
1
|
-
import "../../../../../dialect-helpers-
|
|
1
|
+
import "../../../../../dialect-helpers-HxEQGl_1.mjs";
|
|
2
2
|
import "../../../../../after-B1IIdH3Y.mjs";
|
|
3
3
|
import "../../../../../object-cache-Bok5j2ae.mjs";
|
|
4
4
|
import { n as slugify } from "../../../../../slugify-C_tqlU4G.mjs";
|
|
5
|
-
import "../../../../../base64-
|
|
6
|
-
import "../../../../../types-
|
|
7
|
-
import "../../../../../media-
|
|
8
|
-
import "../../../../../taxonomy-
|
|
5
|
+
import "../../../../../base64-B-PsqheR.mjs";
|
|
6
|
+
import "../../../../../types-D1iJ3DpO.mjs";
|
|
7
|
+
import "../../../../../media-BjhhENaJ.mjs";
|
|
8
|
+
import "../../../../../taxonomy-DfVooU4W.mjs";
|
|
9
9
|
import "../../../../../options-BlmBHTvX.mjs";
|
|
10
10
|
import "../../../../../request-cache-BSUptuJR.mjs";
|
|
11
11
|
import "../../../../../byline-registry-BCuOp4UF.mjs";
|
|
12
|
-
import "../../../../../field-defs-cache-
|
|
13
|
-
import { t as BylineRepository } from "../../../../../byline-
|
|
12
|
+
import "../../../../../field-defs-cache-DvmlgP-D.mjs";
|
|
13
|
+
import { t as BylineRepository } from "../../../../../byline-XEjchwzZ.mjs";
|
|
14
14
|
import "../../../../../enrich-CFJJgxs_.mjs";
|
|
15
15
|
import "../../../../../resolve-Cd9dzclN.mjs";
|
|
16
|
-
import "../../../../../loader-
|
|
17
|
-
import "../../../../../taxonomies-
|
|
18
|
-
import
|
|
19
|
-
import "../../../../../
|
|
20
|
-
import { t as
|
|
21
|
-
import { n as
|
|
22
|
-
import { n as parseBody, t as isParseError } from "../../../../../parse-
|
|
23
|
-
import "../../../../../
|
|
24
|
-
import
|
|
25
|
-
import "../../../../../
|
|
16
|
+
import "../../../../../loader-Be3ouI5L.mjs";
|
|
17
|
+
import "../../../../../taxonomies-DjSKBZpq.mjs";
|
|
18
|
+
import "../../../../../settings-CpA4lQFt.mjs";
|
|
19
|
+
import { t as handleTaxonomyCreate } from "../../../../../taxonomies-Ce49uIzY.mjs";
|
|
20
|
+
import { n as resolveAndValidateExternalUrl, t as SsrfError } from "../../../../../ssrf-CviKqWmq.mjs";
|
|
21
|
+
import { n as apiSuccess, r as handleError, t as apiError } from "../../../../../error-CEGF6UZb.mjs";
|
|
22
|
+
import { n as parseBody, t as isParseError } from "../../../../../parse-C_-6klII.mjs";
|
|
23
|
+
import "../../../../../media-kIV1IxFf.mjs";
|
|
24
|
+
import "../../../../../redirects-BBq3n2Rj.mjs";
|
|
25
|
+
import { T as wpPluginExecuteBody } from "../../../../../relations-5_avdrN_.mjs";
|
|
26
|
+
import "../../../../../status-COfycGIU.mjs";
|
|
26
27
|
import "../../../../../api/schemas/index.mjs";
|
|
27
|
-
import { _ as importSiteSettings, a as fetchPluginOptions, i as fetchPluginMenus, n as fetchPluginCommentsPage, o as fetchPluginTaxonomies, p as getSource, r as fetchPluginContentPage, t as fetchPluginComments, v as parseSiteSettingsFromPlugin, x as importMenusFromPlugin, y as importCommentsFromPlugin } from "../../../../../import-
|
|
28
|
-
import "../../../../../ssrf-
|
|
29
|
-
import { _ as sanitizeFieldSlug, g as resolveImportByline } from "../../../../../utils-
|
|
30
|
-
import {
|
|
31
|
-
import { a as preImportWxrTaxonomies, r as loadTaxonomyPlanFromDb, t as attachPostTaxonomies } from "../../../../../wxr-taxonomies-
|
|
28
|
+
import { _ as importSiteSettings, a as fetchPluginOptions, i as fetchPluginMenus, n as fetchPluginCommentsPage, o as fetchPluginTaxonomies, p as getSource, r as fetchPluginContentPage, t as fetchPluginComments, v as parseSiteSettingsFromPlugin, x as importMenusFromPlugin, y as importCommentsFromPlugin } from "../../../../../import-Dmkm8S1W.mjs";
|
|
29
|
+
import "../../../../../ssrf-BB__xfNM.mjs";
|
|
30
|
+
import { _ as sanitizeFieldSlug, g as resolveImportByline } from "../../../../../utils-BbUgmeZG.mjs";
|
|
31
|
+
import { r as requirePerm } from "../../../../../authorize-WxsiePzy.mjs";
|
|
32
|
+
import { a as preImportWxrTaxonomies, r as loadTaxonomyPlanFromDb, t as attachPostTaxonomies } from "../../../../../wxr-taxonomies-Cs1N6O8z.mjs";
|
|
32
33
|
import { importMediaWithProgress } from "../wordpress/media.mjs";
|
|
33
34
|
import { ContentRepository, SchemaRegistry } from "emdash";
|
|
34
35
|
|