emdash 0.0.0-b → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -43
- package/dist/adapters-BLMa4JGD.d.mts +106 -0
- package/dist/adapters-BLMa4JGD.d.mts.map +1 -0
- package/dist/apply-Bjfq_b4-.mjs +1293 -0
- package/dist/apply-Bjfq_b4-.mjs.map +1 -0
- package/dist/astro/index.d.mts +51 -0
- package/dist/astro/index.d.mts.map +1 -0
- package/dist/astro/index.mjs +1336 -0
- package/dist/astro/index.mjs.map +1 -0
- package/dist/astro/middleware/auth.d.mts +31 -0
- package/dist/astro/middleware/auth.d.mts.map +1 -0
- package/dist/astro/middleware/auth.mjs +654 -0
- package/dist/astro/middleware/auth.mjs.map +1 -0
- package/dist/astro/middleware/redirect.d.mts +22 -0
- package/dist/astro/middleware/redirect.d.mts.map +1 -0
- package/dist/astro/middleware/redirect.mjs +63 -0
- package/dist/astro/middleware/redirect.mjs.map +1 -0
- package/dist/astro/middleware/request-context.d.mts +18 -0
- package/dist/astro/middleware/request-context.d.mts.map +1 -0
- package/dist/astro/middleware/request-context.mjs +1310 -0
- package/dist/astro/middleware/request-context.mjs.map +1 -0
- package/dist/astro/middleware/setup.d.mts +20 -0
- package/dist/astro/middleware/setup.d.mts.map +1 -0
- package/dist/astro/middleware/setup.mjs +47 -0
- package/dist/astro/middleware/setup.mjs.map +1 -0
- package/dist/astro/middleware.d.mts +13 -0
- package/dist/astro/middleware.d.mts.map +1 -0
- package/dist/astro/middleware.mjs +1613 -0
- package/dist/astro/middleware.mjs.map +1 -0
- package/dist/astro/types.d.mts +250 -0
- package/dist/astro/types.d.mts.map +1 -0
- package/dist/astro/types.mjs +1 -0
- package/dist/base64-MBPo9ozB.mjs +59 -0
- package/dist/base64-MBPo9ozB.mjs.map +1 -0
- package/dist/byline-CL847F26.mjs +213 -0
- package/dist/byline-CL847F26.mjs.map +1 -0
- package/dist/bylines-C2a-2TGt.mjs +136 -0
- package/dist/bylines-C2a-2TGt.mjs.map +1 -0
- package/dist/chunk-ClPoSABd.mjs +21 -0
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.mjs +3909 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/client/cf-access.d.mts +60 -0
- package/dist/client/cf-access.d.mts.map +1 -0
- package/dist/client/cf-access.mjs +179 -0
- package/dist/client/cf-access.mjs.map +1 -0
- package/dist/client/index.d.mts +398 -0
- package/dist/client/index.d.mts.map +1 -0
- package/dist/client/index.mjs +346 -0
- package/dist/client/index.mjs.map +1 -0
- package/dist/config-CKE8p9xM.mjs +55 -0
- package/dist/config-CKE8p9xM.mjs.map +1 -0
- package/dist/connection-B4zVnQIa.mjs +40 -0
- package/dist/connection-B4zVnQIa.mjs.map +1 -0
- package/dist/content-D6C2WsZC.mjs +824 -0
- package/dist/content-D6C2WsZC.mjs.map +1 -0
- package/dist/db/index.d.mts +4 -0
- package/dist/db/index.mjs +62 -0
- package/dist/db/index.mjs.map +1 -0
- package/dist/db/libsql.d.mts +11 -0
- package/dist/db/libsql.d.mts.map +1 -0
- package/dist/db/libsql.mjs +17 -0
- package/dist/db/libsql.mjs.map +1 -0
- package/dist/db/postgres.d.mts +11 -0
- package/dist/db/postgres.d.mts.map +1 -0
- package/dist/db/postgres.mjs +30 -0
- package/dist/db/postgres.mjs.map +1 -0
- package/dist/db/sqlite.d.mts +11 -0
- package/dist/db/sqlite.d.mts.map +1 -0
- package/dist/db/sqlite.mjs +16 -0
- package/dist/db/sqlite.mjs.map +1 -0
- package/dist/default-Cyi4aAxu.mjs +81 -0
- package/dist/default-Cyi4aAxu.mjs.map +1 -0
- package/dist/dialect-helpers-B9uSp2GJ.mjs +90 -0
- package/dist/dialect-helpers-B9uSp2GJ.mjs.map +1 -0
- package/dist/error-Cxz0tQeO.mjs +27 -0
- package/dist/error-Cxz0tQeO.mjs.map +1 -0
- package/dist/index-C1xF3OGh.d.mts +4527 -0
- package/dist/index-C1xF3OGh.d.mts.map +1 -0
- package/dist/index.d.mts +16 -0
- package/dist/index.mjs +30 -0
- package/dist/load-yOOlckBj.mjs +28 -0
- package/dist/load-yOOlckBj.mjs.map +1 -0
- package/dist/loader-fz8Q_3EO.mjs +447 -0
- package/dist/loader-fz8Q_3EO.mjs.map +1 -0
- package/dist/manifest-schema-Dcl0R6nM.mjs +184 -0
- package/dist/manifest-schema-Dcl0R6nM.mjs.map +1 -0
- package/dist/media/index.d.mts +26 -0
- package/dist/media/index.d.mts.map +1 -0
- package/dist/media/index.mjs +55 -0
- package/dist/media/index.mjs.map +1 -0
- package/dist/media/local-runtime.d.mts +39 -0
- package/dist/media/local-runtime.d.mts.map +1 -0
- package/dist/media/local-runtime.mjs +133 -0
- package/dist/media/local-runtime.mjs.map +1 -0
- package/dist/media-DqHVh136.mjs +200 -0
- package/dist/media-DqHVh136.mjs.map +1 -0
- package/dist/mode-C2EzN1uE.mjs +23 -0
- package/dist/mode-C2EzN1uE.mjs.map +1 -0
- package/dist/page/index.d.mts +140 -0
- package/dist/page/index.d.mts.map +1 -0
- package/dist/page/index.mjs +416 -0
- package/dist/page/index.mjs.map +1 -0
- package/dist/placeholder-CmGAmqeO.d.mts +276 -0
- package/dist/placeholder-CmGAmqeO.d.mts.map +1 -0
- package/dist/placeholder-SmpOx-_v.mjs +243 -0
- package/dist/placeholder-SmpOx-_v.mjs.map +1 -0
- package/dist/plugin-utils.d.mts +58 -0
- package/dist/plugin-utils.d.mts.map +1 -0
- package/dist/plugin-utils.mjs +78 -0
- package/dist/plugin-utils.mjs.map +1 -0
- package/dist/plugins/adapt-sandbox-entry.d.mts +22 -0
- package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -0
- package/dist/plugins/adapt-sandbox-entry.mjs +113 -0
- package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -0
- package/dist/query-CS_iSj34.mjs +460 -0
- package/dist/query-CS_iSj34.mjs.map +1 -0
- package/dist/redirect-DIfIni3r.mjs +329 -0
- package/dist/redirect-DIfIni3r.mjs.map +1 -0
- package/dist/registry-D_w5HW4G.mjs +863 -0
- package/dist/registry-D_w5HW4G.mjs.map +1 -0
- package/dist/request-context.d.mts +49 -0
- package/dist/request-context.d.mts.map +1 -0
- package/dist/request-context.mjs +43 -0
- package/dist/request-context.mjs.map +1 -0
- package/dist/runner-C0hCbYnD.mjs +1412 -0
- package/dist/runner-C0hCbYnD.mjs.map +1 -0
- package/dist/runner-EAtf0ZIe.d.mts +27 -0
- package/dist/runner-EAtf0ZIe.d.mts.map +1 -0
- package/dist/runtime.d.mts +26 -0
- package/dist/runtime.d.mts.map +1 -0
- package/dist/runtime.mjs +42 -0
- package/dist/runtime.mjs.map +1 -0
- package/dist/search-DG603UrT.mjs +9211 -0
- package/dist/search-DG603UrT.mjs.map +1 -0
- package/dist/seed/index.d.mts +3 -0
- package/dist/seed/index.mjs +15 -0
- package/dist/seo/index.d.mts +70 -0
- package/dist/seo/index.d.mts.map +1 -0
- package/dist/seo/index.mjs +70 -0
- package/dist/seo/index.mjs.map +1 -0
- package/dist/storage/local.d.mts +39 -0
- package/dist/storage/local.d.mts.map +1 -0
- package/dist/storage/local.mjs +166 -0
- package/dist/storage/local.mjs.map +1 -0
- package/dist/storage/s3.d.mts +32 -0
- package/dist/storage/s3.d.mts.map +1 -0
- package/dist/storage/s3.mjs +175 -0
- package/dist/storage/s3.mjs.map +1 -0
- package/dist/tokens-DpgrkrXK.mjs +171 -0
- package/dist/tokens-DpgrkrXK.mjs.map +1 -0
- package/dist/transport-BFGblqwG.d.mts +42 -0
- package/dist/transport-BFGblqwG.d.mts.map +1 -0
- package/dist/transport-yxiQsi8I.mjs +418 -0
- package/dist/transport-yxiQsi8I.mjs.map +1 -0
- package/dist/types-BRuPJGdV.d.mts +102 -0
- package/dist/types-BRuPJGdV.d.mts.map +1 -0
- package/dist/types-C4-fAxN3.d.mts +182 -0
- package/dist/types-C4-fAxN3.d.mts.map +1 -0
- package/dist/types-CMMN0pNg.mjs +31 -0
- package/dist/types-CMMN0pNg.mjs.map +1 -0
- package/dist/types-CUBbjgmP.mjs +16 -0
- package/dist/types-CUBbjgmP.mjs.map +1 -0
- package/dist/types-DRjfYOEv.d.mts +426 -0
- package/dist/types-DRjfYOEv.d.mts.map +1 -0
- package/dist/types-DY5zk5HN.mjs +73 -0
- package/dist/types-DY5zk5HN.mjs.map +1 -0
- package/dist/types-DaNLHo_T.d.mts +184 -0
- package/dist/types-DaNLHo_T.d.mts.map +1 -0
- package/dist/types-DvhsUmSJ.d.mts +1111 -0
- package/dist/types-DvhsUmSJ.d.mts.map +1 -0
- package/dist/validate-CpBtVMsD.d.mts +378 -0
- package/dist/validate-CpBtVMsD.d.mts.map +1 -0
- package/dist/validate-CqRJb_xU.mjs +97 -0
- package/dist/validate-CqRJb_xU.mjs.map +1 -0
- package/dist/validate-O7PWmlnq.mjs +328 -0
- package/dist/validate-O7PWmlnq.mjs.map +1 -0
- package/locals.d.ts +46 -0
- package/package.json +233 -19
- package/src/api/authorize.ts +63 -0
- package/src/api/csrf.ts +48 -0
- package/src/api/error.ts +99 -0
- package/src/api/errors.ts +445 -0
- package/src/api/escape.ts +9 -0
- package/src/api/handlers/api-tokens.ts +240 -0
- package/src/api/handlers/comments.ts +314 -0
- package/src/api/handlers/content.ts +1315 -0
- package/src/api/handlers/dashboard.ts +205 -0
- package/src/api/handlers/device-flow.ts +684 -0
- package/src/api/handlers/index.ts +163 -0
- package/src/api/handlers/manifest.ts +158 -0
- package/src/api/handlers/marketplace.ts +930 -0
- package/src/api/handlers/media.ts +207 -0
- package/src/api/handlers/menus.ts +493 -0
- package/src/api/handlers/oauth-authorization.ts +429 -0
- package/src/api/handlers/oauth-clients.ts +349 -0
- package/src/api/handlers/oauth-user-lookup.ts +39 -0
- package/src/api/handlers/plugins.ts +254 -0
- package/src/api/handlers/redirects.ts +360 -0
- package/src/api/handlers/revision.ts +145 -0
- package/src/api/handlers/schema.ts +534 -0
- package/src/api/handlers/sections.ts +289 -0
- package/src/api/handlers/seo.ts +115 -0
- package/src/api/handlers/settings.ts +49 -0
- package/src/api/handlers/snapshot.ts +350 -0
- package/src/api/handlers/taxonomies.ts +523 -0
- package/src/api/index.ts +6 -0
- package/src/api/openapi/document.ts +2368 -0
- package/src/api/openapi/index.ts +1 -0
- package/src/api/parse.ts +139 -0
- package/src/api/redirect.ts +14 -0
- package/src/api/rev.ts +67 -0
- package/src/api/schemas/auth.ts +112 -0
- package/src/api/schemas/bylines.ts +85 -0
- package/src/api/schemas/comments.ts +117 -0
- package/src/api/schemas/common.ts +89 -0
- package/src/api/schemas/content.ts +191 -0
- package/src/api/schemas/import.ts +52 -0
- package/src/api/schemas/index.ts +17 -0
- package/src/api/schemas/media.ts +116 -0
- package/src/api/schemas/menus.ts +111 -0
- package/src/api/schemas/redirects.ts +155 -0
- package/src/api/schemas/schema.ts +203 -0
- package/src/api/schemas/search.ts +63 -0
- package/src/api/schemas/sections.ts +67 -0
- package/src/api/schemas/settings.ts +63 -0
- package/src/api/schemas/setup.ts +37 -0
- package/src/api/schemas/taxonomies.ts +113 -0
- package/src/api/schemas/users.ts +96 -0
- package/src/api/schemas/widgets.ts +80 -0
- package/src/api/site-url.ts +25 -0
- package/src/api/types.ts +82 -0
- package/src/astro/index.ts +27 -0
- package/src/astro/integration/index.ts +303 -0
- package/src/astro/integration/routes.ts +834 -0
- package/src/astro/integration/runtime.ts +338 -0
- package/src/astro/integration/virtual-modules.ts +469 -0
- package/src/astro/integration/vite-config.ts +335 -0
- package/src/astro/middleware/auth.ts +743 -0
- package/src/astro/middleware/redirect.ts +89 -0
- package/src/astro/middleware/request-context.ts +129 -0
- package/src/astro/middleware/setup.ts +89 -0
- package/src/astro/middleware.ts +398 -0
- package/src/astro/routes/PluginRegistry.tsx +15 -0
- package/src/astro/routes/admin.astro +81 -0
- package/src/astro/routes/api/admin/allowed-domains/[domain].ts +112 -0
- package/src/astro/routes/api/admin/allowed-domains/index.ts +108 -0
- package/src/astro/routes/api/admin/api-tokens/[id].ts +40 -0
- package/src/astro/routes/api/admin/api-tokens/index.ts +68 -0
- package/src/astro/routes/api/admin/bylines/[id]/index.ts +87 -0
- package/src/astro/routes/api/admin/bylines/index.ts +72 -0
- package/src/astro/routes/api/admin/comments/[id]/status.ts +116 -0
- package/src/astro/routes/api/admin/comments/[id].ts +64 -0
- package/src/astro/routes/api/admin/comments/bulk.ts +42 -0
- package/src/astro/routes/api/admin/comments/counts.ts +30 -0
- package/src/astro/routes/api/admin/comments/index.ts +46 -0
- package/src/astro/routes/api/admin/hooks/exclusive/[hookName].ts +91 -0
- package/src/astro/routes/api/admin/hooks/exclusive/index.ts +51 -0
- package/src/astro/routes/api/admin/oauth-clients/[id].ts +110 -0
- package/src/astro/routes/api/admin/oauth-clients/index.ts +71 -0
- package/src/astro/routes/api/admin/plugins/[id]/disable.ts +39 -0
- package/src/astro/routes/api/admin/plugins/[id]/enable.ts +39 -0
- package/src/astro/routes/api/admin/plugins/[id]/index.ts +38 -0
- package/src/astro/routes/api/admin/plugins/[id]/uninstall.ts +48 -0
- package/src/astro/routes/api/admin/plugins/[id]/update.ts +59 -0
- package/src/astro/routes/api/admin/plugins/index.ts +32 -0
- package/src/astro/routes/api/admin/plugins/marketplace/[id]/icon.ts +61 -0
- package/src/astro/routes/api/admin/plugins/marketplace/[id]/index.ts +33 -0
- package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +62 -0
- package/src/astro/routes/api/admin/plugins/marketplace/index.ts +38 -0
- package/src/astro/routes/api/admin/plugins/updates.ts +28 -0
- package/src/astro/routes/api/admin/themes/marketplace/[id]/index.ts +33 -0
- package/src/astro/routes/api/admin/themes/marketplace/[id]/thumbnail.ts +61 -0
- package/src/astro/routes/api/admin/themes/marketplace/index.ts +45 -0
- package/src/astro/routes/api/admin/users/[id]/disable.ts +69 -0
- package/src/astro/routes/api/admin/users/[id]/enable.ts +48 -0
- package/src/astro/routes/api/admin/users/[id]/index.ts +146 -0
- package/src/astro/routes/api/admin/users/[id]/send-recovery.ts +72 -0
- package/src/astro/routes/api/admin/users/index.ts +66 -0
- package/src/astro/routes/api/auth/dev-bypass.ts +139 -0
- package/src/astro/routes/api/auth/invite/accept.ts +52 -0
- package/src/astro/routes/api/auth/invite/complete.ts +84 -0
- package/src/astro/routes/api/auth/invite/index.ts +99 -0
- package/src/astro/routes/api/auth/logout.ts +40 -0
- package/src/astro/routes/api/auth/magic-link/send.ts +89 -0
- package/src/astro/routes/api/auth/magic-link/verify.ts +71 -0
- package/src/astro/routes/api/auth/me.ts +60 -0
- package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +219 -0
- package/src/astro/routes/api/auth/oauth/[provider].ts +119 -0
- package/src/astro/routes/api/auth/passkey/[id].ts +124 -0
- package/src/astro/routes/api/auth/passkey/index.ts +54 -0
- package/src/astro/routes/api/auth/passkey/options.ts +82 -0
- package/src/astro/routes/api/auth/passkey/register/options.ts +86 -0
- package/src/astro/routes/api/auth/passkey/register/verify.ts +115 -0
- package/src/astro/routes/api/auth/passkey/verify.ts +66 -0
- package/src/astro/routes/api/auth/signup/complete.ts +85 -0
- package/src/astro/routes/api/auth/signup/request.ts +77 -0
- package/src/astro/routes/api/auth/signup/verify.ts +53 -0
- package/src/astro/routes/api/comments/[collection]/[contentId]/index.ts +312 -0
- package/src/astro/routes/api/content/[collection]/[id]/compare.ts +28 -0
- package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +54 -0
- package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +61 -0
- package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +33 -0
- package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +107 -0
- package/src/astro/routes/api/content/[collection]/[id]/publish.ts +56 -0
- package/src/astro/routes/api/content/[collection]/[id]/restore.ts +54 -0
- package/src/astro/routes/api/content/[collection]/[id]/revisions.ts +31 -0
- package/src/astro/routes/api/content/[collection]/[id]/schedule.ts +101 -0
- package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +140 -0
- package/src/astro/routes/api/content/[collection]/[id]/translations.ts +30 -0
- package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +56 -0
- package/src/astro/routes/api/content/[collection]/[id].ts +137 -0
- package/src/astro/routes/api/content/[collection]/index.ts +59 -0
- package/src/astro/routes/api/content/[collection]/trash.ts +33 -0
- package/src/astro/routes/api/dashboard.ts +32 -0
- package/src/astro/routes/api/dev/emails.ts +36 -0
- package/src/astro/routes/api/import/probe.ts +47 -0
- package/src/astro/routes/api/import/wordpress/analyze.ts +510 -0
- package/src/astro/routes/api/import/wordpress/execute.ts +283 -0
- package/src/astro/routes/api/import/wordpress/media.ts +338 -0
- package/src/astro/routes/api/import/wordpress/prepare.ts +181 -0
- package/src/astro/routes/api/import/wordpress/rewrite-urls.ts +393 -0
- package/src/astro/routes/api/import/wordpress-plugin/analyze.ts +111 -0
- package/src/astro/routes/api/import/wordpress-plugin/callback.ts +58 -0
- package/src/astro/routes/api/import/wordpress-plugin/execute.ts +347 -0
- package/src/astro/routes/api/manifest.ts +62 -0
- package/src/astro/routes/api/mcp.ts +124 -0
- package/src/astro/routes/api/media/[id]/confirm.ts +93 -0
- package/src/astro/routes/api/media/[id].ts +145 -0
- package/src/astro/routes/api/media/file/[key].ts +79 -0
- package/src/astro/routes/api/media/providers/[providerId]/[itemId].ts +86 -0
- package/src/astro/routes/api/media/providers/[providerId]/index.ts +111 -0
- package/src/astro/routes/api/media/providers/index.ts +30 -0
- package/src/astro/routes/api/media/upload-url.ts +137 -0
- package/src/astro/routes/api/media.ts +190 -0
- package/src/astro/routes/api/menus/[name]/items.ts +87 -0
- package/src/astro/routes/api/menus/[name]/reorder.ts +33 -0
- package/src/astro/routes/api/menus/[name].ts +65 -0
- package/src/astro/routes/api/menus/index.ts +47 -0
- package/src/astro/routes/api/oauth/authorize.ts +412 -0
- package/src/astro/routes/api/oauth/device/authorize.ts +45 -0
- package/src/astro/routes/api/oauth/device/code.ts +51 -0
- package/src/astro/routes/api/oauth/device/token.ts +69 -0
- package/src/astro/routes/api/oauth/token/refresh.ts +38 -0
- package/src/astro/routes/api/oauth/token/revoke.ts +38 -0
- package/src/astro/routes/api/oauth/token.ts +184 -0
- package/src/astro/routes/api/openapi.json.ts +32 -0
- package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +92 -0
- package/src/astro/routes/api/redirects/404s/index.ts +72 -0
- package/src/astro/routes/api/redirects/404s/summary.ts +33 -0
- package/src/astro/routes/api/redirects/[id].ts +84 -0
- package/src/astro/routes/api/redirects/index.ts +52 -0
- package/src/astro/routes/api/revisions/[revisionId]/index.ts +29 -0
- package/src/astro/routes/api/revisions/[revisionId]/restore.ts +58 -0
- package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +76 -0
- package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +52 -0
- package/src/astro/routes/api/schema/collections/[slug]/fields/reorder.ts +32 -0
- package/src/astro/routes/api/schema/collections/[slug]/index.ts +80 -0
- package/src/astro/routes/api/schema/collections/index.ts +47 -0
- package/src/astro/routes/api/schema/index.ts +109 -0
- package/src/astro/routes/api/schema/orphans/[slug].ts +36 -0
- package/src/astro/routes/api/schema/orphans/index.ts +26 -0
- package/src/astro/routes/api/search/enable.ts +64 -0
- package/src/astro/routes/api/search/index.ts +55 -0
- package/src/astro/routes/api/search/rebuild.ts +72 -0
- package/src/astro/routes/api/search/stats.ts +35 -0
- package/src/astro/routes/api/search/suggest.ts +53 -0
- package/src/astro/routes/api/sections/[slug].ts +84 -0
- package/src/astro/routes/api/sections/index.ts +52 -0
- package/src/astro/routes/api/settings/email.ts +150 -0
- package/src/astro/routes/api/settings.ts +67 -0
- package/src/astro/routes/api/setup/admin-verify.ts +100 -0
- package/src/astro/routes/api/setup/admin.ts +94 -0
- package/src/astro/routes/api/setup/dev-bypass.ts +199 -0
- package/src/astro/routes/api/setup/dev-reset.ts +40 -0
- package/src/astro/routes/api/setup/index.ts +126 -0
- package/src/astro/routes/api/setup/status.ts +122 -0
- package/src/astro/routes/api/snapshot.ts +75 -0
- package/src/astro/routes/api/taxonomies/[name]/terms/[slug].ts +95 -0
- package/src/astro/routes/api/taxonomies/[name]/terms/index.ts +69 -0
- package/src/astro/routes/api/taxonomies/index.ts +59 -0
- package/src/astro/routes/api/themes/preview.ts +77 -0
- package/src/astro/routes/api/typegen.ts +114 -0
- package/src/astro/routes/api/well-known/auth.ts +68 -0
- package/src/astro/routes/api/well-known/oauth-authorization-server.ts +44 -0
- package/src/astro/routes/api/well-known/oauth-protected-resource.ts +37 -0
- package/src/astro/routes/api/widget-areas/[name]/reorder.ts +68 -0
- package/src/astro/routes/api/widget-areas/[name]/widgets/[id].ts +127 -0
- package/src/astro/routes/api/widget-areas/[name]/widgets.ts +80 -0
- package/src/astro/routes/api/widget-areas/[name].ts +87 -0
- package/src/astro/routes/api/widget-areas/index.ts +99 -0
- package/src/astro/routes/api/widget-components.ts +22 -0
- package/src/astro/routes/robots.txt.ts +77 -0
- package/src/astro/routes/sitemap.xml.ts +97 -0
- package/src/astro/storage/adapters.ts +74 -0
- package/src/astro/storage/index.ts +19 -0
- package/src/astro/storage/types.ts +60 -0
- package/src/astro/types.ts +346 -0
- package/src/auth/api-tokens.ts +25 -0
- package/src/auth/challenge-store.ts +80 -0
- package/src/auth/mode.ts +96 -0
- package/src/auth/oauth-state-store.ts +96 -0
- package/src/auth/passkey-config.ts +27 -0
- package/src/auth/rate-limit.ts +158 -0
- package/src/auth/scopes.ts +33 -0
- package/src/auth/types.ts +104 -0
- package/src/aws-sdk.d.ts +100 -0
- package/src/bylines/index.ts +237 -0
- package/src/cleanup.ts +153 -0
- package/src/cli/client-factory.ts +100 -0
- package/src/cli/commands/auth.ts +46 -0
- package/src/cli/commands/bundle-utils.ts +247 -0
- package/src/cli/commands/bundle.ts +609 -0
- package/src/cli/commands/content.ts +442 -0
- package/src/cli/commands/dev.ts +191 -0
- package/src/cli/commands/doctor.ts +211 -0
- package/src/cli/commands/export-seed.ts +630 -0
- package/src/cli/commands/import/wordpress.ts +1056 -0
- package/src/cli/commands/init.ts +192 -0
- package/src/cli/commands/login.ts +547 -0
- package/src/cli/commands/media.ts +165 -0
- package/src/cli/commands/menu.ts +67 -0
- package/src/cli/commands/plugin-init.ts +291 -0
- package/src/cli/commands/plugin-validate.ts +31 -0
- package/src/cli/commands/plugin.ts +33 -0
- package/src/cli/commands/publish.ts +697 -0
- package/src/cli/commands/schema.ts +233 -0
- package/src/cli/commands/search-cmd.ts +54 -0
- package/src/cli/commands/seed.ts +286 -0
- package/src/cli/commands/taxonomy.ts +128 -0
- package/src/cli/commands/types.ts +68 -0
- package/src/cli/credentials.ts +236 -0
- package/src/cli/index.ts +70 -0
- package/src/cli/output.ts +75 -0
- package/src/cli/wxr/parser.ts +969 -0
- package/src/client/cf-access.ts +193 -0
- package/src/client/index.ts +854 -0
- package/src/client/portable-text.ts +413 -0
- package/src/client/transport.ts +200 -0
- package/src/comments/moderator.ts +46 -0
- package/src/comments/notifications.ts +144 -0
- package/src/comments/query.ts +105 -0
- package/src/comments/service.ts +213 -0
- package/src/components/Break.astro +45 -0
- package/src/components/Button.astro +71 -0
- package/src/components/Buttons.astro +49 -0
- package/src/components/Code.astro +59 -0
- package/src/components/Columns.astro +59 -0
- package/src/components/CommentForm.astro +315 -0
- package/src/components/Comments.astro +232 -0
- package/src/components/Cover.astro +128 -0
- package/src/components/EmDashBodyEnd.astro +32 -0
- package/src/components/EmDashBodyStart.astro +32 -0
- package/src/components/EmDashHead.astro +53 -0
- package/src/components/EmDashImage.astro +178 -0
- package/src/components/EmDashMedia.astro +167 -0
- package/src/components/Embed.astro +128 -0
- package/src/components/File.astro +122 -0
- package/src/components/Gallery.astro +93 -0
- package/src/components/HtmlBlock.astro +33 -0
- package/src/components/Image.astro +178 -0
- package/src/components/InlineEditor.astro +27 -0
- package/src/components/InlinePortableTextEditor.tsx +1905 -0
- package/src/components/LiveSearch.astro +614 -0
- package/src/components/PortableText.astro +51 -0
- package/src/components/Pullquote.astro +51 -0
- package/src/components/Table.astro +108 -0
- package/src/components/WidgetArea.astro +22 -0
- package/src/components/WidgetRenderer.astro +72 -0
- package/src/components/index.ts +116 -0
- package/src/components/marks/Link.astro +31 -0
- package/src/components/marks/StrikeThrough.astro +7 -0
- package/src/components/marks/Subscript.astro +7 -0
- package/src/components/marks/Superscript.astro +7 -0
- package/src/components/marks/Underline.astro +7 -0
- package/src/components/widgets/Archives.astro +65 -0
- package/src/components/widgets/Categories.astro +35 -0
- package/src/components/widgets/RecentPosts.astro +51 -0
- package/src/components/widgets/Search.astro +18 -0
- package/src/components/widgets/Tags.astro +38 -0
- package/src/content/converters/index.ts +9 -0
- package/src/content/converters/portable-text-to-prosemirror.ts +385 -0
- package/src/content/converters/prosemirror-to-portable-text.ts +413 -0
- package/src/content/converters/types.ts +120 -0
- package/src/content/index.ts +5 -0
- package/src/database/connection.ts +67 -0
- package/src/database/dialect-helpers.ts +138 -0
- package/src/database/index.ts +5 -0
- package/src/database/migrations/001_initial.ts +170 -0
- package/src/database/migrations/002_media_status.ts +26 -0
- package/src/database/migrations/003_schema_registry.ts +79 -0
- package/src/database/migrations/004_plugins.ts +62 -0
- package/src/database/migrations/005_menus.ts +67 -0
- package/src/database/migrations/006_taxonomy_defs.ts +51 -0
- package/src/database/migrations/007_widgets.ts +42 -0
- package/src/database/migrations/008_auth.ts +194 -0
- package/src/database/migrations/009_user_disabled.ts +27 -0
- package/src/database/migrations/011_sections.ts +65 -0
- package/src/database/migrations/012_search.ts +25 -0
- package/src/database/migrations/013_scheduled_publishing.ts +51 -0
- package/src/database/migrations/014_draft_revisions.ts +72 -0
- package/src/database/migrations/015_indexes.ts +82 -0
- package/src/database/migrations/016_api_tokens.ts +89 -0
- package/src/database/migrations/017_authorization_codes.ts +45 -0
- package/src/database/migrations/018_seo.ts +56 -0
- package/src/database/migrations/019_i18n.ts +618 -0
- package/src/database/migrations/020_collection_url_pattern.ts +23 -0
- package/src/database/migrations/021_remove_section_categories.ts +43 -0
- package/src/database/migrations/022_marketplace_plugin_state.ts +46 -0
- package/src/database/migrations/023_plugin_metadata.ts +33 -0
- package/src/database/migrations/024_media_placeholders.ts +32 -0
- package/src/database/migrations/025_oauth_clients.ts +28 -0
- package/src/database/migrations/026_cron_tasks.ts +49 -0
- package/src/database/migrations/027_comments.ts +87 -0
- package/src/database/migrations/028_drop_author_url.ts +9 -0
- package/src/database/migrations/029_redirects.ts +67 -0
- package/src/database/migrations/030_widen_scheduled_index.ts +48 -0
- package/src/database/migrations/031_bylines.ts +90 -0
- package/src/database/migrations/032_rate_limits.ts +39 -0
- package/src/database/migrations/runner.ts +170 -0
- package/src/database/repositories/audit.ts +294 -0
- package/src/database/repositories/byline.ts +387 -0
- package/src/database/repositories/comment.ts +458 -0
- package/src/database/repositories/content.ts +1144 -0
- package/src/database/repositories/index.ts +30 -0
- package/src/database/repositories/media.ts +347 -0
- package/src/database/repositories/options.ts +150 -0
- package/src/database/repositories/plugin-storage.ts +373 -0
- package/src/database/repositories/redirect.ts +480 -0
- package/src/database/repositories/revision.ts +200 -0
- package/src/database/repositories/seo.ts +176 -0
- package/src/database/repositories/taxonomy.ts +294 -0
- package/src/database/repositories/types.ts +132 -0
- package/src/database/repositories/user.ts +258 -0
- package/src/database/transaction.ts +54 -0
- package/src/database/types.ts +501 -0
- package/src/database/validate.ts +138 -0
- package/src/db/adapters.ts +125 -0
- package/src/db/index.ts +37 -0
- package/src/db/libsql.ts +23 -0
- package/src/db/postgres.ts +30 -0
- package/src/db/sqlite.ts +27 -0
- package/src/emdash-runtime.ts +2096 -0
- package/src/fields/boolean.ts +34 -0
- package/src/fields/datetime.ts +44 -0
- package/src/fields/file.ts +41 -0
- package/src/fields/image.ts +34 -0
- package/src/fields/index.ts +42 -0
- package/src/fields/integer.ts +50 -0
- package/src/fields/json.ts +37 -0
- package/src/fields/multiselect.ts +48 -0
- package/src/fields/number.ts +52 -0
- package/src/fields/portable-text.ts +33 -0
- package/src/fields/reference.ts +29 -0
- package/src/fields/richtext.ts +31 -0
- package/src/fields/select.ts +46 -0
- package/src/fields/slug.ts +38 -0
- package/src/fields/text.ts +55 -0
- package/src/fields/textarea.ts +52 -0
- package/src/fields/types.ts +64 -0
- package/src/i18n/config.ts +68 -0
- package/src/import/index.ts +90 -0
- package/src/import/menus.ts +436 -0
- package/src/import/registry.ts +111 -0
- package/src/import/sections.ts +103 -0
- package/src/import/settings.ts +281 -0
- package/src/import/sources/wordpress-plugin.ts +641 -0
- package/src/import/sources/wordpress-rest.ts +191 -0
- package/src/import/sources/wxr.ts +330 -0
- package/src/import/ssrf.ts +260 -0
- package/src/import/types.ts +418 -0
- package/src/import/utils.ts +412 -0
- package/src/index.ts +481 -0
- package/src/loader.ts +770 -0
- package/src/mcp/server.ts +1463 -0
- package/src/media/index.ts +32 -0
- package/src/media/local-runtime.ts +213 -0
- package/src/media/local.ts +46 -0
- package/src/media/normalize.ts +190 -0
- package/src/media/placeholder.ts +150 -0
- package/src/media/provider-loader.ts +78 -0
- package/src/media/types.ts +279 -0
- package/src/menus/index.ts +324 -0
- package/src/menus/types.ts +112 -0
- package/src/page/context.ts +93 -0
- package/src/page/fragments.ts +89 -0
- package/src/page/index.ts +58 -0
- package/src/page/jsonld.ts +94 -0
- package/src/page/metadata.ts +185 -0
- package/src/page/seo-contributions.ts +136 -0
- package/src/plugin-utils.ts +80 -0
- package/src/plugins/adapt-sandbox-entry.ts +207 -0
- package/src/plugins/context.ts +833 -0
- package/src/plugins/cron.ts +361 -0
- package/src/plugins/define-plugin.ts +259 -0
- package/src/plugins/email-console.ts +73 -0
- package/src/plugins/email.ts +209 -0
- package/src/plugins/hooks.ts +1273 -0
- package/src/plugins/index.ts +193 -0
- package/src/plugins/manager.ts +595 -0
- package/src/plugins/manifest-schema.ts +230 -0
- package/src/plugins/marketplace.ts +460 -0
- package/src/plugins/request-meta.ts +139 -0
- package/src/plugins/routes.ts +302 -0
- package/src/plugins/sandbox/index.ts +18 -0
- package/src/plugins/sandbox/noop.ts +76 -0
- package/src/plugins/sandbox/types.ts +173 -0
- package/src/plugins/scheduler/node.ts +122 -0
- package/src/plugins/scheduler/piggyback.ts +71 -0
- package/src/plugins/scheduler/types.ts +27 -0
- package/src/plugins/state.ts +208 -0
- package/src/plugins/storage-indexes.ts +326 -0
- package/src/plugins/storage-query.ts +240 -0
- package/src/plugins/types.ts +1284 -0
- package/src/preview/helpers.ts +27 -0
- package/src/preview/index.ts +40 -0
- package/src/preview/tokens.ts +279 -0
- package/src/preview/urls.ts +118 -0
- package/src/query.ts +674 -0
- package/src/redirects/patterns.ts +224 -0
- package/src/request-context.ts +67 -0
- package/src/runtime.ts +21 -0
- package/src/schema/index.ts +29 -0
- package/src/schema/query.ts +44 -0
- package/src/schema/registry.ts +965 -0
- package/src/schema/types.ts +276 -0
- package/src/schema/zod-generator.ts +413 -0
- package/src/search/fts-manager.ts +452 -0
- package/src/search/index.ts +26 -0
- package/src/search/query.ts +396 -0
- package/src/search/text-extraction.ts +162 -0
- package/src/search/types.ts +114 -0
- package/src/sections/index.ts +226 -0
- package/src/sections/types.ts +86 -0
- package/src/seed/apply.ts +1141 -0
- package/src/seed/default.ts +86 -0
- package/src/seed/index.ts +28 -0
- package/src/seed/load.ts +35 -0
- package/src/seed/types.ts +341 -0
- package/src/seed/validate.ts +642 -0
- package/src/seo/index.ts +179 -0
- package/src/settings/index.ts +203 -0
- package/src/settings/types.ts +58 -0
- package/src/storage/index.ts +28 -0
- package/src/storage/local.ts +249 -0
- package/src/storage/s3.ts +263 -0
- package/src/storage/types.ts +204 -0
- package/src/taxonomies/index.ts +309 -0
- package/src/taxonomies/types.ts +61 -0
- package/src/ui.ts +75 -0
- package/src/utils/base64.ts +73 -0
- package/src/utils/hash.ts +36 -0
- package/src/utils/sanitize.ts +20 -0
- package/src/utils/slugify.ts +29 -0
- package/src/utils/url.ts +48 -0
- package/src/virtual-modules.d.ts +111 -0
- package/src/visual-editing/editable.ts +108 -0
- package/src/visual-editing/toolbar.ts +1229 -0
- package/src/widgets/components.ts +105 -0
- package/src/widgets/index.ts +131 -0
- package/src/widgets/types.ts +81 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress import prepare endpoint
|
|
3
|
+
*
|
|
4
|
+
* POST /_emdash/api/import/wordpress/prepare
|
|
5
|
+
*
|
|
6
|
+
* Creates collections and fields needed for import.
|
|
7
|
+
* This is called after analyze, before execute.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { APIRoute } from "astro";
|
|
11
|
+
|
|
12
|
+
import { requirePerm } from "#api/authorize.js";
|
|
13
|
+
import { apiError, apiSuccess, handleError } from "#api/error.js";
|
|
14
|
+
import { isParseError, parseBody } from "#api/parse.js";
|
|
15
|
+
import { wpPrepareBody } from "#api/schemas.js";
|
|
16
|
+
import { FIELD_TYPES, type FieldType } from "#schema/types.js";
|
|
17
|
+
import type { EmDashHandlers } from "#types";
|
|
18
|
+
|
|
19
|
+
import { capitalize, singularize, type ImportFieldDef } from "./analyze.js";
|
|
20
|
+
|
|
21
|
+
/** Validate that a string is a known FieldType, returning undefined if not */
|
|
22
|
+
function asFieldType(value: string): FieldType | undefined {
|
|
23
|
+
// eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- validated by includes check
|
|
24
|
+
return (FIELD_TYPES as readonly string[]).includes(value) ? (value as FieldType) : undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const prerender = false;
|
|
28
|
+
|
|
29
|
+
interface PrepareRequest {
|
|
30
|
+
postTypes: Array<{
|
|
31
|
+
name: string;
|
|
32
|
+
collection: string;
|
|
33
|
+
fields: ImportFieldDef[];
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface PrepareResult {
|
|
38
|
+
success: boolean;
|
|
39
|
+
collectionsCreated: string[];
|
|
40
|
+
fieldsCreated: Array<{ collection: string; field: string }>;
|
|
41
|
+
errors: Array<{ collection: string; error: string }>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const POST: APIRoute = async ({ request, locals }) => {
|
|
45
|
+
const { emdash, user } = locals;
|
|
46
|
+
|
|
47
|
+
if (!emdash?.db) {
|
|
48
|
+
return apiError("NOT_CONFIGURED", "EmDash not configured", 500);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const denied = requirePerm(user, "import:execute");
|
|
52
|
+
if (denied) return denied;
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const body = await parseBody(request, wpPrepareBody);
|
|
56
|
+
if (isParseError(body)) return body;
|
|
57
|
+
|
|
58
|
+
// eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Zod schema output narrowed to PrepareRequest
|
|
59
|
+
const result = await prepareImport(emdash.db, body as PrepareRequest);
|
|
60
|
+
|
|
61
|
+
return apiSuccess(result, result.success ? 200 : 400);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
return handleError(error, "Failed to prepare import", "WXR_PREPARE_ERROR");
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
async function prepareImport(
|
|
68
|
+
db: NonNullable<EmDashHandlers["db"]>,
|
|
69
|
+
request: PrepareRequest,
|
|
70
|
+
): Promise<PrepareResult> {
|
|
71
|
+
const { SchemaRegistry } = await import("#schema/registry.js");
|
|
72
|
+
const registry = new SchemaRegistry(db);
|
|
73
|
+
|
|
74
|
+
const result: PrepareResult = {
|
|
75
|
+
success: true,
|
|
76
|
+
collectionsCreated: [],
|
|
77
|
+
fieldsCreated: [],
|
|
78
|
+
errors: [],
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
for (const postType of request.postTypes) {
|
|
82
|
+
const collectionSlug = postType.collection;
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
// Check if collection exists
|
|
86
|
+
let collection = await registry.getCollection(collectionSlug);
|
|
87
|
+
|
|
88
|
+
if (!collection) {
|
|
89
|
+
// Create the collection
|
|
90
|
+
const label = capitalize(collectionSlug);
|
|
91
|
+
const labelSingular = capitalize(singularize(collectionSlug));
|
|
92
|
+
|
|
93
|
+
// Enable search by default for posts and pages
|
|
94
|
+
const isSearchable = ["posts", "pages", "post", "page"].includes(collectionSlug);
|
|
95
|
+
const supports: ("revisions" | "drafts" | "search")[] = ["revisions", "drafts"];
|
|
96
|
+
if (isSearchable) {
|
|
97
|
+
supports.push("search");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Default URL patterns for known post types
|
|
101
|
+
const urlPattern =
|
|
102
|
+
collectionSlug === "pages"
|
|
103
|
+
? "/{slug}"
|
|
104
|
+
: collectionSlug === "posts"
|
|
105
|
+
? "/blog/{slug}"
|
|
106
|
+
: undefined;
|
|
107
|
+
|
|
108
|
+
collection = await registry.createCollection({
|
|
109
|
+
slug: collectionSlug,
|
|
110
|
+
label,
|
|
111
|
+
labelSingular,
|
|
112
|
+
description: `Imported from WordPress post type: ${postType.name}`,
|
|
113
|
+
supports,
|
|
114
|
+
urlPattern,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
result.collectionsCreated.push(collectionSlug);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Create missing fields
|
|
121
|
+
const existingFields = await registry.listFields(collection.id);
|
|
122
|
+
const existingFieldSlugs = new Set(existingFields.map((f) => f.slug));
|
|
123
|
+
|
|
124
|
+
for (const field of postType.fields) {
|
|
125
|
+
if (existingFieldSlugs.has(field.slug)) {
|
|
126
|
+
// Field already exists - skip
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const fieldType = asFieldType(field.type);
|
|
131
|
+
if (!fieldType) {
|
|
132
|
+
result.errors.push({
|
|
133
|
+
collection: collectionSlug,
|
|
134
|
+
error: `Unknown field type "${field.type}" for field "${field.slug}"`,
|
|
135
|
+
});
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
await registry.createField(collectionSlug, {
|
|
140
|
+
slug: field.slug,
|
|
141
|
+
label: field.label,
|
|
142
|
+
type: fieldType,
|
|
143
|
+
required: field.required,
|
|
144
|
+
unique: false,
|
|
145
|
+
searchable: field.searchable ?? false,
|
|
146
|
+
sortOrder: existingFields.length + result.fieldsCreated.length,
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
result.fieldsCreated.push({
|
|
150
|
+
collection: collectionSlug,
|
|
151
|
+
field: field.slug,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Enable search if collection supports it and has searchable fields
|
|
156
|
+
const isSearchable = ["posts", "pages", "post", "page"].includes(collectionSlug);
|
|
157
|
+
if (isSearchable) {
|
|
158
|
+
const { FTSManager } = await import("#search/fts-manager.js");
|
|
159
|
+
const ftsManager = new FTSManager(db);
|
|
160
|
+
|
|
161
|
+
const searchableFields = await ftsManager.getSearchableFields(collectionSlug);
|
|
162
|
+
if (searchableFields.length > 0) {
|
|
163
|
+
try {
|
|
164
|
+
await ftsManager.enableSearch(collectionSlug);
|
|
165
|
+
} catch {
|
|
166
|
+
// Ignore - search can be enabled manually later
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
} catch (error) {
|
|
171
|
+
console.error(`Prepare error for collection "${collectionSlug}":`, error);
|
|
172
|
+
result.success = false;
|
|
173
|
+
result.errors.push({
|
|
174
|
+
collection: collectionSlug,
|
|
175
|
+
error: "Failed to prepare collection",
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress URL rewrite endpoint
|
|
3
|
+
*
|
|
4
|
+
* POST /_emdash/api/import/wordpress/rewrite-urls
|
|
5
|
+
*
|
|
6
|
+
* Rewrites old WordPress media URLs in Portable Text content
|
|
7
|
+
* to point to newly imported EmDash media URLs.
|
|
8
|
+
*
|
|
9
|
+
* Handles URL variants (e.g., image.jpg vs image.jpg?w=200) by matching
|
|
10
|
+
* on the base URL path without query parameters.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { APIRoute } from "astro";
|
|
14
|
+
import { sql } from "kysely";
|
|
15
|
+
|
|
16
|
+
import { requirePerm } from "#api/authorize.js";
|
|
17
|
+
import { apiError, apiSuccess, handleError } from "#api/error.js";
|
|
18
|
+
import { isParseError, parseBody } from "#api/parse.js";
|
|
19
|
+
import { wpRewriteUrlsBody } from "#api/schemas.js";
|
|
20
|
+
import { normalizeMediaValue } from "#media/normalize.js";
|
|
21
|
+
import type { MediaProvider } from "#media/types.js";
|
|
22
|
+
import type { EmDashHandlers } from "#types";
|
|
23
|
+
|
|
24
|
+
export const prerender = false;
|
|
25
|
+
|
|
26
|
+
const REGEX_SPECIAL_CHARS = /[.*+?^${}()|[\]\\]/g;
|
|
27
|
+
|
|
28
|
+
export interface RewriteUrlsResult {
|
|
29
|
+
/** Total items updated */
|
|
30
|
+
updated: number;
|
|
31
|
+
/** Updates by collection */
|
|
32
|
+
byCollection: Record<string, number>;
|
|
33
|
+
/** URLs that were rewritten */
|
|
34
|
+
urlsRewritten: number;
|
|
35
|
+
/** Any errors encountered */
|
|
36
|
+
errors: Array<{ collection: string; id: string; error: string }>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const POST: APIRoute = async ({ request, locals }) => {
|
|
40
|
+
const { emdash, user } = locals;
|
|
41
|
+
|
|
42
|
+
if (!emdash?.db) {
|
|
43
|
+
return apiError("NO_DB", "Database not initialized", 500);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const denied = requirePerm(user, "import:execute");
|
|
47
|
+
if (denied) return denied;
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
const body = await parseBody(request, wpRewriteUrlsBody);
|
|
51
|
+
if (isParseError(body)) return body;
|
|
52
|
+
|
|
53
|
+
const urlEntries = Object.entries(body.urlMap);
|
|
54
|
+
if (urlEntries.length === 0) {
|
|
55
|
+
return apiSuccess({
|
|
56
|
+
updated: 0,
|
|
57
|
+
byCollection: {},
|
|
58
|
+
urlsRewritten: 0,
|
|
59
|
+
errors: [],
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const getProvider = (id: string) => emdash.getMediaProvider(id);
|
|
64
|
+
const result = await rewriteUrls(emdash.db, body.urlMap, getProvider, body.collections);
|
|
65
|
+
|
|
66
|
+
return apiSuccess(result);
|
|
67
|
+
} catch (error) {
|
|
68
|
+
return handleError(error, "Failed to rewrite URLs", "REWRITE_ERROR");
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Strip query parameters from a URL for base matching
|
|
74
|
+
*/
|
|
75
|
+
function getBaseUrl(url: string): string {
|
|
76
|
+
try {
|
|
77
|
+
const parsed = new URL(url);
|
|
78
|
+
return `${parsed.origin}${parsed.pathname}`;
|
|
79
|
+
} catch {
|
|
80
|
+
// If URL parsing fails, try simple string split
|
|
81
|
+
return url.split("?")[0] || url;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Build a map of base URLs to new URLs for flexible matching
|
|
87
|
+
*/
|
|
88
|
+
function buildBaseUrlMap(urlMap: Record<string, string>): Map<string, string> {
|
|
89
|
+
const baseMap = new Map<string, string>();
|
|
90
|
+
for (const [oldUrl, newUrl] of Object.entries(urlMap)) {
|
|
91
|
+
const baseUrl = getBaseUrl(oldUrl);
|
|
92
|
+
baseMap.set(baseUrl, newUrl);
|
|
93
|
+
}
|
|
94
|
+
return baseMap;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Find matching new URL for a given URL, checking both exact and base matches
|
|
99
|
+
*/
|
|
100
|
+
function findMatchingUrl(
|
|
101
|
+
url: string,
|
|
102
|
+
exactMap: Record<string, string>,
|
|
103
|
+
baseMap: Map<string, string>,
|
|
104
|
+
): string | null {
|
|
105
|
+
// Try exact match first
|
|
106
|
+
if (exactMap[url]) {
|
|
107
|
+
return exactMap[url];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Try base URL match (ignoring query params)
|
|
111
|
+
const baseUrl = getBaseUrl(url);
|
|
112
|
+
const baseMatch = baseMap.get(baseUrl);
|
|
113
|
+
if (baseMatch) {
|
|
114
|
+
return baseMatch;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Portable Text block type (simplified for URL rewriting)
|
|
122
|
+
*/
|
|
123
|
+
interface PortableTextBlock {
|
|
124
|
+
_type: string;
|
|
125
|
+
_key?: string;
|
|
126
|
+
asset?: {
|
|
127
|
+
_type?: string;
|
|
128
|
+
_ref?: string;
|
|
129
|
+
url?: string;
|
|
130
|
+
};
|
|
131
|
+
link?: string;
|
|
132
|
+
// For nested content like galleries
|
|
133
|
+
images?: PortableTextBlock[];
|
|
134
|
+
columns?: Array<{ content?: PortableTextBlock[] }>;
|
|
135
|
+
[key: string]: unknown;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Rewrite URLs in a Portable Text array, returning whether any changes were made
|
|
140
|
+
*/
|
|
141
|
+
function rewritePortableTextUrls(
|
|
142
|
+
blocks: PortableTextBlock[],
|
|
143
|
+
exactMap: Record<string, string>,
|
|
144
|
+
baseMap: Map<string, string>,
|
|
145
|
+
): { changed: boolean; urlsRewritten: number } {
|
|
146
|
+
let changed = false;
|
|
147
|
+
let urlsRewritten = 0;
|
|
148
|
+
|
|
149
|
+
for (const block of blocks) {
|
|
150
|
+
// Handle image blocks
|
|
151
|
+
if (block._type === "image" && block.asset?.url) {
|
|
152
|
+
const newUrl = findMatchingUrl(block.asset.url, exactMap, baseMap);
|
|
153
|
+
if (newUrl) {
|
|
154
|
+
block.asset.url = newUrl;
|
|
155
|
+
block.asset._ref = newUrl; // Also update the reference
|
|
156
|
+
changed = true;
|
|
157
|
+
urlsRewritten++;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Handle image link URLs (for linked images)
|
|
162
|
+
if (block._type === "image" && block.link) {
|
|
163
|
+
const newUrl = findMatchingUrl(block.link, exactMap, baseMap);
|
|
164
|
+
if (newUrl) {
|
|
165
|
+
block.link = newUrl;
|
|
166
|
+
changed = true;
|
|
167
|
+
urlsRewritten++;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Handle gallery blocks with nested images
|
|
172
|
+
if (block._type === "gallery" && Array.isArray(block.images)) {
|
|
173
|
+
const result = rewritePortableTextUrls(block.images, exactMap, baseMap);
|
|
174
|
+
if (result.changed) {
|
|
175
|
+
changed = true;
|
|
176
|
+
urlsRewritten += result.urlsRewritten;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Handle columns blocks with nested content
|
|
181
|
+
if (block._type === "columns" && Array.isArray(block.columns)) {
|
|
182
|
+
for (const column of block.columns) {
|
|
183
|
+
if (Array.isArray(column.content)) {
|
|
184
|
+
const result = rewritePortableTextUrls(column.content, exactMap, baseMap);
|
|
185
|
+
if (result.changed) {
|
|
186
|
+
changed = true;
|
|
187
|
+
urlsRewritten += result.urlsRewritten;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return { changed, urlsRewritten };
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Rewrite URLs in a string field using simple string replacement
|
|
199
|
+
*/
|
|
200
|
+
function rewriteStringUrls(
|
|
201
|
+
value: string,
|
|
202
|
+
exactMap: Record<string, string>,
|
|
203
|
+
baseMap: Map<string, string>,
|
|
204
|
+
): { newValue: string; changed: boolean; urlsRewritten: number } {
|
|
205
|
+
let newValue = value;
|
|
206
|
+
let changed = false;
|
|
207
|
+
let urlsRewritten = 0;
|
|
208
|
+
|
|
209
|
+
// Try exact matches first
|
|
210
|
+
for (const [oldUrl, newUrl] of Object.entries(exactMap)) {
|
|
211
|
+
if (newValue.includes(oldUrl)) {
|
|
212
|
+
newValue = newValue.split(oldUrl).join(newUrl);
|
|
213
|
+
changed = true;
|
|
214
|
+
urlsRewritten++;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// For base URL matching in strings, we need to be more careful
|
|
219
|
+
// Only match if we find a URL that starts with the base
|
|
220
|
+
for (const [baseUrl, newUrl] of baseMap.entries()) {
|
|
221
|
+
// Look for the base URL followed by optional query string or end
|
|
222
|
+
const regex = new RegExp(escapeRegExp(baseUrl) + "(\\?[^\"'\\s]*)?", "g");
|
|
223
|
+
const matches = newValue.match(regex);
|
|
224
|
+
if (matches) {
|
|
225
|
+
for (const match of matches) {
|
|
226
|
+
// Don't replace if we already have an exact match in the map
|
|
227
|
+
if (!exactMap[match]) {
|
|
228
|
+
newValue = newValue.split(match).join(newUrl);
|
|
229
|
+
changed = true;
|
|
230
|
+
urlsRewritten++;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return { newValue, changed, urlsRewritten };
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Escape special regex characters in a string
|
|
241
|
+
*/
|
|
242
|
+
function escapeRegExp(string: string): string {
|
|
243
|
+
return string.replace(REGEX_SPECIAL_CHARS, "\\$&");
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async function rewriteUrls(
|
|
247
|
+
db: NonNullable<EmDashHandlers["db"]>,
|
|
248
|
+
urlMap: Record<string, string>,
|
|
249
|
+
getProvider: (id: string) => MediaProvider | undefined,
|
|
250
|
+
collections?: string[],
|
|
251
|
+
): Promise<RewriteUrlsResult> {
|
|
252
|
+
const { SchemaRegistry } = await import("#schema/registry.js");
|
|
253
|
+
const registry = new SchemaRegistry(db);
|
|
254
|
+
|
|
255
|
+
const result: RewriteUrlsResult = {
|
|
256
|
+
updated: 0,
|
|
257
|
+
byCollection: {},
|
|
258
|
+
urlsRewritten: 0,
|
|
259
|
+
errors: [],
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
// Build base URL map for flexible matching
|
|
263
|
+
const baseMap = buildBaseUrlMap(urlMap);
|
|
264
|
+
|
|
265
|
+
// Get all collections or filter to specified ones
|
|
266
|
+
const allCollections = await registry.listCollections();
|
|
267
|
+
const targetCollections = collections?.length
|
|
268
|
+
? allCollections.filter((c) => collections.includes(c.slug))
|
|
269
|
+
: allCollections;
|
|
270
|
+
|
|
271
|
+
for (const collection of targetCollections) {
|
|
272
|
+
// Get fields that might contain URLs
|
|
273
|
+
const fields = await registry.listFields(collection.id);
|
|
274
|
+
const portableTextFields = fields.filter((f) => f.type === "portableText");
|
|
275
|
+
const stringFields = fields.filter((f) => ["text", "string"].includes(f.type));
|
|
276
|
+
// Image and file fields store URLs directly as TEXT
|
|
277
|
+
const mediaFields = fields.filter((f) => ["image", "file"].includes(f.type));
|
|
278
|
+
|
|
279
|
+
if (portableTextFields.length === 0 && stringFields.length === 0 && mediaFields.length === 0)
|
|
280
|
+
continue;
|
|
281
|
+
|
|
282
|
+
// Get table name
|
|
283
|
+
const tableName = `ec_${collection.slug}`;
|
|
284
|
+
|
|
285
|
+
try {
|
|
286
|
+
// Query all rows
|
|
287
|
+
const rows = await sql<{ id: string; [key: string]: unknown }>`
|
|
288
|
+
SELECT * FROM ${sql.ref(tableName)}
|
|
289
|
+
WHERE deleted_at IS NULL
|
|
290
|
+
`.execute(db);
|
|
291
|
+
|
|
292
|
+
for (const row of rows.rows) {
|
|
293
|
+
let rowUpdated = false;
|
|
294
|
+
const updates: Record<string, unknown> = {};
|
|
295
|
+
let rowUrlsRewritten = 0;
|
|
296
|
+
|
|
297
|
+
// Handle Portable Text fields - parse JSON and rewrite URLs in blocks
|
|
298
|
+
for (const field of portableTextFields) {
|
|
299
|
+
const value = row[field.slug];
|
|
300
|
+
if (!value || typeof value !== "string") continue;
|
|
301
|
+
|
|
302
|
+
try {
|
|
303
|
+
// eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- JSON.parse returns unknown; validated by Array.isArray below
|
|
304
|
+
const blocks = JSON.parse(value) as PortableTextBlock[];
|
|
305
|
+
if (!Array.isArray(blocks)) continue;
|
|
306
|
+
|
|
307
|
+
const rewriteResult = rewritePortableTextUrls(blocks, urlMap, baseMap);
|
|
308
|
+
|
|
309
|
+
if (rewriteResult.changed) {
|
|
310
|
+
updates[field.slug] = JSON.stringify(blocks);
|
|
311
|
+
rowUpdated = true;
|
|
312
|
+
rowUrlsRewritten += rewriteResult.urlsRewritten;
|
|
313
|
+
}
|
|
314
|
+
} catch {
|
|
315
|
+
// Not valid JSON, try string replacement as fallback
|
|
316
|
+
const stringResult = rewriteStringUrls(value, urlMap, baseMap);
|
|
317
|
+
if (stringResult.changed) {
|
|
318
|
+
updates[field.slug] = stringResult.newValue;
|
|
319
|
+
rowUpdated = true;
|
|
320
|
+
rowUrlsRewritten += stringResult.urlsRewritten;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Handle string/text fields - simple string replacement
|
|
326
|
+
for (const field of stringFields) {
|
|
327
|
+
const value = row[field.slug];
|
|
328
|
+
if (!value || typeof value !== "string") continue;
|
|
329
|
+
|
|
330
|
+
const stringResult = rewriteStringUrls(value, urlMap, baseMap);
|
|
331
|
+
if (stringResult.changed) {
|
|
332
|
+
updates[field.slug] = stringResult.newValue;
|
|
333
|
+
rowUpdated = true;
|
|
334
|
+
rowUrlsRewritten += stringResult.urlsRewritten;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Handle image/file fields - normalize to MediaValue objects
|
|
339
|
+
for (const field of mediaFields) {
|
|
340
|
+
const value = row[field.slug];
|
|
341
|
+
if (!value || typeof value !== "string") continue;
|
|
342
|
+
|
|
343
|
+
// Try to find a matching rewritten URL
|
|
344
|
+
const newUrl = findMatchingUrl(value, urlMap, baseMap);
|
|
345
|
+
if (newUrl) {
|
|
346
|
+
// Normalize into a proper MediaValue instead of storing a bare URL
|
|
347
|
+
try {
|
|
348
|
+
const normalized = await normalizeMediaValue(newUrl, getProvider);
|
|
349
|
+
updates[field.slug] = normalized ? JSON.stringify(normalized) : newUrl;
|
|
350
|
+
} catch {
|
|
351
|
+
updates[field.slug] = newUrl;
|
|
352
|
+
}
|
|
353
|
+
rowUpdated = true;
|
|
354
|
+
rowUrlsRewritten++;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (rowUpdated) {
|
|
359
|
+
try {
|
|
360
|
+
// Build update query dynamically
|
|
361
|
+
// eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Kysely dynamic table requires type assertion
|
|
362
|
+
let query = db.updateTable(tableName as any).where("id", "=", row.id);
|
|
363
|
+
|
|
364
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
365
|
+
// eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Kysely dynamic column update requires type assertion
|
|
366
|
+
query = query.set({ [key]: value } as any);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
await query.execute();
|
|
370
|
+
|
|
371
|
+
result.updated++;
|
|
372
|
+
result.urlsRewritten += rowUrlsRewritten;
|
|
373
|
+
result.byCollection[collection.slug] = (result.byCollection[collection.slug] || 0) + 1;
|
|
374
|
+
} catch (updateError) {
|
|
375
|
+
result.errors.push({
|
|
376
|
+
collection: collection.slug,
|
|
377
|
+
id: row.id,
|
|
378
|
+
error: updateError instanceof Error ? updateError.message : "Update failed",
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
} catch (queryError) {
|
|
384
|
+
result.errors.push({
|
|
385
|
+
collection: collection.slug,
|
|
386
|
+
id: "*",
|
|
387
|
+
error: queryError instanceof Error ? queryError.message : "Query failed for collection",
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
return result;
|
|
393
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress Plugin analyze endpoint
|
|
3
|
+
*
|
|
4
|
+
* POST /_emdash/api/import/wordpress-plugin/analyze
|
|
5
|
+
*
|
|
6
|
+
* Analyzes a WordPress site with EmDash Exporter plugin installed.
|
|
7
|
+
* Returns content counts, schema compatibility, etc.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { APIRoute } from "astro";
|
|
11
|
+
import { SchemaRegistry } from "emdash";
|
|
12
|
+
|
|
13
|
+
import { requirePerm } from "#api/authorize.js";
|
|
14
|
+
import { apiError, apiSuccess, handleError } from "#api/error.js";
|
|
15
|
+
import { isParseError, parseBody } from "#api/parse.js";
|
|
16
|
+
import { wpPluginAnalyzeBody } from "#api/schemas.js";
|
|
17
|
+
import { getSource } from "#import/index.js";
|
|
18
|
+
import { validateExternalUrl, SsrfError } from "#import/ssrf.js";
|
|
19
|
+
import type { ImportAnalysis } from "#import/types.js";
|
|
20
|
+
import type { EmDashHandlers } from "#types";
|
|
21
|
+
|
|
22
|
+
export const prerender = false;
|
|
23
|
+
|
|
24
|
+
export interface WpPluginAnalyzeResponse {
|
|
25
|
+
success: boolean;
|
|
26
|
+
analysis?: ImportAnalysis;
|
|
27
|
+
error?: { message: string };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const POST: APIRoute = async ({ request, locals }) => {
|
|
31
|
+
const { emdash, user } = locals;
|
|
32
|
+
|
|
33
|
+
const denied = requirePerm(user, "import:execute");
|
|
34
|
+
if (denied) return denied;
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
const body = await parseBody(request, wpPluginAnalyzeBody);
|
|
38
|
+
if (isParseError(body)) return body;
|
|
39
|
+
|
|
40
|
+
// SSRF: reject internal/private network targets
|
|
41
|
+
try {
|
|
42
|
+
validateExternalUrl(body.url);
|
|
43
|
+
} catch (e) {
|
|
44
|
+
const msg = e instanceof SsrfError ? e.message : "Invalid URL";
|
|
45
|
+
return apiError("SSRF_BLOCKED", msg, 400);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Get the WordPress plugin source
|
|
49
|
+
const source = getSource("wordpress-plugin");
|
|
50
|
+
if (!source) {
|
|
51
|
+
return apiError("NOT_CONFIGURED", "WordPress plugin source not available", 500);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Build context with existing collections info
|
|
55
|
+
const existingCollections = await fetchExistingCollections(emdash?.db);
|
|
56
|
+
|
|
57
|
+
// Analyze the site
|
|
58
|
+
const analysis = await source.analyze(
|
|
59
|
+
{ type: "url", url: body.url, token: body.token },
|
|
60
|
+
{
|
|
61
|
+
db: emdash?.db,
|
|
62
|
+
getExistingCollections: async () => existingCollections,
|
|
63
|
+
},
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
return apiSuccess({
|
|
67
|
+
success: true,
|
|
68
|
+
analysis,
|
|
69
|
+
});
|
|
70
|
+
} catch (error) {
|
|
71
|
+
return handleError(error, "Failed to analyze WordPress site", "WP_PLUGIN_ANALYZE_ERROR");
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/** Existing collection info from schema registry */
|
|
76
|
+
interface ExistingCollection {
|
|
77
|
+
slug: string;
|
|
78
|
+
fields: Map<string, { type: string }>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Fetch collections and their fields from schema registry */
|
|
82
|
+
async function fetchExistingCollections(
|
|
83
|
+
db: EmDashHandlers["db"] | undefined,
|
|
84
|
+
): Promise<Map<string, ExistingCollection>> {
|
|
85
|
+
const result = new Map<string, ExistingCollection>();
|
|
86
|
+
|
|
87
|
+
if (!db) return result;
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const registry = new SchemaRegistry(db);
|
|
91
|
+
const collections = await registry.listCollections();
|
|
92
|
+
|
|
93
|
+
for (const collection of collections) {
|
|
94
|
+
const fields = await registry.listFields(collection.id);
|
|
95
|
+
const fieldMap = new Map<string, { type: string }>();
|
|
96
|
+
|
|
97
|
+
for (const field of fields) {
|
|
98
|
+
fieldMap.set(field.slug, { type: field.type });
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
result.set(collection.slug, {
|
|
102
|
+
slug: collection.slug,
|
|
103
|
+
fields: fieldMap,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.warn("Could not fetch schema registry:", error);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return result;
|
|
111
|
+
}
|