emdash 0.7.0 → 1.0.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-BKSf3T9R.d.mts} +1 -1
- package/dist/{adapters-Di31kZ28.d.mts.map → adapters-BKSf3T9R.d.mts.map} +1 -1
- package/dist/{apply-5uslYdUu.mjs → apply-x0eMK1lX.mjs} +18 -17
- package/dist/apply-x0eMK1lX.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 +86 -15
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +5 -5
- package/dist/astro/middleware/auth.d.mts.map +1 -1
- package/dist/astro/middleware/auth.mjs +22 -2
- package/dist/astro/middleware/auth.mjs.map +1 -1
- package/dist/astro/middleware/redirect.mjs +2 -2
- package/dist/astro/middleware/request-context.mjs +1 -1
- package/dist/astro/middleware/setup.mjs +1 -1
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +259 -71
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/types.d.mts +16 -8
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/{byline-C4OVd8b3.mjs → byline-Chbr2GoP.mjs} +3 -3
- package/dist/byline-Chbr2GoP.mjs.map +1 -0
- package/dist/{bylines-hPTW79hw.mjs → bylines-CRNsVG88.mjs} +4 -4
- package/dist/{bylines-hPTW79hw.mjs.map → bylines-CRNsVG88.mjs.map} +1 -1
- package/dist/cli/index.mjs +16 -12
- 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 +1 -1
- package/dist/{content-D7J5y73J.mjs → content-BcQPYxdV.mjs} +13 -15
- package/dist/content-BcQPYxdV.mjs.map +1 -0
- package/dist/db/index.d.mts +3 -3
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{db-errors-D0UT85nC.mjs → db-errors-l1Qh2RPR.mjs} +1 -1
- package/dist/{db-errors-D0UT85nC.mjs.map → db-errors-l1Qh2RPR.mjs.map} +1 -1
- package/dist/{default-CME5YdZ3.mjs → default-DCVqE5ib.mjs} +1 -1
- package/dist/{default-CME5YdZ3.mjs.map → default-DCVqE5ib.mjs.map} +1 -1
- package/dist/{error-CiYn9yDu.mjs → error-zG5T1UGA.mjs} +1 -1
- package/dist/error-zG5T1UGA.mjs.map +1 -0
- package/dist/{index-De6_Xv3v.d.mts → index-DIb-CzNx.d.mts} +157 -14
- package/dist/index-DIb-CzNx.d.mts.map +1 -0
- package/dist/index.d.mts +11 -11
- package/dist/index.mjs +22 -20
- package/dist/{load-CBcmDIot.mjs → load-CyEoextb.mjs} +1 -1
- package/dist/{load-CBcmDIot.mjs.map → load-CyEoextb.mjs.map} +1 -1
- package/dist/{loader-DeiBJEMe.mjs → loader-CndGj8kM.mjs} +8 -6
- package/dist/loader-CndGj8kM.mjs.map +1 -0
- package/dist/{manifest-schema-V30qsMft.mjs → manifest-schema-DH9xhc6t.mjs} +13 -1
- package/dist/manifest-schema-DH9xhc6t.mjs.map +1 -0
- package/dist/media/index.d.mts +1 -1
- package/dist/media/local-runtime.d.mts +7 -7
- package/dist/media/local-runtime.mjs +2 -2
- package/dist/{media-DqHVh136.mjs → media-D8FbNsl0.mjs} +4 -7
- package/dist/media-D8FbNsl0.mjs.map +1 -0
- package/dist/{mode-CpNnGkPz.mjs → mode-BnAOqItE.mjs} +1 -1
- package/dist/mode-BnAOqItE.mjs.map +1 -0
- package/dist/page/index.d.mts +2 -2
- package/dist/placeholder-C-fk5hYI.mjs.map +1 -1
- package/dist/{placeholder-tzpqGWII.d.mts → placeholder-D29tWZ7o.d.mts} +1 -1
- package/dist/{placeholder-tzpqGWII.d.mts.map → placeholder-D29tWZ7o.d.mts.map} +1 -1
- package/dist/plugins/adapt-sandbox-entry.d.mts +5 -5
- package/dist/plugins/adapt-sandbox-entry.mjs +1 -1
- package/dist/{query-g4Ug-9j9.mjs → query-fqEdLFms.mjs} +9 -9
- package/dist/{query-g4Ug-9j9.mjs.map → query-fqEdLFms.mjs.map} +1 -1
- package/dist/{redirect-CN0Rt9Ob.mjs → redirect-D_pshWdf.mjs} +4 -4
- package/dist/redirect-D_pshWdf.mjs.map +1 -0
- package/dist/{registry-Ci3WxVAr.mjs → registry-C3Mr0ODu.mjs} +33 -9
- package/dist/registry-C3Mr0ODu.mjs.map +1 -0
- package/dist/{request-cache-DiR961CV.mjs → request-cache-Ci7f5pBb.mjs} +1 -1
- package/dist/request-cache-Ci7f5pBb.mjs.map +1 -0
- package/dist/{runner-BR2xKwhn.d.mts → runner-OURCaApa.d.mts} +2 -2
- package/dist/{runner-BR2xKwhn.d.mts.map → runner-OURCaApa.d.mts.map} +1 -1
- package/dist/runtime.d.mts +6 -6
- package/dist/runtime.mjs +2 -2
- package/dist/{search-B0effn3j.mjs → search-BoZYFuUk.mjs} +227 -84
- package/dist/search-BoZYFuUk.mjs.map +1 -0
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +12 -12
- 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-B4IAshV8.mjs} +5 -5
- package/dist/{taxonomies-K2z0Uhnj.mjs.map → taxonomies-B4IAshV8.mjs.map} +1 -1
- package/dist/{tokens-BFPFx3CA.mjs → tokens-D9vnZqYS.mjs} +1 -1
- package/dist/{tokens-BFPFx3CA.mjs.map → tokens-D9vnZqYS.mjs.map} +1 -1
- package/dist/{transport-BykRfpyy.mjs → transport-C9ugt2Nr.mjs} +1 -1
- package/dist/{transport-BykRfpyy.mjs.map → transport-C9ugt2Nr.mjs.map} +1 -1
- package/dist/{transport-H4Iwx7tC.d.mts → transport-CUnEL3Vs.d.mts} +1 -1
- package/dist/{transport-H4Iwx7tC.d.mts.map → transport-CUnEL3Vs.d.mts.map} +1 -1
- package/dist/types-BIgulNsW.mjs +68 -0
- package/dist/types-BIgulNsW.mjs.map +1 -0
- package/dist/{types-DDS4MxsT.mjs → types-Bm1dn-q3.mjs} +1 -1
- package/dist/{types-DDS4MxsT.mjs.map → types-Bm1dn-q3.mjs.map} +1 -1
- package/dist/{types-CnZYHyLW.d.mts → types-BmPPSUEx.d.mts} +1 -1
- package/dist/{types-CnZYHyLW.d.mts.map → types-BmPPSUEx.d.mts.map} +1 -1
- package/dist/{types-6CUZRrZP.d.mts → types-BrA0xf5I.d.mts} +24 -2
- package/dist/{types-6CUZRrZP.d.mts.map → types-BrA0xf5I.d.mts.map} +1 -1
- package/dist/{types-C2v0c34j.d.mts → types-CS8FIX7L.d.mts} +1 -1
- package/dist/{types-C2v0c34j.d.mts.map → types-CS8FIX7L.d.mts.map} +1 -1
- package/dist/{types-BH2L167P.mjs → types-CgqmmMJB.mjs} +1 -1
- package/dist/{types-BH2L167P.mjs.map → types-CgqmmMJB.mjs.map} +1 -1
- package/dist/{types-CFWjXmus.d.mts → types-DIMwPFub.d.mts} +1 -1
- package/dist/{types-CFWjXmus.d.mts.map → types-DIMwPFub.d.mts.map} +1 -1
- package/dist/{types-DgrIP0tF.d.mts → types-i36XcA_X.d.mts} +49 -6
- package/dist/types-i36XcA_X.d.mts.map +1 -0
- package/dist/{validate-CqsNItbt.mjs → validate-CxVsLehf.mjs} +2 -2
- package/dist/{validate-CqsNItbt.mjs.map → validate-CxVsLehf.mjs.map} +1 -1
- package/dist/{validate-kM8Pjuf7.d.mts → validate-DHxmpFJt.d.mts} +4 -4
- package/dist/{validate-kM8Pjuf7.d.mts.map → validate-DHxmpFJt.d.mts.map} +1 -1
- package/dist/validation-C-ZpN2GI.mjs +144 -0
- package/dist/validation-C-ZpN2GI.mjs.map +1 -0
- package/dist/version-DJrV1K0M.mjs +7 -0
- package/dist/{version-BnTKdfam.mjs.map → version-DJrV1K0M.mjs.map} +1 -1
- package/dist/zod-generator-CpwccCIv.mjs +132 -0
- package/dist/zod-generator-CpwccCIv.mjs.map +1 -0
- package/package.json +19 -6
- 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 +13 -0
- package/src/api/handlers/content.ts +122 -3
- package/src/api/handlers/index.ts +2 -0
- package/src/api/handlers/media.ts +8 -1
- package/src/api/handlers/menus.ts +160 -21
- package/src/api/handlers/redirects.ts +16 -3
- package/src/api/handlers/sections.ts +8 -1
- package/src/api/handlers/taxonomies.ts +128 -16
- package/src/api/handlers/validation.ts +212 -0
- package/src/api/openapi/document.ts +4 -1
- package/src/api/public-url.ts +6 -3
- package/src/api/route-utils.ts +14 -0
- package/src/api/schemas/common.ts +1 -1
- package/src/api/schemas/setup.ts +8 -0
- package/src/api/schemas/widgets.ts +12 -10
- package/src/api/setup-complete.ts +40 -0
- package/src/astro/integration/index.ts +13 -2
- package/src/astro/integration/routes.ts +28 -0
- package/src/astro/integration/runtime.ts +19 -1
- package/src/astro/integration/virtual-modules.ts +41 -0
- package/src/astro/integration/vite-config.ts +43 -12
- package/src/astro/middleware/auth.ts +21 -0
- package/src/astro/middleware.ts +18 -1
- package/src/astro/routes/PluginRegistry.tsx +10 -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/content/[collection]/[id]/translations.ts +1 -1
- package/src/astro/routes/api/content/[collection]/index.ts +1 -9
- package/src/astro/routes/api/import/wordpress/media.ts +2 -7
- package/src/astro/routes/api/import/wordpress/prepare.ts +10 -0
- package/src/astro/routes/api/settings/email.ts +4 -9
- 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/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 +9 -0
- package/src/auth/mode.ts +15 -3
- 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/cli/commands/bundle.ts +3 -1
- package/src/components/EmDashImage.astro +7 -6
- package/src/components/Gallery.astro +5 -3
- package/src/components/Image.astro +8 -3
- package/src/components/InlinePortableTextEditor.tsx +2 -1
- package/src/components/LiveSearch.astro +5 -14
- 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 +40 -40
- 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 +12 -16
- package/src/database/repositories/taxonomy.ts +14 -3
- package/src/database/repositories/types.ts +57 -8
- package/src/database/repositories/user.ts +6 -8
- package/src/emdash-runtime.ts +306 -90
- package/src/index.ts +5 -1
- package/src/loader.ts +6 -5
- package/src/mcp/server.ts +678 -105
- package/src/media/normalize.ts +1 -1
- package/src/media/url.ts +78 -0
- package/src/plugins/email-console.ts +10 -3
- package/src/plugins/hooks.ts +11 -0
- package/src/plugins/manifest-schema.ts +12 -0
- package/src/plugins/types.ts +23 -2
- package/src/query.ts +1 -1
- package/src/request-cache.ts +3 -0
- package/src/schema/registry.ts +41 -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/storage/s3.ts +12 -6
- 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/content-D7J5y73J.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/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/search-B0effn3j.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
|
@@ -4,28 +4,30 @@ import "../connection-2igzM-AT.mjs";
|
|
|
4
4
|
import { t as validateIdentifier } from "../validate-VPnKoIzW.mjs";
|
|
5
5
|
import { a as isSqlite } from "../dialect-helpers-DhTzaUxP.mjs";
|
|
6
6
|
import { r as runMigrations } from "../runner-tQ7BJ4T7.mjs";
|
|
7
|
-
import { At as
|
|
8
|
-
import { r as RevisionRepository } from "../content-
|
|
7
|
+
import { At as handleContentSchedule, B as EmailPipeline, Ct as handleContentGet, Dt as handleContentPermanentDelete, Et as handleContentListTrashed, Ft as validateRev, G as extractRequestMeta, H as createHookPipeline, J as definePlugin, K as sanitizeHeadersForSandbox, L as PluginRouteRegistry, Mt as handleContentUnpublish, Nt as handleContentUnschedule, Ot as handleContentPublish, Pt as handleContentUpdate, R as DEV_CONSOLE_EMAIL_PLUGIN_ID, St as handleContentDuplicate, Tt as handleContentList, U as resolveExclusiveHooks, W as CronExecutor, Z as after, _t as handleContentCountScheduled, at as PluginStateRepository, bt as handleContentDelete, ct as handleMediaDelete, dt as handleMediaUpdate, ft as handleRevisionGet, gt as handleContentCompare, jt as handleContentTranslations, kt as handleContentRestore, lt as handleMediaGet, mt as handleRevisionRestore, nt as loadBundleFromR2, pt as handleRevisionList, q as getTrustedProxyHeaders, st as handleMediaCreate, ut as handleMediaList, vt as handleContentCountTrashed, wt as handleContentGetIncludingTrashed, xt as handleContentDiscardDraft, yt as handleContentCreate, z as devConsoleEmailDeliver } from "../search-BoZYFuUk.mjs";
|
|
8
|
+
import { r as RevisionRepository } from "../content-BcQPYxdV.mjs";
|
|
9
9
|
import "../base64-MBPo9ozB.mjs";
|
|
10
|
-
import "../types-
|
|
11
|
-
import { t as MediaRepository } from "../media-
|
|
12
|
-
import { p as OptionsRepository } from "../apply-
|
|
13
|
-
import "../redirect-
|
|
14
|
-
import "../byline-
|
|
10
|
+
import "../types-BIgulNsW.mjs";
|
|
11
|
+
import { t as MediaRepository } from "../media-D8FbNsl0.mjs";
|
|
12
|
+
import { p as OptionsRepository } from "../apply-x0eMK1lX.mjs";
|
|
13
|
+
import "../redirect-D_pshWdf.mjs";
|
|
14
|
+
import "../byline-Chbr2GoP.mjs";
|
|
15
15
|
import { n as normalizeMediaValue } from "../placeholder-C-fk5hYI.mjs";
|
|
16
16
|
import { i as setI18nConfig } from "../config-BXwuX8Bx.mjs";
|
|
17
|
-
import {
|
|
18
|
-
import { n as
|
|
19
|
-
import "../
|
|
20
|
-
import "../
|
|
21
|
-
import
|
|
22
|
-
import {
|
|
23
|
-
import "../
|
|
24
|
-
import "../
|
|
25
|
-
import "../
|
|
17
|
+
import { r as hashString } from "../zod-generator-CpwccCIv.mjs";
|
|
18
|
+
import { i as FTSManager, n as SchemaRegistry } from "../registry-C3Mr0ODu.mjs";
|
|
19
|
+
import { n as getDb } from "../loader-CndGj8kM.mjs";
|
|
20
|
+
import "../request-cache-Ci7f5pBb.mjs";
|
|
21
|
+
import "../taxonomies-B4IAshV8.mjs";
|
|
22
|
+
import { r as normalizeManifestRoute } from "../manifest-schema-DH9xhc6t.mjs";
|
|
23
|
+
import "../error-zG5T1UGA.mjs";
|
|
24
|
+
import { a as invalidateUrlPatternCache } from "../query-fqEdLFms.mjs";
|
|
25
|
+
import "../tokens-D9vnZqYS.mjs";
|
|
26
|
+
import "../bylines-CRNsVG88.mjs";
|
|
27
|
+
import "../load-CyEoextb.mjs";
|
|
26
28
|
import "../index.mjs";
|
|
27
|
-
import { n as VERSION, t as COMMIT } from "../version-
|
|
28
|
-
import { t as getAuthMode } from "../mode-
|
|
29
|
+
import { n as VERSION, t as COMMIT } from "../version-DJrV1K0M.mjs";
|
|
30
|
+
import { t as getAuthMode } from "../mode-BnAOqItE.mjs";
|
|
29
31
|
import { Kysely, sql } from "kysely";
|
|
30
32
|
import { defineMiddleware } from "astro:middleware";
|
|
31
33
|
import virtualConfig from "virtual:emdash/config";
|
|
@@ -281,6 +283,19 @@ var PiggybackScheduler = class {
|
|
|
281
283
|
//#endregion
|
|
282
284
|
//#region src/emdash-runtime.ts
|
|
283
285
|
const LEADING_SLASH_PATTERN = /^\//;
|
|
286
|
+
/**
|
|
287
|
+
* Parse a JSON column expected to contain an array of strings.
|
|
288
|
+
*
|
|
289
|
+
* Throws on malformed JSON rather than returning []; callers are responsible
|
|
290
|
+
* for deciding how to handle/log the error. Empty string / null inputs return
|
|
291
|
+
* [] (they represent "no value"). Non-string array entries are filtered out.
|
|
292
|
+
*/
|
|
293
|
+
function parseStringArray(raw) {
|
|
294
|
+
if (!raw) return [];
|
|
295
|
+
const parsed = JSON.parse(raw);
|
|
296
|
+
if (!Array.isArray(parsed)) return [];
|
|
297
|
+
return parsed.filter((v) => typeof v === "string");
|
|
298
|
+
}
|
|
284
299
|
const VALID_METADATA_KINDS = new Set([
|
|
285
300
|
"meta",
|
|
286
301
|
"property",
|
|
@@ -410,27 +425,27 @@ var EmDashRuntime = class EmDashRuntime {
|
|
|
410
425
|
if (ctx?.db) return ctx.db;
|
|
411
426
|
return this._db;
|
|
412
427
|
}
|
|
413
|
-
constructor(
|
|
414
|
-
this._db = db;
|
|
415
|
-
this.storage = storage;
|
|
416
|
-
this.configuredPlugins = configuredPlugins;
|
|
417
|
-
this.sandboxedPlugins = sandboxedPlugins;
|
|
418
|
-
this.sandboxedPluginEntries = sandboxedPluginEntries;
|
|
419
|
-
this.schemaRegistry = new SchemaRegistry(db);
|
|
420
|
-
this._hooks = hooks;
|
|
421
|
-
this.enabledPlugins = enabledPlugins;
|
|
422
|
-
this.pluginStates = pluginStates;
|
|
423
|
-
this.config = config;
|
|
424
|
-
this.mediaProviders = mediaProviders;
|
|
425
|
-
this.mediaProviderEntries = mediaProviderEntries;
|
|
426
|
-
this.cronExecutor = cronExecutor;
|
|
427
|
-
this.cronScheduler = cronScheduler;
|
|
428
|
-
this.email = emailPipeline;
|
|
429
|
-
this.allPipelinePlugins = allPipelinePlugins;
|
|
430
|
-
this.pipelineFactoryOptions = pipelineFactoryOptions;
|
|
431
|
-
this.runtimeDeps = runtimeDeps;
|
|
432
|
-
this.pipelineRef = pipelineRef;
|
|
433
|
-
this._manifestCacheKey = manifestCacheKey;
|
|
428
|
+
constructor(parts) {
|
|
429
|
+
this._db = parts.db;
|
|
430
|
+
this.storage = parts.storage;
|
|
431
|
+
this.configuredPlugins = parts.configuredPlugins;
|
|
432
|
+
this.sandboxedPlugins = parts.sandboxedPlugins;
|
|
433
|
+
this.sandboxedPluginEntries = parts.sandboxedPluginEntries;
|
|
434
|
+
this.schemaRegistry = new SchemaRegistry(parts.db);
|
|
435
|
+
this._hooks = parts.hooks;
|
|
436
|
+
this.enabledPlugins = parts.enabledPlugins;
|
|
437
|
+
this.pluginStates = parts.pluginStates;
|
|
438
|
+
this.config = parts.config;
|
|
439
|
+
this.mediaProviders = parts.mediaProviders;
|
|
440
|
+
this.mediaProviderEntries = parts.mediaProviderEntries;
|
|
441
|
+
this.cronExecutor = parts.cronExecutor;
|
|
442
|
+
this.cronScheduler = parts.cronScheduler;
|
|
443
|
+
this.email = parts.emailPipeline;
|
|
444
|
+
this.allPipelinePlugins = parts.allPipelinePlugins;
|
|
445
|
+
this.pipelineFactoryOptions = parts.pipelineFactoryOptions;
|
|
446
|
+
this.runtimeDeps = parts.runtimeDeps;
|
|
447
|
+
this.pipelineRef = parts.pipelineRef;
|
|
448
|
+
this._manifestCacheKey = parts.manifestCacheKey;
|
|
434
449
|
}
|
|
435
450
|
/**
|
|
436
451
|
* Get the sandbox runner instance (for marketplace install/update)
|
|
@@ -723,7 +738,27 @@ var EmDashRuntime = class EmDashRuntime {
|
|
|
723
738
|
virtualConfig?.i18n?.defaultLocale ?? "",
|
|
724
739
|
(virtualConfig?.i18n?.locales ?? []).toSorted().join(",")
|
|
725
740
|
].join("|"));
|
|
726
|
-
return new EmDashRuntime(
|
|
741
|
+
return new EmDashRuntime({
|
|
742
|
+
db,
|
|
743
|
+
storage,
|
|
744
|
+
configuredPlugins: deps.plugins,
|
|
745
|
+
sandboxedPlugins,
|
|
746
|
+
sandboxedPluginEntries: deps.sandboxedPluginEntries,
|
|
747
|
+
hooks: pipeline,
|
|
748
|
+
enabledPlugins,
|
|
749
|
+
pluginStates,
|
|
750
|
+
config: deps.config,
|
|
751
|
+
mediaProviders,
|
|
752
|
+
mediaProviderEntries,
|
|
753
|
+
cronExecutor,
|
|
754
|
+
cronScheduler,
|
|
755
|
+
emailPipeline,
|
|
756
|
+
allPipelinePlugins,
|
|
757
|
+
pipelineFactoryOptions,
|
|
758
|
+
runtimeDeps: deps,
|
|
759
|
+
pipelineRef,
|
|
760
|
+
manifestCacheKey
|
|
761
|
+
});
|
|
727
762
|
}
|
|
728
763
|
/**
|
|
729
764
|
* Get a media provider by ID
|
|
@@ -777,9 +812,9 @@ var EmDashRuntime = class EmDashRuntime {
|
|
|
777
812
|
}
|
|
778
813
|
})();
|
|
779
814
|
if (collectionCount.count === 0 && !setupDone) {
|
|
780
|
-
const { applySeed } = await import("../apply-
|
|
781
|
-
const { loadSeed } = await import("../load-
|
|
782
|
-
const { validateSeed } = await import("../validate-
|
|
815
|
+
const { applySeed } = await import("../apply-x0eMK1lX.mjs").then((n) => n.n);
|
|
816
|
+
const { loadSeed } = await import("../load-CyEoextb.mjs").then((n) => n.r);
|
|
817
|
+
const { validateSeed } = await import("../validate-CxVsLehf.mjs").then((n) => n.n);
|
|
783
818
|
const seed = await loadSeed();
|
|
784
819
|
if (validateSeed(seed).valid) {
|
|
785
820
|
await applySeed(db, seed, { onConflict: "skip" });
|
|
@@ -1055,7 +1090,7 @@ var EmDashRuntime = class EmDashRuntime {
|
|
|
1055
1090
|
label: row.label,
|
|
1056
1091
|
labelSingular: row.label_singular ?? void 0,
|
|
1057
1092
|
hierarchical: row.hierarchical === 1,
|
|
1058
|
-
collections:
|
|
1093
|
+
collections: parseStringArray(row.collections).toSorted()
|
|
1059
1094
|
}));
|
|
1060
1095
|
} catch (error) {
|
|
1061
1096
|
console.debug("EmDash: Could not load taxonomy definitions:", error);
|
|
@@ -1143,16 +1178,67 @@ var EmDashRuntime = class EmDashRuntime {
|
|
|
1143
1178
|
return handleContentList(this.db, collection, params);
|
|
1144
1179
|
}
|
|
1145
1180
|
async handleContentGet(collection, id, locale) {
|
|
1146
|
-
|
|
1181
|
+
const result = await handleContentGet(this.db, collection, id, locale);
|
|
1182
|
+
return this.hydrateDraftData(result);
|
|
1147
1183
|
}
|
|
1148
1184
|
async handleContentGetIncludingTrashed(collection, id, locale) {
|
|
1149
|
-
|
|
1185
|
+
const result = await handleContentGetIncludingTrashed(this.db, collection, id, locale);
|
|
1186
|
+
return this.hydrateDraftData(result);
|
|
1187
|
+
}
|
|
1188
|
+
/**
|
|
1189
|
+
* If the response item has a `draftRevisionId`, replace `item.data` with
|
|
1190
|
+
* the draft revision's data and expose the original published values as
|
|
1191
|
+
* `liveData`. This makes the content_get / content_update round-trip
|
|
1192
|
+
* intuitive — read returns the latest content the caller has saved
|
|
1193
|
+
* (their pending draft), with the previously-published values still
|
|
1194
|
+
* accessible for compare-style flows.
|
|
1195
|
+
*
|
|
1196
|
+
* No-op when no draft exists or the response is an error.
|
|
1197
|
+
*/
|
|
1198
|
+
async hydrateDraftData(result) {
|
|
1199
|
+
if (!result || typeof result !== "object") return result;
|
|
1200
|
+
const r = result;
|
|
1201
|
+
if (!r.success || !r.data?.item) return result;
|
|
1202
|
+
const item = r.data.item;
|
|
1203
|
+
const draftRevisionId = typeof item.draftRevisionId === "string" ? item.draftRevisionId : null;
|
|
1204
|
+
if (!draftRevisionId) return result;
|
|
1205
|
+
try {
|
|
1206
|
+
const revision = await new RevisionRepository(this.db).findById(draftRevisionId);
|
|
1207
|
+
if (!revision) return result;
|
|
1208
|
+
const liveData = item.data && typeof item.data === "object" ? item.data : {};
|
|
1209
|
+
const revisionData = {};
|
|
1210
|
+
for (const [key, value] of Object.entries(revision.data)) if (!key.startsWith("_")) revisionData[key] = value;
|
|
1211
|
+
const mergedData = {
|
|
1212
|
+
...liveData,
|
|
1213
|
+
...revisionData
|
|
1214
|
+
};
|
|
1215
|
+
return {
|
|
1216
|
+
...result,
|
|
1217
|
+
data: {
|
|
1218
|
+
...r.data,
|
|
1219
|
+
item: {
|
|
1220
|
+
...item,
|
|
1221
|
+
data: mergedData,
|
|
1222
|
+
liveData
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
};
|
|
1226
|
+
} catch (error) {
|
|
1227
|
+
console.error("[emdash] draft hydration failed:", error);
|
|
1228
|
+
return result;
|
|
1229
|
+
}
|
|
1150
1230
|
}
|
|
1151
1231
|
async handleContentCreate(collection, body) {
|
|
1152
1232
|
let processedData = body.data;
|
|
1153
1233
|
if (this.hooks.hasHooks("content:beforeSave")) processedData = (await this.hooks.runContentBeforeSave(body.data, collection, true)).content;
|
|
1154
1234
|
processedData = await this.runSandboxedBeforeSave(processedData, collection, true);
|
|
1155
1235
|
processedData = await this.normalizeMediaFields(collection, processedData);
|
|
1236
|
+
const { validateContentData } = await import("../validation-C-ZpN2GI.mjs");
|
|
1237
|
+
const validation = await validateContentData(this.db, collection, processedData, { partial: false });
|
|
1238
|
+
if (!validation.ok) return {
|
|
1239
|
+
success: false,
|
|
1240
|
+
error: validation.error
|
|
1241
|
+
};
|
|
1156
1242
|
const result = await handleContentCreate(this.db, collection, {
|
|
1157
1243
|
...body,
|
|
1158
1244
|
data: processedData,
|
|
@@ -1163,7 +1249,7 @@ var EmDashRuntime = class EmDashRuntime {
|
|
|
1163
1249
|
return result;
|
|
1164
1250
|
}
|
|
1165
1251
|
async handleContentUpdate(collection, id, body) {
|
|
1166
|
-
const { ContentRepository } = await import("../content-
|
|
1252
|
+
const { ContentRepository } = await import("../content-BcQPYxdV.mjs").then((n) => n.n);
|
|
1167
1253
|
const repo = new ContentRepository(this.db);
|
|
1168
1254
|
const resolvedItem = await repo.findByIdOrSlug(collection, id);
|
|
1169
1255
|
const resolvedId = resolvedItem?.id ?? id;
|
|
@@ -1190,6 +1276,12 @@ var EmDashRuntime = class EmDashRuntime {
|
|
|
1190
1276
|
if (this.hooks.hasHooks("content:beforeSave")) processedData = (await this.hooks.runContentBeforeSave(bodyWithoutRev.data, collection, false)).content;
|
|
1191
1277
|
processedData = await this.runSandboxedBeforeSave(processedData, collection, false);
|
|
1192
1278
|
processedData = await this.normalizeMediaFields(collection, processedData);
|
|
1279
|
+
const { validateContentData } = await import("../validation-C-ZpN2GI.mjs");
|
|
1280
|
+
const validation = await validateContentData(this.db, collection, processedData, { partial: true });
|
|
1281
|
+
if (!validation.ok) return {
|
|
1282
|
+
success: false,
|
|
1283
|
+
error: validation.error
|
|
1284
|
+
};
|
|
1193
1285
|
}
|
|
1194
1286
|
let usesDraftRevisions = false;
|
|
1195
1287
|
if (processedData) try {
|
|
@@ -1234,8 +1326,9 @@ var EmDashRuntime = class EmDashRuntime {
|
|
|
1234
1326
|
authorId: bodyWithoutRev.authorId,
|
|
1235
1327
|
bylines: bodyWithoutRev.bylines
|
|
1236
1328
|
});
|
|
1237
|
-
|
|
1238
|
-
|
|
1329
|
+
const hydrated = await this.hydrateDraftData(result);
|
|
1330
|
+
if (hydrated.success && hydrated.data) this.runAfterSaveHooks(contentItemToRecord(hydrated.data.item), collection, false);
|
|
1331
|
+
return hydrated;
|
|
1239
1332
|
}
|
|
1240
1333
|
async handleContentDelete(collection, id) {
|
|
1241
1334
|
if (this.hooks.hasHooks("content:beforeDelete")) {
|
|
@@ -1353,7 +1446,47 @@ var EmDashRuntime = class EmDashRuntime {
|
|
|
1353
1446
|
return handleRevisionGet(this.db, revisionId);
|
|
1354
1447
|
}
|
|
1355
1448
|
async handleRevisionRestore(revisionId, callerUserId) {
|
|
1356
|
-
|
|
1449
|
+
const revisionRepo = new RevisionRepository(this.db);
|
|
1450
|
+
const revision = await revisionRepo.findById(revisionId);
|
|
1451
|
+
if (!revision) return {
|
|
1452
|
+
success: false,
|
|
1453
|
+
error: {
|
|
1454
|
+
code: "NOT_FOUND",
|
|
1455
|
+
message: `Revision not found: ${revisionId}`
|
|
1456
|
+
}
|
|
1457
|
+
};
|
|
1458
|
+
if (!((await this.schemaRegistry.getCollectionWithFields(revision.collection))?.supports?.includes("revisions") ?? false)) {
|
|
1459
|
+
const result = await handleRevisionRestore(this.db, revisionId, callerUserId);
|
|
1460
|
+
return this.hydrateDraftData(result);
|
|
1461
|
+
}
|
|
1462
|
+
try {
|
|
1463
|
+
const newDraft = await revisionRepo.create({
|
|
1464
|
+
collection: revision.collection,
|
|
1465
|
+
entryId: revision.entryId,
|
|
1466
|
+
data: revision.data,
|
|
1467
|
+
authorId: callerUserId
|
|
1468
|
+
});
|
|
1469
|
+
validateIdentifier(revision.collection, "collection");
|
|
1470
|
+
const tableName = `ec_${revision.collection}`;
|
|
1471
|
+
await sql`
|
|
1472
|
+
UPDATE ${sql.ref(tableName)}
|
|
1473
|
+
SET draft_revision_id = ${newDraft.id},
|
|
1474
|
+
updated_at = ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
1475
|
+
WHERE id = ${revision.entryId}
|
|
1476
|
+
`.execute(this.db);
|
|
1477
|
+
revisionRepo.pruneOldRevisions(revision.collection, revision.entryId, 50).catch(() => {});
|
|
1478
|
+
const refetched = await handleContentGet(this.db, revision.collection, revision.entryId);
|
|
1479
|
+
return this.hydrateDraftData(refetched);
|
|
1480
|
+
} catch (error) {
|
|
1481
|
+
console.error("[emdash] revision restore failed:", error);
|
|
1482
|
+
return {
|
|
1483
|
+
success: false,
|
|
1484
|
+
error: {
|
|
1485
|
+
code: "REVISION_RESTORE_ERROR",
|
|
1486
|
+
message: "Failed to restore revision"
|
|
1487
|
+
}
|
|
1488
|
+
};
|
|
1489
|
+
}
|
|
1357
1490
|
}
|
|
1358
1491
|
/**
|
|
1359
1492
|
* Get route metadata for a plugin route without invoking the handler.
|
|
@@ -1486,16 +1619,30 @@ var EmDashRuntime = class EmDashRuntime {
|
|
|
1486
1619
|
return true;
|
|
1487
1620
|
}
|
|
1488
1621
|
runAfterSaveHooks(content, collection, isNew) {
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1622
|
+
after(async () => {
|
|
1623
|
+
if (this.hooks.hasHooks("content:afterSave")) try {
|
|
1624
|
+
await this.hooks.runContentAfterSave(content, collection, isNew);
|
|
1625
|
+
} catch (err) {
|
|
1626
|
+
console.error("EmDash afterSave hook error:", err);
|
|
1627
|
+
}
|
|
1628
|
+
const tasks = [];
|
|
1629
|
+
for (const [pluginKey, plugin] of this.sandboxedPlugins) {
|
|
1630
|
+
const [id] = pluginKey.split(":");
|
|
1631
|
+
if (!id || !this.isPluginEnabled(id)) continue;
|
|
1632
|
+
tasks.push((async () => {
|
|
1633
|
+
try {
|
|
1634
|
+
await plugin.invokeHook("content:afterSave", {
|
|
1635
|
+
content,
|
|
1636
|
+
collection,
|
|
1637
|
+
isNew
|
|
1638
|
+
});
|
|
1639
|
+
} catch (err) {
|
|
1640
|
+
console.error(`EmDash: Sandboxed plugin ${id} afterSave error:`, err);
|
|
1641
|
+
}
|
|
1642
|
+
})());
|
|
1643
|
+
}
|
|
1644
|
+
await Promise.allSettled(tasks);
|
|
1645
|
+
});
|
|
1499
1646
|
}
|
|
1500
1647
|
runAfterDeleteHooks(id, collection, permanent) {
|
|
1501
1648
|
if (this.hooks.hasHooks("content:afterDelete")) this.hooks.runContentAfterDelete(id, collection, permanent).catch((err) => console.error("EmDash afterDelete hook error:", err));
|
|
@@ -1510,15 +1657,29 @@ var EmDashRuntime = class EmDashRuntime {
|
|
|
1510
1657
|
}
|
|
1511
1658
|
}
|
|
1512
1659
|
runAfterPublishHooks(content, collection) {
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1660
|
+
after(async () => {
|
|
1661
|
+
if (this.hooks.hasHooks("content:afterPublish")) try {
|
|
1662
|
+
await this.hooks.runContentAfterPublish(content, collection);
|
|
1663
|
+
} catch (err) {
|
|
1664
|
+
console.error("EmDash afterPublish hook error:", err);
|
|
1665
|
+
}
|
|
1666
|
+
const tasks = [];
|
|
1667
|
+
for (const [pluginKey, plugin] of this.sandboxedPlugins) {
|
|
1668
|
+
const [pluginId] = pluginKey.split(":");
|
|
1669
|
+
if (!pluginId || !this.isPluginEnabled(pluginId)) continue;
|
|
1670
|
+
tasks.push((async () => {
|
|
1671
|
+
try {
|
|
1672
|
+
await plugin.invokeHook("content:afterPublish", {
|
|
1673
|
+
content,
|
|
1674
|
+
collection
|
|
1675
|
+
});
|
|
1676
|
+
} catch (err) {
|
|
1677
|
+
console.error(`EmDash: Sandboxed plugin ${pluginId} afterPublish error:`, err);
|
|
1678
|
+
}
|
|
1679
|
+
})());
|
|
1680
|
+
}
|
|
1681
|
+
await Promise.allSettled(tasks);
|
|
1682
|
+
});
|
|
1522
1683
|
}
|
|
1523
1684
|
runAfterUnpublishHooks(content, collection) {
|
|
1524
1685
|
if (this.hooks.hasHooks("content:afterUnpublish")) this.hooks.runContentAfterUnpublish(content, collection).catch((err) => console.error("EmDash afterUnpublish hook error:", err));
|
|
@@ -1629,6 +1790,28 @@ var EmDashRuntime = class EmDashRuntime {
|
|
|
1629
1790
|
}
|
|
1630
1791
|
};
|
|
1631
1792
|
|
|
1793
|
+
//#endregion
|
|
1794
|
+
//#region src/media/url.ts
|
|
1795
|
+
/**
|
|
1796
|
+
* Resolve the public URL for a locally stored media key. Returns an empty
|
|
1797
|
+
* string when no key is given. When a storage adapter is supplied, defers to
|
|
1798
|
+
* `storage.getPublicUrl()`; otherwise returns the internal proxy route.
|
|
1799
|
+
*/
|
|
1800
|
+
function resolvePublicMediaUrl(storage, storageKey) {
|
|
1801
|
+
if (!storageKey) return "";
|
|
1802
|
+
if (storage) return storage.getPublicUrl(storageKey);
|
|
1803
|
+
return `/_emdash/api/media/file/${storageKey}`;
|
|
1804
|
+
}
|
|
1805
|
+
/**
|
|
1806
|
+
* Build the `getPublicMediaUrl` closure attached to `Astro.locals.emdash`.
|
|
1807
|
+
* Shared by the anonymous fast path and the full-runtime path in middleware.
|
|
1808
|
+
*
|
|
1809
|
+
* @internal
|
|
1810
|
+
*/
|
|
1811
|
+
function createPublicMediaUrlResolver(storage) {
|
|
1812
|
+
return (key) => resolvePublicMediaUrl(storage, key);
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1632
1815
|
//#endregion
|
|
1633
1816
|
//#region src/astro/middleware.ts
|
|
1634
1817
|
/**
|
|
@@ -1751,6 +1934,9 @@ function createRequestScopedDb$1(opts) {
|
|
|
1751
1934
|
const onRequest = defineMiddleware(async (context, next) => {
|
|
1752
1935
|
const { request, locals, cookies } = context;
|
|
1753
1936
|
const url = context.url;
|
|
1937
|
+
if (!url.pathname.startsWith("/_emdash") && virtualConfig?.authProviders) {
|
|
1938
|
+
if (virtualConfig.authProviders.some((p) => p.routes?.some((r) => r.pattern && url.pathname === r.pattern))) return finalizeResponse(await next());
|
|
1939
|
+
}
|
|
1754
1940
|
const queryRecorder = isInstrumentationEnabled() ? createRecorder(url.pathname, request.method, request.headers.get("x-perf-phase") ?? "default") : void 0;
|
|
1755
1941
|
const run = async () => {
|
|
1756
1942
|
const isEmDashRoute = url.pathname.startsWith("/_emdash");
|
|
@@ -1766,7 +1952,7 @@ const onRequest = defineMiddleware(async (context, next) => {
|
|
|
1766
1952
|
if (!setupVerified) {
|
|
1767
1953
|
const t0 = performance.now();
|
|
1768
1954
|
try {
|
|
1769
|
-
const { getDb } = await import("../loader-
|
|
1955
|
+
const { getDb } = await import("../loader-CndGj8kM.mjs").then((n) => n.r);
|
|
1770
1956
|
await (await getDb()).selectFrom("_emdash_migrations").selectAll().limit(1).execute();
|
|
1771
1957
|
setupVerified = true;
|
|
1772
1958
|
} catch {
|
|
@@ -1787,7 +1973,8 @@ const onRequest = defineMiddleware(async (context, next) => {
|
|
|
1787
1973
|
setupVerified = true;
|
|
1788
1974
|
locals.emdash = {
|
|
1789
1975
|
collectPageMetadata: runtime.collectPageMetadata.bind(runtime),
|
|
1790
|
-
collectPageFragments: runtime.collectPageFragments.bind(runtime)
|
|
1976
|
+
collectPageFragments: runtime.collectPageFragments.bind(runtime),
|
|
1977
|
+
getPublicMediaUrl: createPublicMediaUrlResolver(runtime.storage)
|
|
1791
1978
|
};
|
|
1792
1979
|
} catch {}
|
|
1793
1980
|
timings.push({
|
|
@@ -1900,6 +2087,7 @@ const onRequest = defineMiddleware(async (context, next) => {
|
|
|
1900
2087
|
ensureSearchHealthy: runtime.ensureSearchHealthy.bind(runtime),
|
|
1901
2088
|
storage: runtime.storage,
|
|
1902
2089
|
db: runtime.db,
|
|
2090
|
+
getPublicMediaUrl: createPublicMediaUrlResolver(runtime.storage),
|
|
1903
2091
|
hooks: runtime.hooks,
|
|
1904
2092
|
email: runtime.email,
|
|
1905
2093
|
configuredPlugins: runtime.configuredPlugins,
|