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,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* POST /_emdash/api/setup/dev-bypass
|
|
3
|
+
* GET /_emdash/api/setup/dev-bypass
|
|
4
|
+
*
|
|
5
|
+
* Development-only endpoint to bypass the setup wizard.
|
|
6
|
+
* Runs migrations, creates a dev admin user, and marks setup complete.
|
|
7
|
+
*
|
|
8
|
+
* ONLY available when import.meta.env.DEV is true.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* - GET with redirect: /_emdash/api/setup/dev-bypass?redirect=/_emdash/admin
|
|
12
|
+
* - POST for API: Returns JSON with setup info
|
|
13
|
+
*
|
|
14
|
+
* For agent/browser testing, navigate to:
|
|
15
|
+
* /_emdash/api/setup/dev-bypass?redirect=/_emdash/admin
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { APIRoute } from "astro";
|
|
19
|
+
|
|
20
|
+
export const prerender = false;
|
|
21
|
+
|
|
22
|
+
import { ulid } from "ulidx";
|
|
23
|
+
|
|
24
|
+
import { apiError, apiSuccess, handleError } from "#api/error.js";
|
|
25
|
+
import { escapeHtml } from "#api/escape.js";
|
|
26
|
+
import { handleApiTokenCreate } from "#api/handlers/api-tokens.js";
|
|
27
|
+
import { isSafeRedirect } from "#api/redirect.js";
|
|
28
|
+
import { runMigrations } from "#db/migrations/runner.js";
|
|
29
|
+
import { OptionsRepository } from "#db/repositories/options.js";
|
|
30
|
+
import { applySeed } from "#seed/apply.js";
|
|
31
|
+
import { loadSeed } from "#seed/load.js";
|
|
32
|
+
import { validateSeed } from "#seed/validate.js";
|
|
33
|
+
|
|
34
|
+
// RBAC role levels (matching @emdash-cms/auth)
|
|
35
|
+
const ROLE_ADMIN = 50;
|
|
36
|
+
|
|
37
|
+
const DEV_USER_EMAIL = "dev@emdash.local";
|
|
38
|
+
const DEV_USER_NAME = "Dev Admin";
|
|
39
|
+
const DEV_SITE_TITLE = "EmDash Dev Site";
|
|
40
|
+
|
|
41
|
+
async function handleDevBypass(context: Parameters<APIRoute>[0]): Promise<Response> {
|
|
42
|
+
// CRITICAL: Only allow in development mode
|
|
43
|
+
if (!import.meta.env.DEV) {
|
|
44
|
+
return apiError("FORBIDDEN", "Dev bypass is only available in development mode", 403);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const { locals, url, session } = context;
|
|
48
|
+
const { emdash } = locals;
|
|
49
|
+
|
|
50
|
+
if (!emdash?.db) {
|
|
51
|
+
return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
// Run migrations
|
|
56
|
+
const migrations = await runMigrations(emdash.db);
|
|
57
|
+
console.log("[setup-dev-bypass] Migrations applied:", migrations.applied);
|
|
58
|
+
|
|
59
|
+
// Apply seed (user seed or built-in default)
|
|
60
|
+
const seed = await loadSeed();
|
|
61
|
+
const validation = validateSeed(seed);
|
|
62
|
+
if (validation.valid) {
|
|
63
|
+
const seedResult = await applySeed(emdash.db, seed, {
|
|
64
|
+
includeContent: true,
|
|
65
|
+
onConflict: "skip",
|
|
66
|
+
storage: emdash.storage ?? undefined,
|
|
67
|
+
});
|
|
68
|
+
console.log(
|
|
69
|
+
`[setup-dev-bypass] Seed applied: ${seedResult.collections.created} collections, ${seedResult.fields.created} fields`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const options = new OptionsRepository(emdash.db);
|
|
74
|
+
|
|
75
|
+
// Find or create dev user (direct DB access to avoid @emdash-cms/auth import issues in dev)
|
|
76
|
+
const existingUser = await emdash.db
|
|
77
|
+
.selectFrom("users")
|
|
78
|
+
.selectAll()
|
|
79
|
+
.where("email", "=", DEV_USER_EMAIL)
|
|
80
|
+
.executeTakeFirst();
|
|
81
|
+
|
|
82
|
+
let user: { id: string; email: string; name: string; role: number };
|
|
83
|
+
let userCreated = false;
|
|
84
|
+
|
|
85
|
+
if (!existingUser) {
|
|
86
|
+
const now = new Date().toISOString();
|
|
87
|
+
const newUser = {
|
|
88
|
+
id: ulid(),
|
|
89
|
+
email: DEV_USER_EMAIL,
|
|
90
|
+
name: DEV_USER_NAME,
|
|
91
|
+
role: ROLE_ADMIN,
|
|
92
|
+
email_verified: 1,
|
|
93
|
+
created_at: now,
|
|
94
|
+
updated_at: now,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
await emdash.db.insertInto("users").values(newUser).execute();
|
|
98
|
+
|
|
99
|
+
user = {
|
|
100
|
+
id: newUser.id,
|
|
101
|
+
email: newUser.email,
|
|
102
|
+
name: newUser.name,
|
|
103
|
+
role: newUser.role,
|
|
104
|
+
};
|
|
105
|
+
userCreated = true;
|
|
106
|
+
console.log("[setup-dev-bypass] Created dev admin user:", user.email);
|
|
107
|
+
} else {
|
|
108
|
+
user = {
|
|
109
|
+
id: existingUser.id,
|
|
110
|
+
email: existingUser.email,
|
|
111
|
+
name: existingUser.name || DEV_USER_NAME,
|
|
112
|
+
role: existingUser.role,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Set site title if not already set
|
|
117
|
+
const existingTitle = await options.get("emdash:site_title");
|
|
118
|
+
if (!existingTitle) {
|
|
119
|
+
await options.set("emdash:site_title", DEV_SITE_TITLE);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Store canonical site URL (used by magic-link/recovery emails)
|
|
123
|
+
await options.set("emdash:site_url", url.origin);
|
|
124
|
+
|
|
125
|
+
// Mark setup complete
|
|
126
|
+
await options.set("emdash:setup_complete", true);
|
|
127
|
+
|
|
128
|
+
// Create session
|
|
129
|
+
if (session) {
|
|
130
|
+
session.set("user", { id: user.id });
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Optionally create a PAT token (?token=1) for headless/CLI testing.
|
|
134
|
+
let token: string | undefined;
|
|
135
|
+
if (url.searchParams.has("token")) {
|
|
136
|
+
const result = await handleApiTokenCreate(emdash.db, user.id, {
|
|
137
|
+
name: "dev-bypass-token",
|
|
138
|
+
scopes: [
|
|
139
|
+
"content:read",
|
|
140
|
+
"content:write",
|
|
141
|
+
"media:read",
|
|
142
|
+
"media:write",
|
|
143
|
+
"schema:read",
|
|
144
|
+
"schema:write",
|
|
145
|
+
"admin",
|
|
146
|
+
],
|
|
147
|
+
});
|
|
148
|
+
if (result.success) {
|
|
149
|
+
token = result.data.token;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Check for redirect parameter
|
|
154
|
+
const redirect = url.searchParams.get("redirect");
|
|
155
|
+
|
|
156
|
+
if (redirect) {
|
|
157
|
+
// Validate redirect is a safe local path (prevent open redirect via //evil.com or /\evil.com)
|
|
158
|
+
if (!isSafeRedirect(redirect)) {
|
|
159
|
+
return apiError("INVALID_REDIRECT", "Redirect must be a local path", 400);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Return an HTML page with meta-refresh redirect
|
|
163
|
+
// This ensures the session is fully saved before redirect
|
|
164
|
+
const safeRedirect = escapeHtml(redirect);
|
|
165
|
+
const html = `<!DOCTYPE html>
|
|
166
|
+
<html>
|
|
167
|
+
<head>
|
|
168
|
+
<meta http-equiv="refresh" content="0;url=${safeRedirect}">
|
|
169
|
+
</head>
|
|
170
|
+
<body>Redirecting...</body>
|
|
171
|
+
</html>`;
|
|
172
|
+
return new Response(html, {
|
|
173
|
+
status: 200,
|
|
174
|
+
headers: { "Content-Type": "text/html" },
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Return JSON response
|
|
179
|
+
return apiSuccess({
|
|
180
|
+
success: true,
|
|
181
|
+
message: "Dev setup complete",
|
|
182
|
+
migrations: migrations.applied,
|
|
183
|
+
userCreated,
|
|
184
|
+
user: {
|
|
185
|
+
id: user.id,
|
|
186
|
+
email: user.email,
|
|
187
|
+
name: user.name,
|
|
188
|
+
role: user.role,
|
|
189
|
+
},
|
|
190
|
+
...(token ? { token } : {}),
|
|
191
|
+
});
|
|
192
|
+
} catch (error) {
|
|
193
|
+
return handleError(error, "Dev bypass failed", "DEV_BYPASS_ERROR");
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Support both GET and POST
|
|
198
|
+
export const GET: APIRoute = handleDevBypass;
|
|
199
|
+
export const POST: APIRoute = handleDevBypass;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* POST /_emdash/api/setup/dev-reset
|
|
3
|
+
*
|
|
4
|
+
* Development-only endpoint to reset setup state for testing.
|
|
5
|
+
* Clears the setup_complete flag and deletes all users,
|
|
6
|
+
* returning the site to the pre-setup state.
|
|
7
|
+
*
|
|
8
|
+
* ONLY available when import.meta.env.DEV is true.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { APIRoute } from "astro";
|
|
12
|
+
|
|
13
|
+
export const prerender = false;
|
|
14
|
+
|
|
15
|
+
import { apiError, apiSuccess, handleError } from "#api/error.js";
|
|
16
|
+
import { OptionsRepository } from "#db/repositories/options.js";
|
|
17
|
+
|
|
18
|
+
export const POST: APIRoute = async ({ locals }) => {
|
|
19
|
+
if (!import.meta.env.DEV) {
|
|
20
|
+
return apiError("FORBIDDEN", "Dev reset is only available in development mode", 403);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const { emdash } = locals;
|
|
24
|
+
|
|
25
|
+
if (!emdash?.db) {
|
|
26
|
+
return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const options = new OptionsRepository(emdash.db);
|
|
31
|
+
|
|
32
|
+
await options.delete("emdash:setup_complete");
|
|
33
|
+
await options.delete("emdash:setup_state");
|
|
34
|
+
await emdash.db.deleteFrom("users").execute();
|
|
35
|
+
|
|
36
|
+
return apiSuccess({ success: true });
|
|
37
|
+
} catch (error) {
|
|
38
|
+
return handleError(error, "Dev reset failed", "DEV_RESET_ERROR");
|
|
39
|
+
}
|
|
40
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* POST /_emdash/api/setup
|
|
3
|
+
*
|
|
4
|
+
* Executes the setup wizard - applies seed file and marks setup complete
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { APIRoute } from "astro";
|
|
8
|
+
|
|
9
|
+
export const prerender = false;
|
|
10
|
+
|
|
11
|
+
import { apiError, apiSuccess, handleError } from "#api/error.js";
|
|
12
|
+
import { isParseError, parseBody } from "#api/parse.js";
|
|
13
|
+
import { setupBody } from "#api/schemas.js";
|
|
14
|
+
import { getAuthMode } from "#auth/mode.js";
|
|
15
|
+
import { runMigrations } from "#db/migrations/runner.js";
|
|
16
|
+
import { OptionsRepository } from "#db/repositories/options.js";
|
|
17
|
+
import { applySeed } from "#seed/apply.js";
|
|
18
|
+
import { loadSeed } from "#seed/load.js";
|
|
19
|
+
import { validateSeed } from "#seed/validate.js";
|
|
20
|
+
|
|
21
|
+
export const POST: APIRoute = async ({ request, locals }) => {
|
|
22
|
+
const { emdash } = locals;
|
|
23
|
+
|
|
24
|
+
if (!emdash?.db) {
|
|
25
|
+
return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
// Guard: reject if setup has already been completed.
|
|
30
|
+
// The options table may not exist on first-ever setup (pre-migration),
|
|
31
|
+
// so a query failure means setup hasn't run yet — allow it to proceed.
|
|
32
|
+
try {
|
|
33
|
+
const options = new OptionsRepository(emdash.db);
|
|
34
|
+
const setupComplete = await options.get("emdash:setup_complete");
|
|
35
|
+
|
|
36
|
+
if (setupComplete === true || setupComplete === "true") {
|
|
37
|
+
return apiError("ALREADY_CONFIGURED", "Setup has already been completed", 409);
|
|
38
|
+
}
|
|
39
|
+
} catch {
|
|
40
|
+
// Options table doesn't exist yet — first-ever setup, allow it
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Parse request body
|
|
44
|
+
const body = await parseBody(request, setupBody);
|
|
45
|
+
if (isParseError(body)) return body;
|
|
46
|
+
|
|
47
|
+
// 1. Run core migrations
|
|
48
|
+
try {
|
|
49
|
+
await runMigrations(emdash.db);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
return handleError(error, "Failed to run database migrations", "MIGRATION_ERROR");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 2. Load seed file (user seed or built-in default)
|
|
55
|
+
const seed = await loadSeed();
|
|
56
|
+
|
|
57
|
+
// 3. Override seed settings with form values
|
|
58
|
+
seed.settings = {
|
|
59
|
+
...seed.settings,
|
|
60
|
+
title: body.title,
|
|
61
|
+
tagline: body.tagline,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// 4. Apply seed
|
|
65
|
+
const validation = validateSeed(seed);
|
|
66
|
+
if (!validation.valid) {
|
|
67
|
+
return apiError("INVALID_SEED", `Invalid seed file: ${validation.errors.join(", ")}`, 400);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let result;
|
|
71
|
+
try {
|
|
72
|
+
result = await applySeed(emdash.db, seed, {
|
|
73
|
+
includeContent: body.includeContent,
|
|
74
|
+
onConflict: "skip",
|
|
75
|
+
storage: emdash.storage ?? undefined,
|
|
76
|
+
});
|
|
77
|
+
} catch (error) {
|
|
78
|
+
return handleError(error, "Failed to apply seed", "SEED_ERROR");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// 5. Store setup state
|
|
82
|
+
// In external auth mode, mark setup complete immediately (first user to login becomes admin)
|
|
83
|
+
// In passkey mode, setup_complete is set after admin user is created
|
|
84
|
+
const authMode = getAuthMode(emdash.config);
|
|
85
|
+
const useExternalAuth = authMode.type === "external";
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
const options = new OptionsRepository(emdash.db);
|
|
89
|
+
|
|
90
|
+
// Store the canonical site URL from the setup request.
|
|
91
|
+
// This is trusted because setup runs on the real domain.
|
|
92
|
+
const siteUrl = new URL(request.url).origin;
|
|
93
|
+
await options.set("emdash:site_url", siteUrl);
|
|
94
|
+
|
|
95
|
+
if (useExternalAuth) {
|
|
96
|
+
// External auth mode: mark setup complete now
|
|
97
|
+
// First user to log in via external provider will become admin
|
|
98
|
+
await options.set("emdash:setup_complete", true);
|
|
99
|
+
await options.set("emdash:site_title", body.title);
|
|
100
|
+
if (body.tagline) {
|
|
101
|
+
await options.set("emdash:site_tagline", body.tagline);
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
// Passkey mode: store state for next step (admin creation)
|
|
105
|
+
await options.set("emdash:setup_state", {
|
|
106
|
+
step: "site_complete",
|
|
107
|
+
title: body.title,
|
|
108
|
+
tagline: body.tagline,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
} catch (error) {
|
|
112
|
+
console.error("Failed to save setup state:", error);
|
|
113
|
+
// Non-fatal - continue anyway
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 6. Return success with result
|
|
117
|
+
return apiSuccess({
|
|
118
|
+
success: true,
|
|
119
|
+
// In external auth mode, setup is complete - redirect to admin
|
|
120
|
+
setupComplete: useExternalAuth,
|
|
121
|
+
result,
|
|
122
|
+
});
|
|
123
|
+
} catch (error) {
|
|
124
|
+
return handleError(error, "Setup failed", "SETUP_ERROR");
|
|
125
|
+
}
|
|
126
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GET /_emdash/api/setup/status
|
|
3
|
+
*
|
|
4
|
+
* Returns setup status and seed file information
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { APIRoute } from "astro";
|
|
8
|
+
|
|
9
|
+
export const prerender = false;
|
|
10
|
+
|
|
11
|
+
import { apiError, apiSuccess, handleError } from "#api/error.js";
|
|
12
|
+
import { getAuthMode } from "#auth/mode.js";
|
|
13
|
+
import { loadUserSeed } from "#seed/load.js";
|
|
14
|
+
|
|
15
|
+
export const GET: APIRoute = async ({ locals }) => {
|
|
16
|
+
const { emdash } = locals;
|
|
17
|
+
|
|
18
|
+
if (!emdash?.db) {
|
|
19
|
+
return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
// Check if setup is complete
|
|
24
|
+
const setupComplete = await emdash.db
|
|
25
|
+
.selectFrom("options")
|
|
26
|
+
.select("value")
|
|
27
|
+
.where("name", "=", "emdash:setup_complete")
|
|
28
|
+
.executeTakeFirst();
|
|
29
|
+
|
|
30
|
+
// Value is JSON-encoded, parse it. Accepts both boolean true and string "true"
|
|
31
|
+
const isComplete =
|
|
32
|
+
setupComplete &&
|
|
33
|
+
(() => {
|
|
34
|
+
try {
|
|
35
|
+
const parsed = JSON.parse(setupComplete.value);
|
|
36
|
+
return parsed === true || parsed === "true";
|
|
37
|
+
} catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
})();
|
|
41
|
+
|
|
42
|
+
// Also check if users exist
|
|
43
|
+
let hasUsers = false;
|
|
44
|
+
try {
|
|
45
|
+
const userCount = await emdash.db
|
|
46
|
+
.selectFrom("users")
|
|
47
|
+
.select((eb) => eb.fn.countAll<number>().as("count"))
|
|
48
|
+
.executeTakeFirstOrThrow();
|
|
49
|
+
hasUsers = userCount.count > 0;
|
|
50
|
+
} catch {
|
|
51
|
+
// Users table might not exist yet
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Setup is complete only if flag is set AND users exist
|
|
55
|
+
if (isComplete && hasUsers) {
|
|
56
|
+
return apiSuccess({
|
|
57
|
+
needsSetup: false,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Determine current step
|
|
62
|
+
// step: "start" | "site" | "admin" | "complete"
|
|
63
|
+
let step: "start" | "site" | "admin" = "start";
|
|
64
|
+
|
|
65
|
+
// Get setup state if it exists
|
|
66
|
+
const setupState = await emdash.db
|
|
67
|
+
.selectFrom("options")
|
|
68
|
+
.select("value")
|
|
69
|
+
.where("name", "=", "emdash:setup_state")
|
|
70
|
+
.executeTakeFirst();
|
|
71
|
+
|
|
72
|
+
if (setupState) {
|
|
73
|
+
try {
|
|
74
|
+
const state = JSON.parse(setupState.value);
|
|
75
|
+
if (state.step === "admin") {
|
|
76
|
+
step = "admin";
|
|
77
|
+
} else if (state.step === "site") {
|
|
78
|
+
step = "site";
|
|
79
|
+
}
|
|
80
|
+
} catch {
|
|
81
|
+
// Invalid state, stay at start
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// If setup_complete but no users, jump to admin step
|
|
86
|
+
if (isComplete && !hasUsers) {
|
|
87
|
+
step = "admin";
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Check auth mode
|
|
91
|
+
const authMode = getAuthMode(emdash.config);
|
|
92
|
+
const useExternalAuth = authMode.type === "external";
|
|
93
|
+
|
|
94
|
+
// In external auth mode, setup is complete if flag is set (no users required initially)
|
|
95
|
+
if (useExternalAuth && isComplete) {
|
|
96
|
+
return apiSuccess({
|
|
97
|
+
needsSetup: false,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Setup needed - try to load seed file info
|
|
102
|
+
const seed = await loadUserSeed();
|
|
103
|
+
const seedInfo = seed
|
|
104
|
+
? {
|
|
105
|
+
name: seed.meta?.name || "Unknown Template",
|
|
106
|
+
description: seed.meta?.description || "",
|
|
107
|
+
collections: seed.collections?.length || 0,
|
|
108
|
+
hasContent: !!(seed.content && Object.keys(seed.content).length > 0),
|
|
109
|
+
}
|
|
110
|
+
: null;
|
|
111
|
+
|
|
112
|
+
return apiSuccess({
|
|
113
|
+
needsSetup: true,
|
|
114
|
+
step,
|
|
115
|
+
seedInfo,
|
|
116
|
+
// Tell the wizard which auth mode is active
|
|
117
|
+
authMode: useExternalAuth ? authMode.providerType : "passkey",
|
|
118
|
+
});
|
|
119
|
+
} catch (error) {
|
|
120
|
+
return handleError(error, "Failed to check setup status", "SETUP_STATUS_ERROR");
|
|
121
|
+
}
|
|
122
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Snapshot endpoint — exports a portable database snapshot for preview mode.
|
|
3
|
+
*
|
|
4
|
+
* Security:
|
|
5
|
+
* - Authenticated users: requires content:read + schema:read permissions
|
|
6
|
+
* - Preview services: requires valid X-Preview-Signature header (HMAC-SHA256)
|
|
7
|
+
* - Excludes auth/user/session/token tables
|
|
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 {
|
|
15
|
+
generateSnapshot,
|
|
16
|
+
parsePreviewSignatureHeader,
|
|
17
|
+
verifyPreviewSignature,
|
|
18
|
+
} from "#api/handlers/snapshot.js";
|
|
19
|
+
|
|
20
|
+
export const prerender = false;
|
|
21
|
+
|
|
22
|
+
export const GET: APIRoute = async ({ request, locals, url }) => {
|
|
23
|
+
const { emdash, user } = locals;
|
|
24
|
+
|
|
25
|
+
if (!emdash?.db) {
|
|
26
|
+
return apiError("NOT_CONFIGURED", "EmDash is not initialized", 500);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Check for preview signature auth (used by DO preview services)
|
|
30
|
+
const previewSig = request.headers.get("X-Preview-Signature");
|
|
31
|
+
let authorized = false;
|
|
32
|
+
|
|
33
|
+
if (previewSig) {
|
|
34
|
+
const secret = import.meta.env.EMDASH_PREVIEW_SECRET || import.meta.env.PREVIEW_SECRET || "";
|
|
35
|
+
if (!secret) {
|
|
36
|
+
console.warn(
|
|
37
|
+
"[snapshot] X-Preview-Signature header present but no PREVIEW_SECRET configured",
|
|
38
|
+
);
|
|
39
|
+
} else {
|
|
40
|
+
const parsed = parsePreviewSignatureHeader(previewSig);
|
|
41
|
+
if (!parsed) {
|
|
42
|
+
console.warn("[snapshot] Failed to parse X-Preview-Signature header");
|
|
43
|
+
} else {
|
|
44
|
+
authorized = await verifyPreviewSignature(parsed.source, parsed.exp, parsed.sig, secret);
|
|
45
|
+
if (!authorized) {
|
|
46
|
+
console.warn("[snapshot] Preview signature verification failed", {
|
|
47
|
+
source: parsed.source,
|
|
48
|
+
exp: parsed.exp,
|
|
49
|
+
expired: parsed.exp < Date.now() / 1000,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!authorized) {
|
|
57
|
+
// Fall back to standard user auth
|
|
58
|
+
const contentDenied = requirePerm(user, "content:read");
|
|
59
|
+
if (contentDenied) return contentDenied;
|
|
60
|
+
const schemaDenied = requirePerm(user, "schema:read");
|
|
61
|
+
if (schemaDenied) return schemaDenied;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const includeDrafts = url.searchParams.get("drafts") === "true";
|
|
66
|
+
const snapshot = await generateSnapshot(emdash.db, {
|
|
67
|
+
includeDrafts,
|
|
68
|
+
origin: url.origin,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return apiSuccess(snapshot);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
return handleError(error, "Failed to generate snapshot", "SNAPSHOT_ERROR");
|
|
74
|
+
}
|
|
75
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single term endpoint
|
|
3
|
+
*
|
|
4
|
+
* GET /_emdash/api/taxonomies/:name/terms/:slug - Get a single term
|
|
5
|
+
* PUT /_emdash/api/taxonomies/:name/terms/:slug - Update a term
|
|
6
|
+
* DELETE /_emdash/api/taxonomies/:name/terms/:slug - Delete a term
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { APIRoute } from "astro";
|
|
10
|
+
|
|
11
|
+
import { requirePerm } from "#api/authorize.js";
|
|
12
|
+
import { apiError, handleError, requireDb, unwrapResult } from "#api/error.js";
|
|
13
|
+
import { handleTermDelete, handleTermGet, handleTermUpdate } from "#api/handlers/taxonomies.js";
|
|
14
|
+
import { isParseError, parseBody } from "#api/parse.js";
|
|
15
|
+
import { updateTermBody } from "#api/schemas.js";
|
|
16
|
+
|
|
17
|
+
export const prerender = false;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get a single term
|
|
21
|
+
*/
|
|
22
|
+
export const GET: APIRoute = async ({ params, locals }) => {
|
|
23
|
+
const { emdash, user } = locals;
|
|
24
|
+
const { name, slug } = params;
|
|
25
|
+
|
|
26
|
+
if (!name || !slug) {
|
|
27
|
+
return apiError("VALIDATION_ERROR", "Taxonomy name and slug required", 400);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const dbErr = requireDb(emdash?.db);
|
|
31
|
+
if (dbErr) return dbErr;
|
|
32
|
+
|
|
33
|
+
const denied = requirePerm(user, "taxonomies:read");
|
|
34
|
+
if (denied) return denied;
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
const result = await handleTermGet(emdash.db, name, slug);
|
|
38
|
+
return unwrapResult(result);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
return handleError(error, "Failed to get term", "TERM_GET_ERROR");
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Update a term
|
|
46
|
+
*/
|
|
47
|
+
export const PUT: APIRoute = async ({ params, request, locals }) => {
|
|
48
|
+
const { emdash, user } = locals;
|
|
49
|
+
const { name, slug } = params;
|
|
50
|
+
|
|
51
|
+
if (!name || !slug) {
|
|
52
|
+
return apiError("VALIDATION_ERROR", "Taxonomy name and slug required", 400);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const dbErr = requireDb(emdash?.db);
|
|
56
|
+
if (dbErr) return dbErr;
|
|
57
|
+
|
|
58
|
+
const denied = requirePerm(user, "taxonomies:manage");
|
|
59
|
+
if (denied) return denied;
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
const body = await parseBody(request, updateTermBody);
|
|
63
|
+
if (isParseError(body)) return body;
|
|
64
|
+
|
|
65
|
+
const result = await handleTermUpdate(emdash.db, name, slug, body);
|
|
66
|
+
return unwrapResult(result);
|
|
67
|
+
} catch (error) {
|
|
68
|
+
return handleError(error, "Failed to update term", "TERM_UPDATE_ERROR");
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Delete a term
|
|
74
|
+
*/
|
|
75
|
+
export const DELETE: APIRoute = async ({ params, locals }) => {
|
|
76
|
+
const { emdash, user } = locals;
|
|
77
|
+
const { name, slug } = params;
|
|
78
|
+
|
|
79
|
+
if (!name || !slug) {
|
|
80
|
+
return apiError("VALIDATION_ERROR", "Taxonomy name and slug required", 400);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const dbErr = requireDb(emdash?.db);
|
|
84
|
+
if (dbErr) return dbErr;
|
|
85
|
+
|
|
86
|
+
const denied = requirePerm(user, "taxonomies:manage");
|
|
87
|
+
if (denied) return denied;
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const result = await handleTermDelete(emdash.db, name, slug);
|
|
91
|
+
return unwrapResult(result);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
return handleError(error, "Failed to delete term", "TERM_DELETE_ERROR");
|
|
94
|
+
}
|
|
95
|
+
};
|