emdash 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{adapters-Di31kZ28.d.mts → adapters-DoNJiveC.d.mts} +1 -1
- package/dist/{adapters-Di31kZ28.d.mts.map → adapters-DoNJiveC.d.mts.map} +1 -1
- package/dist/{apply-5uslYdUu.mjs → apply-BzltprvY.mjs} +90 -139
- package/dist/apply-BzltprvY.mjs.map +1 -0
- package/dist/astro/index.d.mts +6 -6
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +194 -17
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +6 -7
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +34 -57
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/redirect.d.mts.map +1 -1
- package/dist/astro/middleware/redirect.mjs +17 -12
- package/dist/astro/middleware/redirect.mjs.map +1 -1
- package/dist/astro/middleware/request-context.d.mts.map +1 -1
- package/dist/astro/middleware/request-context.mjs +9 -6
- package/dist/astro/middleware/request-context.mjs.map +1 -1
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +301 -165
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/types.d.mts +34 -10
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/{base64-MBPo9ozB.mjs → base64-BRICGH2l.mjs} +1 -1
- package/dist/{base64-MBPo9ozB.mjs.map → base64-BRICGH2l.mjs.map} +1 -1
- package/dist/{byline-C4OVd8b3.mjs → byline-BSaNL1w7.mjs} +5 -5
- package/dist/byline-BSaNL1w7.mjs.map +1 -0
- package/dist/bylines-CvJ3PYz2.mjs +113 -0
- package/dist/bylines-CvJ3PYz2.mjs.map +1 -0
- package/dist/cache-C6N_hhN7.mjs +65 -0
- package/dist/cache-C6N_hhN7.mjs.map +1 -0
- package/dist/{chunks-HGz06Soa.mjs → chunks-NBQVDOci.mjs} +8 -2
- package/dist/{chunks-HGz06Soa.mjs.map → chunks-NBQVDOci.mjs.map} +1 -1
- package/dist/cli/index.mjs +229 -31
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/cf-access.d.mts +1 -1
- package/dist/client/index.d.mts +1 -1
- package/dist/client/index.mjs +3 -3
- package/dist/client/index.mjs.map +1 -1
- package/dist/{config-BXwuX8Bx.mjs → config-BI0V3ICQ.mjs} +1 -1
- package/dist/{config-BXwuX8Bx.mjs.map → config-BI0V3ICQ.mjs.map} +1 -1
- package/dist/{content-D7J5y73J.mjs → content-8lOYF0pr.mjs} +43 -28
- package/dist/content-8lOYF0pr.mjs.map +1 -0
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +2 -2
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/libsql.d.mts.map +1 -1
- package/dist/db/libsql.mjs +7 -2
- package/dist/db/libsql.mjs.map +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/db/sqlite.d.mts.map +1 -1
- package/dist/db/sqlite.mjs +8 -3
- package/dist/db/sqlite.mjs.map +1 -1
- package/dist/{db-errors-D0UT85nC.mjs → db-errors-WRezodiz.mjs} +1 -1
- package/dist/{db-errors-D0UT85nC.mjs.map → db-errors-WRezodiz.mjs.map} +1 -1
- package/dist/{default-CME5YdZ3.mjs → default-D8ksjWhO.mjs} +1 -1
- package/dist/{default-CME5YdZ3.mjs.map → default-D8ksjWhO.mjs.map} +1 -1
- package/dist/{dialect-helpers-DhTzaUxP.mjs → dialect-helpers-BKCvISIQ.mjs} +19 -2
- package/dist/dialect-helpers-BKCvISIQ.mjs.map +1 -0
- package/dist/{error-CiYn9yDu.mjs → error-D_-tqP-I.mjs} +1 -1
- package/dist/error-D_-tqP-I.mjs.map +1 -0
- package/dist/{index-De6_Xv3v.d.mts → index-BFRaVcD6.d.mts} +243 -40
- package/dist/index-BFRaVcD6.d.mts.map +1 -0
- package/dist/index.d.mts +11 -11
- package/dist/index.mjs +29 -25
- package/dist/{load-CBcmDIot.mjs → load-DDqMMvZL.mjs} +2 -2
- package/dist/{load-CBcmDIot.mjs.map → load-DDqMMvZL.mjs.map} +1 -1
- package/dist/{loader-DeiBJEMe.mjs → loader-CKLbBnhK.mjs} +32 -10
- package/dist/loader-CKLbBnhK.mjs.map +1 -0
- package/dist/{manifest-schema-V30qsMft.mjs → manifest-schema-DqWNC3lM.mjs} +45 -3
- package/dist/manifest-schema-DqWNC3lM.mjs.map +1 -0
- package/dist/media/index.d.mts +1 -1
- package/dist/media/index.mjs +1 -1
- package/dist/media/local-runtime.d.mts +7 -7
- package/dist/media/local-runtime.mjs +3 -3
- package/dist/{media-DqHVh136.mjs → media-BW32b4gi.mjs} +4 -7
- package/dist/media-BW32b4gi.mjs.map +1 -0
- package/dist/{mode-CpNnGkPz.mjs → mode-ier8jbBk.mjs} +1 -1
- package/dist/mode-ier8jbBk.mjs.map +1 -0
- package/dist/options-BVp3UsTS.mjs +117 -0
- package/dist/options-BVp3UsTS.mjs.map +1 -0
- package/dist/page/index.d.mts +2 -2
- package/dist/{placeholder-tzpqGWII.d.mts → placeholder-BE4o_2dc.d.mts} +1 -1
- package/dist/{placeholder-tzpqGWII.d.mts.map → placeholder-BE4o_2dc.d.mts.map} +1 -1
- package/dist/{placeholder-C-fk5hYI.mjs → placeholder-CIJejMlK.mjs} +1 -1
- package/dist/placeholder-CIJejMlK.mjs.map +1 -0
- package/dist/plugins/adapt-sandbox-entry.d.mts +5 -5
- package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
- package/dist/plugins/adapt-sandbox-entry.mjs +6 -5
- package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -1
- package/dist/public-url-DByxYjUw.mjs +51 -0
- package/dist/public-url-DByxYjUw.mjs.map +1 -0
- package/dist/{query-g4Ug-9j9.mjs → query-Cg9ZKRQ0.mjs} +114 -16
- package/dist/query-Cg9ZKRQ0.mjs.map +1 -0
- package/dist/{redirect-CN0Rt9Ob.mjs → redirect-BhUBKRc1.mjs} +13 -8
- package/dist/redirect-BhUBKRc1.mjs.map +1 -0
- package/dist/{registry-Ci3WxVAr.mjs → registry-Dw70ChxB.mjs} +69 -11
- package/dist/registry-Dw70ChxB.mjs.map +1 -0
- package/dist/{request-cache-DiR961CV.mjs → request-cache-B-bmkipQ.mjs} +1 -1
- package/dist/request-cache-B-bmkipQ.mjs.map +1 -0
- package/dist/runner-Bnoj7vjK.d.mts +44 -0
- package/dist/runner-Bnoj7vjK.d.mts.map +1 -0
- package/dist/{runner-tQ7BJ4T7.mjs → runner-C7ADox5q.mjs} +185 -55
- package/dist/{runner-tQ7BJ4T7.mjs.map → runner-C7ADox5q.mjs.map} +1 -1
- package/dist/runtime.d.mts +6 -6
- package/dist/runtime.mjs +4 -4
- package/dist/{search-B0effn3j.mjs → search-dOGEccMa.mjs} +341 -152
- package/dist/search-dOGEccMa.mjs.map +1 -0
- package/dist/secrets-CW3reAnU.mjs +314 -0
- package/dist/secrets-CW3reAnU.mjs.map +1 -0
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +15 -14
- package/dist/seo/index.d.mts +1 -1
- package/dist/storage/local.d.mts +1 -1
- package/dist/storage/local.mjs +1 -1
- package/dist/storage/s3.d.mts +1 -1
- package/dist/storage/s3.d.mts.map +1 -1
- package/dist/storage/s3.mjs +4 -4
- package/dist/storage/s3.mjs.map +1 -1
- package/dist/{taxonomies-K2z0Uhnj.mjs → taxonomies-ZlRtD6AG.mjs} +14 -7
- package/dist/taxonomies-ZlRtD6AG.mjs.map +1 -0
- package/dist/{tokens-BFPFx3CA.mjs → tokens-D7zMmWi2.mjs} +2 -2
- package/dist/{tokens-BFPFx3CA.mjs.map → tokens-D7zMmWi2.mjs.map} +1 -1
- package/dist/{transport-BykRfpyy.mjs → transport-BeMCmin1.mjs} +6 -5
- package/dist/{transport-BykRfpyy.mjs.map → transport-BeMCmin1.mjs.map} +1 -1
- package/dist/{transport-H4Iwx7tC.d.mts → transport-DNEfeMaU.d.mts} +1 -1
- package/dist/{transport-H4Iwx7tC.d.mts.map → transport-DNEfeMaU.d.mts.map} +1 -1
- package/dist/types-4fVtCIm0.mjs +68 -0
- package/dist/types-4fVtCIm0.mjs.map +1 -0
- package/dist/{types-CnZYHyLW.d.mts → types-BSyXeCFW.d.mts} +24 -2
- package/dist/{types-CnZYHyLW.d.mts.map → types-BSyXeCFW.d.mts.map} +1 -1
- package/dist/{types-DgrIP0tF.d.mts → types-BuBIptGk.d.mts} +80 -106
- package/dist/types-BuBIptGk.d.mts.map +1 -0
- package/dist/{types-BH2L167P.mjs → types-CDbKp7ND.mjs} +1 -1
- package/dist/{types-BH2L167P.mjs.map → types-CDbKp7ND.mjs.map} +1 -1
- package/dist/{types-DDS4MxsT.mjs → types-CIOg5AR8.mjs} +1 -1
- package/dist/{types-DDS4MxsT.mjs.map → types-CIOg5AR8.mjs.map} +1 -1
- package/dist/{types-6CUZRrZP.d.mts → types-CJsYGpco.d.mts} +24 -2
- package/dist/{types-6CUZRrZP.d.mts.map → types-CJsYGpco.d.mts.map} +1 -1
- package/dist/types-CRxNbK-Z.mjs +68 -0
- package/dist/types-CRxNbK-Z.mjs.map +1 -0
- package/dist/{types-C2v0c34j.d.mts → types-CrtWgIvl.d.mts} +1 -1
- package/dist/{types-C2v0c34j.d.mts.map → types-CrtWgIvl.d.mts.map} +1 -1
- package/dist/{types-CFWjXmus.d.mts → types-M78DQ1lx.d.mts} +1 -1
- package/dist/{types-CFWjXmus.d.mts.map → types-M78DQ1lx.d.mts.map} +1 -1
- package/dist/{validate-CqsNItbt.mjs → validate-Baqf0slj.mjs} +3 -3
- package/dist/{validate-CqsNItbt.mjs.map → validate-Baqf0slj.mjs.map} +1 -1
- package/dist/{validate-kM8Pjuf7.d.mts → validate-BfQh_C_y.d.mts} +4 -4
- package/dist/{validate-kM8Pjuf7.d.mts.map → validate-BfQh_C_y.d.mts.map} +1 -1
- package/dist/validation-BfEI7tNe.mjs +144 -0
- package/dist/validation-BfEI7tNe.mjs.map +1 -0
- package/dist/version-DoxrVdYf.mjs +7 -0
- package/dist/{version-BnTKdfam.mjs.map → version-DoxrVdYf.mjs.map} +1 -1
- package/dist/zod-generator-CC0xNe_K.mjs +132 -0
- package/dist/zod-generator-CC0xNe_K.mjs.map +1 -0
- package/locals.d.ts +1 -6
- package/package.json +21 -7
- package/src/api/auth-storage.ts +37 -0
- package/src/api/error.ts +6 -0
- package/src/api/errors.ts +8 -0
- package/src/api/handlers/comments.ts +19 -4
- package/src/api/handlers/content.ts +151 -4
- package/src/api/handlers/device-flow.ts +5 -0
- package/src/api/handlers/index.ts +2 -0
- package/src/api/handlers/marketplace.ts +11 -4
- package/src/api/handlers/media.ts +8 -1
- package/src/api/handlers/menus.ts +160 -21
- package/src/api/handlers/oauth-authorization.ts +72 -33
- package/src/api/handlers/redirects.ts +16 -3
- package/src/api/handlers/revision.ts +23 -14
- package/src/api/handlers/sections.ts +8 -1
- package/src/api/handlers/taxonomies.ts +131 -22
- package/src/api/handlers/validation.ts +212 -0
- package/src/api/openapi/document.ts +4 -1
- package/src/api/public-url.ts +54 -5
- package/src/api/route-utils.ts +14 -0
- package/src/api/schemas/comments.ts +2 -2
- package/src/api/schemas/common.ts +1 -1
- package/src/api/schemas/content.ts +17 -0
- package/src/api/schemas/sections.ts +3 -3
- package/src/api/schemas/setup.ts +8 -0
- package/src/api/schemas/users.ts +1 -1
- package/src/api/schemas/widgets.ts +12 -10
- package/src/api/setup-complete.ts +40 -0
- package/src/api/types.ts +5 -1
- package/src/astro/integration/index.ts +30 -2
- package/src/astro/integration/routes.ts +28 -0
- package/src/astro/integration/runtime.ts +49 -1
- package/src/astro/integration/virtual-modules.ts +73 -2
- package/src/astro/integration/vite-config.ts +49 -13
- package/src/astro/middleware/auth.ts +34 -6
- package/src/astro/middleware/redirect.ts +29 -16
- package/src/astro/middleware/request-context.ts +15 -5
- package/src/astro/middleware.ts +41 -10
- package/src/astro/routes/PluginRegistry.tsx +10 -1
- package/src/astro/routes/api/auth/invite/complete.ts +6 -1
- package/src/astro/routes/api/auth/mode.ts +57 -0
- package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +23 -3
- package/src/astro/routes/api/auth/oauth/[provider].ts +10 -4
- package/src/astro/routes/api/auth/passkey/register/verify.ts +6 -1
- package/src/astro/routes/api/auth/passkey/verify.ts +6 -1
- package/src/astro/routes/api/auth/signup/complete.ts +6 -1
- package/src/astro/routes/api/comments/[collection]/[contentId]/index.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +4 -2
- package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +34 -12
- package/src/astro/routes/api/content/[collection]/[id]/publish.ts +32 -2
- package/src/astro/routes/api/content/[collection]/[id]/restore.ts +4 -2
- package/src/astro/routes/api/content/[collection]/[id]/revisions.ts +3 -2
- package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +8 -4
- package/src/astro/routes/api/content/[collection]/[id]/translations.ts +1 -1
- package/src/astro/routes/api/content/[collection]/[id].ts +12 -0
- package/src/astro/routes/api/content/[collection]/index.ts +1 -9
- package/src/astro/routes/api/import/wordpress/execute.ts +3 -1
- package/src/astro/routes/api/import/wordpress/media.ts +2 -7
- package/src/astro/routes/api/import/wordpress/prepare.ts +9 -0
- package/src/astro/routes/api/import/wordpress-plugin/execute.ts +3 -1
- package/src/astro/routes/api/manifest.ts +62 -45
- package/src/astro/routes/api/media/[id]/confirm.ts +10 -1
- package/src/astro/routes/api/media/providers/[providerId]/index.ts +12 -3
- package/src/astro/routes/api/openapi.json.ts +27 -10
- package/src/astro/routes/api/redirects/404s/index.ts +10 -4
- package/src/astro/routes/api/redirects/404s/summary.ts +4 -2
- package/src/astro/routes/api/redirects/[id].ts +10 -4
- package/src/astro/routes/api/redirects/index.ts +7 -3
- package/src/astro/routes/api/revisions/[revisionId]/index.ts +1 -1
- package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +0 -2
- package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +0 -1
- package/src/astro/routes/api/schema/collections/[slug]/fields/reorder.ts +0 -1
- package/src/astro/routes/api/schema/collections/[slug]/index.ts +2 -2
- package/src/astro/routes/api/schema/collections/index.ts +1 -1
- package/src/astro/routes/api/search/index.ts +10 -2
- package/src/astro/routes/api/sections/[slug].ts +10 -4
- package/src/astro/routes/api/sections/index.ts +7 -3
- package/src/astro/routes/api/settings/email.ts +4 -9
- package/src/astro/routes/api/setup/admin-verify.ts +6 -1
- package/src/astro/routes/api/setup/admin.ts +8 -2
- package/src/astro/routes/api/setup/index.ts +2 -2
- package/src/astro/routes/api/setup/status.ts +3 -1
- package/src/astro/routes/api/snapshot.ts +44 -18
- package/src/astro/routes/api/taxonomies/index.ts +0 -1
- package/src/astro/routes/api/themes/preview.ts +11 -5
- package/src/astro/routes/api/widget-areas/[name]/widgets/[id].ts +4 -1
- package/src/astro/routes/api/widget-areas/[name]/widgets.ts +4 -1
- package/src/astro/routes/api/widget-areas/[name].ts +4 -1
- package/src/astro/routes/api/widget-areas/index.ts +4 -1
- package/src/astro/types.ts +32 -3
- package/src/auth/allowed-origins.ts +168 -0
- package/src/auth/mode.ts +15 -3
- package/src/auth/passkey-config.ts +35 -13
- package/src/auth/providers/github-admin.tsx +29 -0
- package/src/auth/providers/github.ts +31 -0
- package/src/auth/providers/google-admin.tsx +44 -0
- package/src/auth/providers/google.ts +31 -0
- package/src/auth/types.ts +114 -4
- package/src/bylines/index.ts +37 -88
- package/src/cli/commands/auth.ts +28 -6
- package/src/cli/commands/bundle-utils.ts +11 -2
- package/src/cli/commands/bundle.ts +31 -9
- package/src/cli/commands/content.ts +13 -0
- package/src/cli/commands/login.ts +8 -1
- package/src/cli/commands/publish.ts +24 -0
- package/src/cli/commands/secrets.ts +183 -0
- package/src/cli/credentials.ts +1 -1
- package/src/cli/index.ts +5 -1
- package/src/client/index.ts +4 -4
- package/src/client/transport.ts +17 -7
- package/src/components/Break.astro +2 -2
- package/src/components/EmDashHead.astro +18 -13
- package/src/components/EmDashImage.astro +7 -6
- package/src/components/Embed.astro +1 -1
- package/src/components/Gallery.astro +6 -4
- package/src/components/Image.astro +9 -4
- package/src/components/InlinePortableTextEditor.tsx +106 -19
- package/src/components/LiveSearch.astro +5 -14
- package/src/config/secrets.ts +528 -0
- package/src/database/dialect-helpers.ts +50 -0
- package/src/database/migrations/034_published_at_index.ts +1 -1
- package/src/database/migrations/035_bounded_404_log.ts +56 -39
- package/src/database/migrations/runner.ts +156 -23
- package/src/database/repositories/audit.ts +6 -8
- package/src/database/repositories/byline.ts +6 -8
- package/src/database/repositories/comment.ts +12 -16
- package/src/database/repositories/content.ts +76 -52
- package/src/database/repositories/index.ts +1 -1
- package/src/database/repositories/media.ts +10 -13
- package/src/database/repositories/plugin-storage.ts +4 -6
- package/src/database/repositories/redirect.ts +26 -19
- package/src/database/repositories/taxonomy.ts +40 -3
- package/src/database/repositories/types.ts +57 -8
- package/src/database/repositories/user.ts +6 -8
- package/src/db/libsql.ts +1 -3
- package/src/db/sqlite.ts +2 -5
- package/src/emdash-runtime.ts +388 -247
- package/src/index.ts +14 -1
- package/src/loader.ts +30 -6
- package/src/mcp/server.ts +781 -141
- package/src/media/normalize.ts +1 -1
- package/src/media/url.ts +78 -0
- package/src/page/site-identity.ts +58 -0
- package/src/plugins/adapt-sandbox-entry.ts +22 -10
- package/src/plugins/context.ts +13 -10
- package/src/plugins/define-plugin.ts +40 -12
- package/src/plugins/email-console.ts +10 -3
- package/src/plugins/hooks.ts +34 -19
- package/src/plugins/index.ts +9 -0
- package/src/plugins/manifest-schema.ts +49 -2
- package/src/plugins/types.ts +174 -13
- package/src/preview/urls.ts +23 -3
- package/src/query.ts +149 -6
- package/src/redirects/cache.ts +38 -18
- package/src/request-cache.ts +3 -0
- package/src/schema/registry.ts +97 -5
- package/src/schema/zod-generator.ts +27 -5
- package/src/search/fts-manager.ts +0 -2
- package/src/search/query.ts +111 -26
- package/src/search/types.ts +8 -1
- package/src/sections/index.ts +7 -9
- package/src/seed/apply.ts +2 -0
- package/src/settings/index.ts +80 -6
- package/src/settings/types.ts +23 -1
- package/src/storage/s3.ts +12 -6
- package/src/taxonomies/index.ts +11 -1
- package/src/virtual-modules.d.ts +21 -1
- package/src/widgets/index.ts +1 -1
- package/dist/apply-5uslYdUu.mjs.map +0 -1
- package/dist/byline-C4OVd8b3.mjs.map +0 -1
- package/dist/bylines-hPTW79hw.mjs +0 -157
- package/dist/bylines-hPTW79hw.mjs.map +0 -1
- package/dist/cache-BkKBuIvS.mjs +0 -56
- package/dist/cache-BkKBuIvS.mjs.map +0 -1
- package/dist/chunk-ClPoSABd.mjs +0 -21
- package/dist/content-D7J5y73J.mjs.map +0 -1
- package/dist/dialect-helpers-DhTzaUxP.mjs.map +0 -1
- package/dist/error-CiYn9yDu.mjs.map +0 -1
- package/dist/index-De6_Xv3v.d.mts.map +0 -1
- package/dist/loader-DeiBJEMe.mjs.map +0 -1
- package/dist/manifest-schema-V30qsMft.mjs.map +0 -1
- package/dist/media-DqHVh136.mjs.map +0 -1
- package/dist/mode-CpNnGkPz.mjs.map +0 -1
- package/dist/placeholder-C-fk5hYI.mjs.map +0 -1
- package/dist/query-g4Ug-9j9.mjs.map +0 -1
- package/dist/redirect-CN0Rt9Ob.mjs.map +0 -1
- package/dist/registry-Ci3WxVAr.mjs.map +0 -1
- package/dist/request-cache-DiR961CV.mjs.map +0 -1
- package/dist/runner-BR2xKwhn.d.mts +0 -34
- package/dist/runner-BR2xKwhn.d.mts.map +0 -1
- package/dist/search-B0effn3j.mjs.map +0 -1
- package/dist/taxonomies-K2z0Uhnj.mjs.map +0 -1
- package/dist/types-CMMN0pNg.mjs +0 -31
- package/dist/types-CMMN0pNg.mjs.map +0 -1
- package/dist/types-DgrIP0tF.d.mts.map +0 -1
- package/dist/version-BnTKdfam.mjs +0 -7
|
@@ -98,6 +98,10 @@ export const POST: APIRoute = async ({ params, request, locals }) => {
|
|
|
98
98
|
const editDenied = requireOwnerPerm(user, authorId, "content:edit_own", "content:edit_any");
|
|
99
99
|
if (editDenied) return editDenied;
|
|
100
100
|
|
|
101
|
+
// Resolve the canonical content ID from the handler result.
|
|
102
|
+
// The URL `id` param may be a slug; we must use the real ID for term storage.
|
|
103
|
+
const canonicalId = typeof existingItem?.id === "string" ? existingItem.id : id;
|
|
104
|
+
|
|
101
105
|
try {
|
|
102
106
|
const body = await parseBody(request, contentTermsBody);
|
|
103
107
|
if (isParseError(body)) return body;
|
|
@@ -120,15 +124,15 @@ export const POST: APIRoute = async ({ params, request, locals }) => {
|
|
|
120
124
|
}
|
|
121
125
|
}
|
|
122
126
|
|
|
123
|
-
// Set the terms (replaces existing)
|
|
124
|
-
await repo.setTermsForEntry(collection,
|
|
127
|
+
// Set the terms (replaces existing) using the canonical ID
|
|
128
|
+
await repo.setTermsForEntry(collection, canonicalId, taxonomy, termIds);
|
|
125
129
|
|
|
126
130
|
// Term assignments changed — invalidate the hasAnyTermAssignments cache
|
|
127
131
|
// so hydration on subsequent reads issues a fresh query.
|
|
128
132
|
invalidateTermCache();
|
|
129
133
|
|
|
130
|
-
// Get the updated terms
|
|
131
|
-
const terms = await repo.getTermsForEntry(collection,
|
|
134
|
+
// Get the updated terms using the canonical ID
|
|
135
|
+
const terms = await repo.getTermsForEntry(collection, canonicalId, taxonomy);
|
|
132
136
|
|
|
133
137
|
return apiSuccess({
|
|
134
138
|
terms: terms.map((t) => ({
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Returns all locale variants linked to the same translation group.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { hasPermission
|
|
9
|
+
import { hasPermission } from "@emdash-cms/auth";
|
|
10
10
|
import type { APIRoute } from "astro";
|
|
11
11
|
|
|
12
12
|
import { requirePerm } from "#api/authorize.js";
|
|
@@ -47,6 +47,18 @@ export const GET: APIRoute = async ({ params, url, locals }) => {
|
|
|
47
47
|
if (status !== "published") {
|
|
48
48
|
return apiError("NOT_FOUND", `Content item not found: ${id}`, 404);
|
|
49
49
|
}
|
|
50
|
+
|
|
51
|
+
// Strip draft hydration data from response for users without read_drafts.
|
|
52
|
+
// handleContentGet overlays draft revision data onto item.data and exposes
|
|
53
|
+
// the published values in item.liveData. Without this, subscribers see
|
|
54
|
+
// unpublished edits in the data field.
|
|
55
|
+
if (item) {
|
|
56
|
+
if (item.liveData && typeof item.liveData === "object") {
|
|
57
|
+
item.data = item.liveData;
|
|
58
|
+
}
|
|
59
|
+
delete item.liveData;
|
|
60
|
+
delete item.draftRevisionId;
|
|
61
|
+
}
|
|
50
62
|
}
|
|
51
63
|
|
|
52
64
|
return unwrapResult(result);
|
|
@@ -61,15 +61,7 @@ export const POST: APIRoute = async ({ params, request, locals, cache }) => {
|
|
|
61
61
|
mapErrorStatus(source.error?.code),
|
|
62
62
|
);
|
|
63
63
|
}
|
|
64
|
-
const
|
|
65
|
-
source.data && typeof source.data === "object"
|
|
66
|
-
? (source.data as Record<string, unknown>)
|
|
67
|
-
: undefined;
|
|
68
|
-
const sourceItem =
|
|
69
|
-
sourceData?.item && typeof sourceData.item === "object"
|
|
70
|
-
? (sourceData.item as Record<string, unknown>)
|
|
71
|
-
: sourceData;
|
|
72
|
-
const sourceAuthor = typeof sourceItem?.authorId === "string" ? sourceItem.authorId : "";
|
|
64
|
+
const sourceAuthor = source.data.item.authorId ?? "";
|
|
73
65
|
const translationDenied = requireOwnerPerm(
|
|
74
66
|
user,
|
|
75
67
|
sourceAuthor,
|
|
@@ -60,7 +60,7 @@ export interface ImportResult {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
export const POST: APIRoute = async ({ request, locals }) => {
|
|
63
|
-
const { emdash,
|
|
63
|
+
const { emdash, user } = locals;
|
|
64
64
|
|
|
65
65
|
const denied = requirePerm(user, "import:execute");
|
|
66
66
|
if (denied) return denied;
|
|
@@ -70,6 +70,8 @@ export const POST: APIRoute = async ({ request, locals }) => {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
try {
|
|
73
|
+
const emdashManifest = await emdash.getManifest();
|
|
74
|
+
|
|
73
75
|
const formData = await request.formData();
|
|
74
76
|
const fileEntry = formData.get("file");
|
|
75
77
|
const file = fileEntry instanceof File ? fileEntry : null;
|
|
@@ -92,7 +92,6 @@ export const POST: APIRoute = async ({ request, locals }) => {
|
|
|
92
92
|
attachments,
|
|
93
93
|
emdash.db,
|
|
94
94
|
emdash.storage,
|
|
95
|
-
request.url,
|
|
96
95
|
sendProgress,
|
|
97
96
|
);
|
|
98
97
|
|
|
@@ -117,7 +116,6 @@ export const POST: APIRoute = async ({ request, locals }) => {
|
|
|
117
116
|
attachments,
|
|
118
117
|
emdash.db,
|
|
119
118
|
emdash.storage,
|
|
120
|
-
request.url,
|
|
121
119
|
() => {}, // No-op progress callback
|
|
122
120
|
);
|
|
123
121
|
|
|
@@ -131,12 +129,9 @@ async function importMediaWithProgress(
|
|
|
131
129
|
attachments: AttachmentInfo[],
|
|
132
130
|
db: NonNullable<EmDashHandlers["db"]>,
|
|
133
131
|
storage: NonNullable<EmDashHandlers["storage"]>,
|
|
134
|
-
requestUrl: string,
|
|
135
132
|
onProgress: (progress: MediaImportProgress) => void,
|
|
136
133
|
): Promise<MediaImportResult> {
|
|
137
134
|
const repo = new MediaRepository(db);
|
|
138
|
-
const url = new URL(requestUrl);
|
|
139
|
-
const baseUrl = `${url.protocol}//${url.host}`;
|
|
140
135
|
const total = attachments.length;
|
|
141
136
|
|
|
142
137
|
const result: MediaImportResult = {
|
|
@@ -237,7 +232,7 @@ async function importMediaWithProgress(
|
|
|
237
232
|
const existing = await repo.findByContentHash(contentHash);
|
|
238
233
|
if (existing) {
|
|
239
234
|
// Same content already exists - reuse it
|
|
240
|
-
const existingUrl =
|
|
235
|
+
const existingUrl = `/_emdash/api/media/file/${existing.storageKey}`;
|
|
241
236
|
result.urlMap[attachment.url] = existingUrl;
|
|
242
237
|
result.imported.push({
|
|
243
238
|
wpId: attachment.id,
|
|
@@ -290,7 +285,7 @@ async function importMediaWithProgress(
|
|
|
290
285
|
});
|
|
291
286
|
|
|
292
287
|
// Build the new URL
|
|
293
|
-
const newUrl =
|
|
288
|
+
const newUrl = `/_emdash/api/media/file/${storageKey}`;
|
|
294
289
|
|
|
295
290
|
result.imported.push({
|
|
296
291
|
wpId: attachment.id,
|
|
@@ -58,6 +58,15 @@ export const POST: APIRoute = async ({ request, locals }) => {
|
|
|
58
58
|
// eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Zod schema output narrowed to PrepareRequest
|
|
59
59
|
const result = await prepareImport(emdash.db, body as PrepareRequest);
|
|
60
60
|
|
|
61
|
+
// Invalidate the URL pattern cache when prepare adds new collections so
|
|
62
|
+
// public routing picks up their patterns immediately. The manifest
|
|
63
|
+
// itself is built fresh per admin request, so cross-request
|
|
64
|
+
// staleness (the original failure mode in #747) is no longer
|
|
65
|
+
// possible — the execute step always reads live schema.
|
|
66
|
+
if (result.collectionsCreated.length > 0) {
|
|
67
|
+
emdash.invalidateUrlPatternCache();
|
|
68
|
+
}
|
|
69
|
+
|
|
61
70
|
return apiSuccess(result, result.success ? 200 : 400);
|
|
62
71
|
} catch (error) {
|
|
63
72
|
return handleError(error, "Failed to prepare import", "WXR_PREPARE_ERROR");
|
|
@@ -36,7 +36,7 @@ export interface WpPluginImportResponse {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
export const POST: APIRoute = async ({ request, locals }) => {
|
|
39
|
-
const { emdash,
|
|
39
|
+
const { emdash, user } = locals;
|
|
40
40
|
|
|
41
41
|
const denied = requirePerm(user, "import:execute");
|
|
42
42
|
if (denied) return denied;
|
|
@@ -46,6 +46,8 @@ export const POST: APIRoute = async ({ request, locals }) => {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
try {
|
|
49
|
+
const emdashManifest = await emdash.getManifest();
|
|
50
|
+
|
|
49
51
|
const body = await parseBody(request, wpPluginExecuteBody);
|
|
50
52
|
if (isParseError(body)) return body;
|
|
51
53
|
|
|
@@ -9,64 +9,81 @@
|
|
|
9
9
|
|
|
10
10
|
import type { APIRoute } from "astro";
|
|
11
11
|
|
|
12
|
+
import { handleError } from "#api/error.js";
|
|
12
13
|
import { getAuthMode } from "#auth/mode.js";
|
|
13
14
|
|
|
14
15
|
import { COMMIT, VERSION } from "../../../version.js";
|
|
15
|
-
import { getStoredConfig } from "../../integration/runtime.js";
|
|
16
16
|
import type { EmDashManifest } from "../../types.js";
|
|
17
17
|
|
|
18
18
|
export const prerender = false;
|
|
19
19
|
|
|
20
20
|
export const GET: APIRoute = async ({ locals }) => {
|
|
21
|
-
const {
|
|
21
|
+
const { emdash } = locals;
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
try {
|
|
24
|
+
// Manifest is built fresh from the live database per admin request.
|
|
25
|
+
// `requestCached` inside `getManifest` dedupes if multiple consumers
|
|
26
|
+
// share the request. Wrapped in try/catch so any future DB-touching
|
|
27
|
+
// additions to `getManifest()` (plugin manifest loading, marketplace
|
|
28
|
+
// lookup, etc.) return the standard error envelope rather than an
|
|
29
|
+
// unstructured 500 — matches the pattern used by the WP execute
|
|
30
|
+
// routes.
|
|
31
|
+
const emdashManifest = emdash ? await emdash.getManifest() : null;
|
|
25
32
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const adminBranding = storedConfig?.admin;
|
|
33
|
+
// Determine auth mode from config
|
|
34
|
+
const authMode = getAuthMode(emdash?.config);
|
|
29
35
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
SELECT COUNT(*) as cnt FROM allowed_domains WHERE enabled = 1
|
|
38
|
-
`.execute(emdash.db);
|
|
39
|
-
signupEnabled = Number(result.rows[0]?.cnt ?? 0) > 0;
|
|
40
|
-
} catch {
|
|
41
|
-
// Table may not exist yet, that's fine
|
|
42
|
-
}
|
|
43
|
-
}
|
|
36
|
+
// Read admin branding from the per-request config plumbed through middleware
|
|
37
|
+
// (same source admin.astro reads from). Reading from a build-time global
|
|
38
|
+
// here was unreliable -- the virtual config module exports the config but
|
|
39
|
+
// doesn't assign it to globalThis, so getStoredConfig() always returned
|
|
40
|
+
// null and the React SPA never received custom logo/siteName/favicon.
|
|
41
|
+
// See issue #835.
|
|
42
|
+
const adminBranding = emdash?.config?.admin;
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
// Check if self-signup is enabled (any allowed domain with enabled = 1)
|
|
45
|
+
// Only relevant for passkey auth — external auth providers handle their own signup
|
|
46
|
+
let signupEnabled = false;
|
|
47
|
+
if (emdash?.db && authMode.type === "passkey") {
|
|
48
|
+
try {
|
|
49
|
+
const { sql } = await import("kysely");
|
|
50
|
+
const result = await sql<{ cnt: unknown }>`
|
|
51
|
+
SELECT COUNT(*) as cnt FROM allowed_domains WHERE enabled = 1
|
|
52
|
+
`.execute(emdash.db);
|
|
53
|
+
signupEnabled = Number(result.rows[0]?.cnt ?? 0) > 0;
|
|
54
|
+
} catch {
|
|
55
|
+
// Table may not exist yet, that's fine
|
|
51
56
|
}
|
|
52
|
-
|
|
53
|
-
version: VERSION,
|
|
54
|
-
commit: COMMIT,
|
|
55
|
-
hash: "default",
|
|
56
|
-
collections: {},
|
|
57
|
-
plugins: {},
|
|
58
|
-
taxonomies: [],
|
|
59
|
-
authMode: "passkey",
|
|
60
|
-
signupEnabled,
|
|
61
|
-
admin: adminBranding,
|
|
62
|
-
};
|
|
57
|
+
}
|
|
63
58
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
59
|
+
const manifest: EmDashManifest = emdashManifest
|
|
60
|
+
? {
|
|
61
|
+
...emdashManifest,
|
|
62
|
+
authMode: authMode.type === "external" ? authMode.providerType : "passkey",
|
|
63
|
+
signupEnabled,
|
|
64
|
+
admin: adminBranding,
|
|
65
|
+
}
|
|
66
|
+
: {
|
|
67
|
+
version: VERSION,
|
|
68
|
+
commit: COMMIT,
|
|
69
|
+
hash: "default",
|
|
70
|
+
collections: {},
|
|
71
|
+
plugins: {},
|
|
72
|
+
taxonomies: [],
|
|
73
|
+
authMode: "passkey",
|
|
74
|
+
signupEnabled,
|
|
75
|
+
admin: adminBranding,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return Response.json(
|
|
79
|
+
{ data: manifest },
|
|
80
|
+
{
|
|
81
|
+
headers: {
|
|
82
|
+
"Cache-Control": "private, no-store",
|
|
83
|
+
},
|
|
69
84
|
},
|
|
70
|
-
|
|
71
|
-
)
|
|
85
|
+
);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
return handleError(error, "Failed to build manifest", "MANIFEST_BUILD_ERROR");
|
|
88
|
+
}
|
|
72
89
|
};
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import type { APIRoute } from "astro";
|
|
11
11
|
import { MediaRepository } from "emdash";
|
|
12
12
|
|
|
13
|
-
import { requirePerm } from "#api/authorize.js";
|
|
13
|
+
import { requireOwnerPerm, requirePerm } from "#api/authorize.js";
|
|
14
14
|
import { apiError, apiSuccess, handleError } from "#api/error.js";
|
|
15
15
|
import { isParseError, parseOptionalBody } from "#api/parse.js";
|
|
16
16
|
import { mediaConfirmBody } from "#api/schemas.js";
|
|
@@ -62,6 +62,15 @@ export const POST: APIRoute = async ({ params, request, locals }) => {
|
|
|
62
62
|
return apiError("INVALID_STATE", `Media item is not pending: ${existing.status}`, 400);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
// Only the uploader or a user with media:edit_any can confirm/fail a pending upload
|
|
66
|
+
const ownerDenied = requireOwnerPerm(
|
|
67
|
+
user,
|
|
68
|
+
existing.authorId ?? "",
|
|
69
|
+
"media:edit_own",
|
|
70
|
+
"media:edit_any",
|
|
71
|
+
);
|
|
72
|
+
if (ownerDenied) return ownerDenied;
|
|
73
|
+
|
|
65
74
|
// Optionally verify the file exists in storage
|
|
66
75
|
if (emdash.storage) {
|
|
67
76
|
const exists = await emdash.storage.exists(existing.storageKey);
|
|
@@ -37,9 +37,8 @@ export const GET: APIRoute = async ({ params, request, locals }) => {
|
|
|
37
37
|
|
|
38
38
|
const url = new URL(request.url);
|
|
39
39
|
const cursor = url.searchParams.get("cursor") || undefined;
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
: undefined;
|
|
40
|
+
const rawLimit = url.searchParams.get("limit");
|
|
41
|
+
const limit = rawLimit ? Math.max(1, Math.min(parseInt(rawLimit, 10) || 50, 100)) : undefined;
|
|
43
42
|
const query = url.searchParams.get("query") || undefined;
|
|
44
43
|
const mimeType = url.searchParams.get("mimeType") || undefined;
|
|
45
44
|
|
|
@@ -98,6 +97,16 @@ export const POST: APIRoute = async ({ params, request, locals }) => {
|
|
|
98
97
|
return apiError("NO_FILE", "No file provided", 400);
|
|
99
98
|
}
|
|
100
99
|
|
|
100
|
+
// Basic size validation (default 50MB, configurable via maxUploadSize)
|
|
101
|
+
const maxSize = emdash.config?.maxUploadSize ?? 50 * 1024 * 1024;
|
|
102
|
+
if (file.size > maxSize) {
|
|
103
|
+
return apiError(
|
|
104
|
+
"FILE_TOO_LARGE",
|
|
105
|
+
`File exceeds maximum size of ${Math.round(maxSize / 1024 / 1024)}MB`,
|
|
106
|
+
413,
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
101
110
|
const item = await provider.upload({
|
|
102
111
|
file,
|
|
103
112
|
filename: file.name,
|
|
@@ -9,33 +9,50 @@
|
|
|
9
9
|
|
|
10
10
|
import type { APIRoute } from "astro";
|
|
11
11
|
|
|
12
|
+
import { handleError } from "../../../api/error.js";
|
|
12
13
|
import { generateOpenApiDocument } from "../../../api/openapi/index.js";
|
|
13
14
|
|
|
14
15
|
export const prerender = false;
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
// Use globalThis with Symbol.for to survive Vite's SSR module duplication
|
|
18
|
+
const OPENAPI_CACHE_KEY = Symbol.for("emdash.openapi.cachedSpec");
|
|
19
|
+
|
|
20
|
+
function getCachedSpec(): string | null {
|
|
21
|
+
const val = (globalThis as Record<symbol, unknown>)[OPENAPI_CACHE_KEY];
|
|
22
|
+
return typeof val === "string" ? val : null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function setCachedSpec(spec: string): void {
|
|
26
|
+
(globalThis as Record<symbol, unknown>)[OPENAPI_CACHE_KEY] = spec;
|
|
27
|
+
}
|
|
17
28
|
|
|
18
29
|
export const GET: APIRoute = async ({ locals }) => {
|
|
19
30
|
const { emdash } = locals;
|
|
20
|
-
|
|
31
|
+
|
|
32
|
+
let spec = getCachedSpec();
|
|
33
|
+
if (!spec && emdash) {
|
|
21
34
|
try {
|
|
22
35
|
const doc = generateOpenApiDocument({ maxUploadSize: emdash.config.maxUploadSize });
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
{ status: 500, headers: { "Content-Type": "application/json" } },
|
|
28
|
-
);
|
|
36
|
+
spec = JSON.stringify(doc);
|
|
37
|
+
setCachedSpec(spec);
|
|
38
|
+
} catch (error) {
|
|
39
|
+
return handleError(error, "Failed to generate OpenAPI document", "OPENAPI_ERROR");
|
|
29
40
|
}
|
|
30
41
|
}
|
|
31
42
|
|
|
32
|
-
|
|
43
|
+
if (!spec) {
|
|
44
|
+
try {
|
|
45
|
+
spec = JSON.stringify(generateOpenApiDocument());
|
|
46
|
+
} catch (error) {
|
|
47
|
+
return handleError(error, "Failed to generate OpenAPI document", "OPENAPI_ERROR");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
33
50
|
|
|
34
51
|
return new Response(spec, {
|
|
35
52
|
status: 200,
|
|
36
53
|
headers: {
|
|
37
54
|
"Content-Type": "application/json",
|
|
38
|
-
"Cache-Control": "
|
|
55
|
+
"Cache-Control": "private, no-store",
|
|
39
56
|
"Access-Control-Allow-Origin": "*",
|
|
40
57
|
},
|
|
41
58
|
});
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import type { APIRoute } from "astro";
|
|
10
10
|
|
|
11
11
|
import { requirePerm } from "#api/authorize.js";
|
|
12
|
-
import { handleError, unwrapResult } from "#api/error.js";
|
|
12
|
+
import { handleError, requireDb, unwrapResult } from "#api/error.js";
|
|
13
13
|
import {
|
|
14
14
|
handleNotFoundClear,
|
|
15
15
|
handleNotFoundList,
|
|
@@ -22,7 +22,9 @@ export const prerender = false;
|
|
|
22
22
|
|
|
23
23
|
export const GET: APIRoute = async ({ url, locals }) => {
|
|
24
24
|
const { emdash, user } = locals;
|
|
25
|
-
const
|
|
25
|
+
const dbErr = requireDb(emdash?.db);
|
|
26
|
+
if (dbErr) return dbErr;
|
|
27
|
+
const db = emdash!.db;
|
|
26
28
|
|
|
27
29
|
const denied = requirePerm(user, "redirects:read");
|
|
28
30
|
if (denied) return denied;
|
|
@@ -40,7 +42,9 @@ export const GET: APIRoute = async ({ url, locals }) => {
|
|
|
40
42
|
|
|
41
43
|
export const DELETE: APIRoute = async ({ locals }) => {
|
|
42
44
|
const { emdash, user } = locals;
|
|
43
|
-
const
|
|
45
|
+
const dbErr = requireDb(emdash?.db);
|
|
46
|
+
if (dbErr) return dbErr;
|
|
47
|
+
const db = emdash!.db;
|
|
44
48
|
|
|
45
49
|
const denied = requirePerm(user, "redirects:manage");
|
|
46
50
|
if (denied) return denied;
|
|
@@ -55,7 +59,9 @@ export const DELETE: APIRoute = async ({ locals }) => {
|
|
|
55
59
|
|
|
56
60
|
export const POST: APIRoute = async ({ request, locals }) => {
|
|
57
61
|
const { emdash, user } = locals;
|
|
58
|
-
const
|
|
62
|
+
const dbErr = requireDb(emdash?.db);
|
|
63
|
+
if (dbErr) return dbErr;
|
|
64
|
+
const db = emdash!.db;
|
|
59
65
|
|
|
60
66
|
const denied = requirePerm(user, "redirects:manage");
|
|
61
67
|
if (denied) return denied;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import type { APIRoute } from "astro";
|
|
8
8
|
|
|
9
9
|
import { requirePerm } from "#api/authorize.js";
|
|
10
|
-
import { handleError, unwrapResult } from "#api/error.js";
|
|
10
|
+
import { handleError, requireDb, unwrapResult } from "#api/error.js";
|
|
11
11
|
import { handleNotFoundSummary } from "#api/handlers/redirects.js";
|
|
12
12
|
import { isParseError, parseQuery } from "#api/parse.js";
|
|
13
13
|
import { notFoundSummaryQuery } from "#api/schemas.js";
|
|
@@ -16,7 +16,9 @@ export const prerender = false;
|
|
|
16
16
|
|
|
17
17
|
export const GET: APIRoute = async ({ url, locals }) => {
|
|
18
18
|
const { emdash, user } = locals;
|
|
19
|
-
const
|
|
19
|
+
const dbErr = requireDb(emdash?.db);
|
|
20
|
+
if (dbErr) return dbErr;
|
|
21
|
+
const db = emdash!.db;
|
|
20
22
|
|
|
21
23
|
const denied = requirePerm(user, "redirects:read");
|
|
22
24
|
if (denied) return denied;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import type { APIRoute } from "astro";
|
|
10
10
|
|
|
11
11
|
import { requirePerm } from "#api/authorize.js";
|
|
12
|
-
import { apiError, handleError, unwrapResult } from "#api/error.js";
|
|
12
|
+
import { apiError, handleError, requireDb, unwrapResult } from "#api/error.js";
|
|
13
13
|
import {
|
|
14
14
|
handleRedirectDelete,
|
|
15
15
|
handleRedirectGet,
|
|
@@ -23,7 +23,9 @@ export const prerender = false;
|
|
|
23
23
|
|
|
24
24
|
export const GET: APIRoute = async ({ params, locals }) => {
|
|
25
25
|
const { emdash, user } = locals;
|
|
26
|
-
const
|
|
26
|
+
const dbErr = requireDb(emdash?.db);
|
|
27
|
+
if (dbErr) return dbErr;
|
|
28
|
+
const db = emdash!.db;
|
|
27
29
|
const { id } = params;
|
|
28
30
|
|
|
29
31
|
const denied = requirePerm(user, "redirects:read");
|
|
@@ -43,7 +45,9 @@ export const GET: APIRoute = async ({ params, locals }) => {
|
|
|
43
45
|
|
|
44
46
|
export const PUT: APIRoute = async ({ params, request, locals }) => {
|
|
45
47
|
const { emdash, user } = locals;
|
|
46
|
-
const
|
|
48
|
+
const dbErr = requireDb(emdash?.db);
|
|
49
|
+
if (dbErr) return dbErr;
|
|
50
|
+
const db = emdash!.db;
|
|
47
51
|
const { id } = params;
|
|
48
52
|
|
|
49
53
|
const denied = requirePerm(user, "redirects:manage");
|
|
@@ -67,7 +71,9 @@ export const PUT: APIRoute = async ({ params, request, locals }) => {
|
|
|
67
71
|
|
|
68
72
|
export const DELETE: APIRoute = async ({ params, locals }) => {
|
|
69
73
|
const { emdash, user } = locals;
|
|
70
|
-
const
|
|
74
|
+
const dbErr = requireDb(emdash?.db);
|
|
75
|
+
if (dbErr) return dbErr;
|
|
76
|
+
const db = emdash!.db;
|
|
71
77
|
const { id } = params;
|
|
72
78
|
|
|
73
79
|
const denied = requirePerm(user, "redirects:manage");
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import type { APIRoute } from "astro";
|
|
9
9
|
|
|
10
10
|
import { requirePerm } from "#api/authorize.js";
|
|
11
|
-
import { handleError, unwrapResult } from "#api/error.js";
|
|
11
|
+
import { handleError, requireDb, unwrapResult } from "#api/error.js";
|
|
12
12
|
import { handleRedirectCreate, handleRedirectList } from "#api/handlers/redirects.js";
|
|
13
13
|
import { isParseError, parseBody, parseQuery } from "#api/parse.js";
|
|
14
14
|
import { createRedirectBody, redirectsListQuery } from "#api/schemas.js";
|
|
@@ -18,7 +18,9 @@ export const prerender = false;
|
|
|
18
18
|
|
|
19
19
|
export const GET: APIRoute = async ({ url, locals }) => {
|
|
20
20
|
const { emdash, user } = locals;
|
|
21
|
-
const
|
|
21
|
+
const dbErr = requireDb(emdash?.db);
|
|
22
|
+
if (dbErr) return dbErr;
|
|
23
|
+
const db = emdash!.db;
|
|
22
24
|
|
|
23
25
|
const denied = requirePerm(user, "redirects:read");
|
|
24
26
|
if (denied) return denied;
|
|
@@ -36,7 +38,9 @@ export const GET: APIRoute = async ({ url, locals }) => {
|
|
|
36
38
|
|
|
37
39
|
export const POST: APIRoute = async ({ request, locals }) => {
|
|
38
40
|
const { emdash, user } = locals;
|
|
39
|
-
const
|
|
41
|
+
const dbErr = requireDb(emdash?.db);
|
|
42
|
+
if (dbErr) return dbErr;
|
|
43
|
+
const db = emdash!.db;
|
|
40
44
|
|
|
41
45
|
const denied = requirePerm(user, "redirects:manage");
|
|
42
46
|
if (denied) return denied;
|
|
@@ -16,7 +16,7 @@ export const GET: APIRoute = async ({ params, locals }) => {
|
|
|
16
16
|
const { emdash, user } = locals;
|
|
17
17
|
const revisionId = params.revisionId!;
|
|
18
18
|
|
|
19
|
-
const denied = requirePerm(user, "content:
|
|
19
|
+
const denied = requirePerm(user, "content:read_drafts");
|
|
20
20
|
if (denied) return denied;
|
|
21
21
|
|
|
22
22
|
if (!emdash?.handleRevisionGet) {
|
|
@@ -57,7 +57,6 @@ export const PUT: APIRoute = async ({ params, request, locals }) => {
|
|
|
57
57
|
fieldSlug,
|
|
58
58
|
body as UpdateFieldInput,
|
|
59
59
|
);
|
|
60
|
-
if (result.success) emdash!.invalidateManifest();
|
|
61
60
|
return unwrapResult(result);
|
|
62
61
|
};
|
|
63
62
|
|
|
@@ -73,6 +72,5 @@ export const DELETE: APIRoute = async ({ params, locals }) => {
|
|
|
73
72
|
if (denied) return denied;
|
|
74
73
|
|
|
75
74
|
const result = await handleSchemaFieldDelete(emdash!.db, collectionSlug, fieldSlug);
|
|
76
|
-
if (result.success) emdash!.invalidateManifest();
|
|
77
75
|
return unwrapResult(result);
|
|
78
76
|
};
|
|
@@ -28,6 +28,5 @@ export const POST: APIRoute = async ({ params, request, locals }) => {
|
|
|
28
28
|
if (isParseError(body)) return body;
|
|
29
29
|
|
|
30
30
|
const result = await handleSchemaFieldReorder(emdash!.db, collectionSlug, body.fieldSlugs);
|
|
31
|
-
if (result.success) emdash!.invalidateManifest();
|
|
32
31
|
return unwrapResult(result);
|
|
33
32
|
};
|
|
@@ -59,7 +59,7 @@ export const PUT: APIRoute = async ({ params, request, locals }) => {
|
|
|
59
59
|
// eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- parseBody validates via Zod
|
|
60
60
|
body as UpdateCollectionInput,
|
|
61
61
|
);
|
|
62
|
-
emdash!.
|
|
62
|
+
emdash!.invalidateUrlPatternCache();
|
|
63
63
|
return unwrapResult(result);
|
|
64
64
|
};
|
|
65
65
|
|
|
@@ -77,6 +77,6 @@ export const DELETE: APIRoute = async ({ params, url, locals }) => {
|
|
|
77
77
|
const result = await handleSchemaCollectionDelete(emdash!.db, slug, {
|
|
78
78
|
force,
|
|
79
79
|
});
|
|
80
|
-
emdash!.
|
|
80
|
+
emdash!.invalidateUrlPatternCache();
|
|
81
81
|
return unwrapResult(result);
|
|
82
82
|
};
|
|
@@ -43,6 +43,6 @@ export const POST: APIRoute = async ({ request, locals }) => {
|
|
|
43
43
|
|
|
44
44
|
// eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Zod schema output narrowed to CreateCollectionInput
|
|
45
45
|
const result = await handleSchemaCollectionCreate(emdash!.db, body as CreateCollectionInput);
|
|
46
|
-
emdash!.
|
|
46
|
+
emdash!.invalidateUrlPatternCache();
|
|
47
47
|
return unwrapResult(result, 201);
|
|
48
48
|
};
|