emdash 0.3.0 → 0.4.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-BLMa4JGD.d.mts → adapters-C2BzVy0p.d.mts} +1 -1
- package/dist/{adapters-BLMa4JGD.d.mts.map → adapters-C2BzVy0p.d.mts.map} +1 -1
- package/dist/{apply-Bqoekfbe.mjs → apply-Cma_PiF6.mjs} +37 -22
- package/dist/apply-Cma_PiF6.mjs.map +1 -0
- package/dist/astro/index.d.mts +6 -6
- package/dist/astro/index.mjs +9 -8
- package/dist/astro/index.mjs.map +1 -1
- package/dist/astro/middleware/auth.d.mts +5 -5
- package/dist/astro/middleware/auth.mjs +2 -2
- package/dist/astro/middleware/redirect.d.mts.map +1 -1
- package/dist/astro/middleware/redirect.mjs +19 -7
- package/dist/astro/middleware/redirect.mjs.map +1 -1
- package/dist/astro/middleware/request-context.mjs +12 -2
- 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 +45 -42
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/types.d.mts +8 -8
- package/dist/{byline-BGj9p9Ht.mjs → byline-WuOq9MFJ.mjs} +3 -2
- package/dist/byline-WuOq9MFJ.mjs.map +1 -0
- package/dist/{bylines-BihaoIDY.mjs → bylines-C_Wsnz4L.mjs} +36 -4
- package/dist/bylines-C_Wsnz4L.mjs.map +1 -0
- package/dist/cache-E3Dts-yT.mjs +56 -0
- package/dist/cache-E3Dts-yT.mjs.map +1 -0
- package/dist/cli/index.mjs +11 -11
- 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/{config-Cq8H0SfX.mjs → config-DkxPrM9l.mjs} +1 -1
- package/dist/{config-Cq8H0SfX.mjs.map → config-DkxPrM9l.mjs.map} +1 -1
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +1 -1
- package/dist/db/libsql.d.mts +1 -1
- package/dist/db/postgres.d.mts +1 -1
- package/dist/db/sqlite.d.mts +1 -1
- package/dist/{default-WYlzADZL.mjs → default-PUx9RK6u.mjs} +1 -1
- package/dist/{default-WYlzADZL.mjs.map → default-PUx9RK6u.mjs.map} +1 -1
- package/dist/{error-DrxtnGPg.mjs → error-HBeQbVhV.mjs} +1 -1
- package/dist/{error-DrxtnGPg.mjs.map → error-HBeQbVhV.mjs.map} +1 -1
- package/dist/{index-Cff7AimE.d.mts → index-CRg3PWfZ.d.mts} +32 -30
- package/dist/index-CRg3PWfZ.d.mts.map +1 -0
- package/dist/index.d.mts +11 -11
- package/dist/index.mjs +17 -17
- package/dist/{load-Veizk2cT.mjs → load-BhSSm-TS.mjs} +1 -1
- package/dist/{load-Veizk2cT.mjs.map → load-BhSSm-TS.mjs.map} +1 -1
- package/dist/{loader-BmYdf3Dr.mjs → loader-BYzwzORf.mjs} +1 -1
- package/dist/{loader-BmYdf3Dr.mjs.map → loader-BYzwzORf.mjs.map} +1 -1
- package/dist/{manifest-schema-CuMio1A9.mjs → manifest-schema-BsXINkQD.mjs} +1 -1
- package/dist/{manifest-schema-CuMio1A9.mjs.map → manifest-schema-BsXINkQD.mjs.map} +1 -1
- 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/{mode-C2EzN1uE.mjs → mode-CyPLdO3C.mjs} +1 -1
- package/dist/{mode-C2EzN1uE.mjs.map → mode-CyPLdO3C.mjs.map} +1 -1
- package/dist/page/index.d.mts +1 -1
- package/dist/patterns-CrCYkMBb.mjs +93 -0
- package/dist/patterns-CrCYkMBb.mjs.map +1 -0
- package/dist/{placeholder-SvFCKbz_.d.mts → placeholder-BBCtpTES.d.mts} +1 -1
- package/dist/{placeholder-SvFCKbz_.d.mts.map → placeholder-BBCtpTES.d.mts.map} +1 -1
- package/dist/{placeholder-aiCD8aSZ.mjs → placeholder-DntBEQo7.mjs} +1 -1
- package/dist/{placeholder-aiCD8aSZ.mjs.map → placeholder-DntBEQo7.mjs.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-sesiOndV.mjs → query-B6Vu0d2i.mjs} +34 -15
- package/dist/{query-sesiOndV.mjs.map → query-B6Vu0d2i.mjs.map} +1 -1
- package/dist/{redirect-DUAk-Yl_.mjs → redirect-7lGhLBNZ.mjs} +2 -92
- package/dist/redirect-7lGhLBNZ.mjs.map +1 -0
- package/dist/{registry-DU18yVo0.mjs → registry-BgnP3ysR.mjs} +19 -35
- package/dist/registry-BgnP3ysR.mjs.map +1 -0
- package/dist/{runner-Biufrii2.mjs → runner-Cd-_WyDo.mjs} +16 -4
- package/dist/runner-Cd-_WyDo.mjs.map +1 -0
- package/dist/{runner-EAtf0ZIe.d.mts → runner-DYv3rX8P.d.mts} +10 -3
- package/dist/runner-DYv3rX8P.d.mts.map +1 -0
- package/dist/runtime.d.mts +6 -6
- package/dist/runtime.mjs +1 -1
- package/dist/{search-BXB-jfu2.mjs → search-B5p9D36n.mjs} +102 -53
- package/dist/search-B5p9D36n.mjs.map +1 -0
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +8 -8
- 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.mjs +1 -1
- package/dist/{tokens-DrB-W6Q-.mjs → tokens-DKHiCYCB.mjs} +1 -1
- package/dist/{tokens-DrB-W6Q-.mjs.map → tokens-DKHiCYCB.mjs.map} +1 -1
- package/dist/transaction-Cn2rjY78.mjs +28 -0
- package/dist/transaction-Cn2rjY78.mjs.map +1 -0
- package/dist/{transport-yxiQsi8I.mjs → transport-BtcQ-Z7T.mjs} +1 -1
- package/dist/{transport-yxiQsi8I.mjs.map → transport-BtcQ-Z7T.mjs.map} +1 -1
- package/dist/{transport-BFGblqwG.d.mts → transport-CKQA_G44.d.mts} +1 -1
- package/dist/{transport-BFGblqwG.d.mts.map → transport-CKQA_G44.d.mts.map} +1 -1
- package/dist/{types-DRjfYOEv.d.mts → types-B6BzlZxx.d.mts} +1 -1
- package/dist/{types-DRjfYOEv.d.mts.map → types-B6BzlZxx.d.mts.map} +1 -1
- package/dist/{types-CaKte3hR.d.mts → types-BYWYxLcp.d.mts} +10 -4
- package/dist/types-BYWYxLcp.d.mts.map +1 -0
- package/dist/{types-BbsYgi_R.d.mts → types-BmkQR1En.d.mts} +1 -1
- package/dist/{types-BbsYgi_R.d.mts.map → types-BmkQR1En.d.mts.map} +1 -1
- package/dist/{types-C1-PVaS_.d.mts → types-DNZpaCBk.d.mts} +1 -1
- package/dist/{types-C1-PVaS_.d.mts.map → types-DNZpaCBk.d.mts.map} +1 -1
- package/dist/{types-Bec-r_3_.mjs → types-Dz9_WMS6.mjs} +1 -1
- package/dist/{types-Bec-r_3_.mjs.map → types-Dz9_WMS6.mjs.map} +1 -1
- package/dist/{types-DPfzHnjW.d.mts → types-gLYVCXCQ.d.mts} +1 -1
- package/dist/{types-DPfzHnjW.d.mts.map → types-gLYVCXCQ.d.mts.map} +1 -1
- package/dist/{types-DuNbGKjF.mjs → types-xxCWI3j0.mjs} +1 -1
- package/dist/{types-DuNbGKjF.mjs.map → types-xxCWI3j0.mjs.map} +1 -1
- package/dist/{validate-bfg9OR6N.d.mts → validate-CcNRWH6I.d.mts} +4 -4
- package/dist/{validate-bfg9OR6N.d.mts.map → validate-CcNRWH6I.d.mts.map} +1 -1
- package/dist/{validate-CXnRKfJK.mjs → validate-DuZDIxfy.mjs} +2 -2
- package/dist/{validate-CXnRKfJK.mjs.map → validate-DuZDIxfy.mjs.map} +1 -1
- package/dist/version-DlTDRdpv.mjs +7 -0
- package/dist/{version-REAapfsU.mjs.map → version-DlTDRdpv.mjs.map} +1 -1
- package/package.json +7 -5
- package/src/api/handlers/content.ts +36 -25
- package/src/api/handlers/menus.ts +19 -16
- package/src/astro/integration/index.ts +2 -3
- package/src/astro/integration/runtime.ts +8 -14
- package/src/astro/integration/vite-config.ts +7 -0
- package/src/astro/middleware/redirect.ts +30 -15
- package/src/astro/middleware.ts +11 -19
- package/src/astro/routes/api/admin/bylines/[id]/index.ts +3 -0
- package/src/astro/routes/api/admin/bylines/index.ts +2 -0
- package/src/astro/routes/api/redirects/[id].ts +3 -0
- package/src/astro/routes/api/redirects/index.ts +2 -0
- package/src/astro/routes/api/schema/collections/[slug]/index.ts +2 -0
- package/src/astro/routes/api/schema/collections/index.ts +1 -0
- package/src/bylines/index.ts +48 -0
- package/src/cleanup.ts +3 -3
- package/src/cli/commands/bundle-utils.ts +5 -5
- package/src/database/migrations/011_sections.ts +2 -2
- package/src/database/migrations/runner.ts +23 -2
- package/src/database/repositories/byline.ts +2 -1
- package/src/emdash-runtime.ts +18 -8
- package/src/index.ts +2 -0
- package/src/mcp/server.ts +40 -67
- package/src/plugins/context.ts +28 -4
- package/src/plugins/cron.ts +29 -4
- package/src/plugins/hooks.ts +22 -10
- package/src/plugins/index.ts +1 -0
- package/src/plugins/manager.ts +6 -2
- package/src/plugins/marketplace.ts +33 -3
- package/src/plugins/routes.ts +3 -3
- package/src/plugins/types.ts +7 -0
- package/src/query.ts +37 -14
- package/src/redirects/cache.ts +68 -0
- package/src/search/fts-manager.ts +20 -11
- package/src/search/query.ts +8 -9
- package/src/seed/apply.ts +49 -28
- package/src/visual-editing/toolbar.ts +11 -1
- package/dist/apply-Bqoekfbe.mjs.map +0 -1
- package/dist/byline-BGj9p9Ht.mjs.map +0 -1
- package/dist/bylines-BihaoIDY.mjs.map +0 -1
- package/dist/index-Cff7AimE.d.mts.map +0 -1
- package/dist/redirect-DUAk-Yl_.mjs.map +0 -1
- package/dist/registry-DU18yVo0.mjs.map +0 -1
- package/dist/runner-Biufrii2.mjs.map +0 -1
- package/dist/runner-EAtf0ZIe.d.mts.map +0 -1
- package/dist/search-BXB-jfu2.mjs.map +0 -1
- package/dist/types-CaKte3hR.d.mts.map +0 -1
- package/dist/version-REAapfsU.mjs +0 -7
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as Database } from "./types-
|
|
1
|
+
import { t as Database } from "./types-B6BzlZxx.mjs";
|
|
2
2
|
import { Kysely } from "kysely";
|
|
3
3
|
|
|
4
4
|
//#region src/database/migrations/runner.d.ts
|
|
@@ -11,7 +11,14 @@ interface MigrationStatus {
|
|
|
11
11
|
*/
|
|
12
12
|
declare function getMigrationStatus(db: Kysely<Database>): Promise<MigrationStatus>;
|
|
13
13
|
/**
|
|
14
|
-
* Run all pending migrations
|
|
14
|
+
* Run all pending migrations.
|
|
15
|
+
*
|
|
16
|
+
* Includes a fast-path: if the migration table already exists and contains
|
|
17
|
+
* exactly MIGRATION_COUNT rows, all migrations have been applied and we can
|
|
18
|
+
* skip the Kysely Migrator entirely. This avoids the expensive
|
|
19
|
+
* `pragma_table_info` introspection that Kysely runs for every table in the
|
|
20
|
+
* database (twice!) just to check if the migration tables exist.
|
|
21
|
+
* On D1 with ~57 tables, that's ~116 queries saved per init.
|
|
15
22
|
*/
|
|
16
23
|
declare function runMigrations(db: Kysely<Database>): Promise<{
|
|
17
24
|
applied: string[];
|
|
@@ -24,4 +31,4 @@ declare function rollbackMigration(db: Kysely<Database>): Promise<{
|
|
|
24
31
|
}>;
|
|
25
32
|
//#endregion
|
|
26
33
|
export { runMigrations as i, getMigrationStatus as n, rollbackMigration as r, MigrationStatus as t };
|
|
27
|
-
//# sourceMappingURL=runner-
|
|
34
|
+
//# sourceMappingURL=runner-DYv3rX8P.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner-DYv3rX8P.d.mts","names":[],"sources":["../src/database/migrations/runner.ts"],"mappings":";;;;UAuFiB,eAAA;EAChB,OAAA;EACA,OAAA;AAAA;;AAUD;;iBAAsB,kBAAA,CAAmB,EAAA,EAAI,MAAA,CAAO,QAAA,IAAY,OAAA,CAAQ,eAAA;;;;;;;;;;;iBAkClD,aAAA,CAAc,EAAA,EAAI,MAAA,CAAO,QAAA,IAAY,OAAA;EAAU,OAAA;AAAA;AAArE;;;AAAA,iBA8CsB,iBAAA,CACrB,EAAA,EAAI,MAAA,CAAO,QAAA,IACT,OAAA;EAAU,UAAA;AAAA"}
|
package/dist/runtime.d.mts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { f as MediaProvider } from "./placeholder-
|
|
2
|
-
import "./types-
|
|
3
|
-
import { Fn as getDb, Mn as EntryData, Nn as EntryFilter, Pn as emdashLoader, jn as CollectionFilter } from "./index-
|
|
4
|
-
import "./runner-
|
|
5
|
-
import "./types-
|
|
6
|
-
import "./validate-
|
|
1
|
+
import { f as MediaProvider } from "./placeholder-BBCtpTES.mjs";
|
|
2
|
+
import "./types-B6BzlZxx.mjs";
|
|
3
|
+
import { Fn as getDb, Mn as EntryData, Nn as EntryFilter, Pn as emdashLoader, jn as CollectionFilter } from "./index-CRg3PWfZ.mjs";
|
|
4
|
+
import "./runner-DYv3rX8P.mjs";
|
|
5
|
+
import "./types-BYWYxLcp.mjs";
|
|
6
|
+
import "./validate-CcNRWH6I.mjs";
|
|
7
7
|
|
|
8
8
|
//#region src/media/provider-loader.d.ts
|
|
9
9
|
/**
|
package/dist/runtime.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "./dialect-helpers-DhTzaUxP.mjs";
|
|
2
2
|
import "./base64-MBPo9ozB.mjs";
|
|
3
3
|
import "./types-CMMN0pNg.mjs";
|
|
4
|
-
import { n as getDb, t as emdashLoader } from "./loader-
|
|
4
|
+
import { n as getDb, t as emdashLoader } from "./loader-BYzwzORf.mjs";
|
|
5
5
|
|
|
6
6
|
//#region src/media/provider-loader.ts
|
|
7
7
|
let virtualMediaProviders;
|
|
@@ -4,14 +4,16 @@ import { a as slugify, r as RevisionRepository, t as ContentRepository } from ".
|
|
|
4
4
|
import { r as encodeBase64, t as decodeBase64 } from "./base64-MBPo9ozB.mjs";
|
|
5
5
|
import { n as decodeCursor, r as encodeCursor, t as EmDashValidationError } from "./types-CMMN0pNg.mjs";
|
|
6
6
|
import { t as MediaRepository } from "./media-DqHVh136.mjs";
|
|
7
|
-
import { a as stripCredentialHeaders, f as OptionsRepository, i as ssrfSafeFetch, o as validateExternalUrl, r as SsrfError } from "./apply-
|
|
8
|
-
import {
|
|
9
|
-
import { t as RedirectRepository } from "./redirect-
|
|
10
|
-
import { n as SQL_BATCH_SIZE, r as chunks, t as BylineRepository } from "./byline-
|
|
11
|
-
import { r as isI18nEnabled } from "./config-
|
|
12
|
-
import {
|
|
13
|
-
import { i as
|
|
14
|
-
import {
|
|
7
|
+
import { a as stripCredentialHeaders, f as OptionsRepository, i as ssrfSafeFetch, o as validateExternalUrl, r as SsrfError } from "./apply-Cma_PiF6.mjs";
|
|
8
|
+
import { t as withTransaction } from "./transaction-Cn2rjY78.mjs";
|
|
9
|
+
import { t as RedirectRepository } from "./redirect-7lGhLBNZ.mjs";
|
|
10
|
+
import { n as SQL_BATCH_SIZE, r as chunks, t as BylineRepository } from "./byline-WuOq9MFJ.mjs";
|
|
11
|
+
import { r as isI18nEnabled } from "./config-DkxPrM9l.mjs";
|
|
12
|
+
import { r as invalidateRedirectCache } from "./cache-E3Dts-yT.mjs";
|
|
13
|
+
import { i as FTSManager, n as SchemaRegistry } from "./registry-BgnP3ysR.mjs";
|
|
14
|
+
import { n as getDb } from "./loader-BYzwzORf.mjs";
|
|
15
|
+
import { i as pluginManifestSchema } from "./manifest-schema-BsXINkQD.mjs";
|
|
16
|
+
import { t as generatePreviewToken } from "./tokens-DKHiCYCB.mjs";
|
|
15
17
|
import { sql } from "kysely";
|
|
16
18
|
import { ulid } from "ulidx";
|
|
17
19
|
import { z } from "astro/zod";
|
|
@@ -1278,34 +1280,18 @@ async function handleContentUpdate(db, collection, id, body) {
|
|
|
1278
1280
|
message: `Collection "${collection}" does not have SEO enabled. Remove the seo field or enable SEO on this collection.`
|
|
1279
1281
|
}
|
|
1280
1282
|
};
|
|
1281
|
-
const
|
|
1282
|
-
const resolvedId = await resolveId(repo, collection, id) ?? id;
|
|
1283
|
-
if (body._rev) {
|
|
1284
|
-
const existing = await repo.findById(collection, resolvedId);
|
|
1285
|
-
if (!existing) return {
|
|
1286
|
-
success: false,
|
|
1287
|
-
error: {
|
|
1288
|
-
code: "NOT_FOUND",
|
|
1289
|
-
message: `Content item not found: ${id}`
|
|
1290
|
-
}
|
|
1291
|
-
};
|
|
1292
|
-
const revCheck = validateRev(body._rev, existing);
|
|
1293
|
-
if (!revCheck.valid) return {
|
|
1294
|
-
success: false,
|
|
1295
|
-
error: {
|
|
1296
|
-
code: "CONFLICT",
|
|
1297
|
-
message: revCheck.message
|
|
1298
|
-
}
|
|
1299
|
-
};
|
|
1300
|
-
}
|
|
1283
|
+
const resolvedId = await resolveId(new ContentRepository(db), collection, id) ?? id;
|
|
1301
1284
|
const item = await withTransaction(db, async (trx) => {
|
|
1302
1285
|
const trxRepo = new ContentRepository(trx);
|
|
1303
1286
|
const bylineRepo = new BylineRepository(trx);
|
|
1304
|
-
|
|
1305
|
-
if (body.
|
|
1306
|
-
|
|
1307
|
-
|
|
1287
|
+
const existing = body._rev || body.slug ? await trxRepo.findById(collection, resolvedId) : null;
|
|
1288
|
+
if (body._rev) {
|
|
1289
|
+
if (!existing) throw Object.assign(/* @__PURE__ */ new Error(`Content item not found: ${id}`), { apiError: { code: "NOT_FOUND" } });
|
|
1290
|
+
const revCheck = validateRev(body._rev, existing);
|
|
1291
|
+
if (!revCheck.valid) throw Object.assign(new Error(revCheck.message), { apiError: { code: "CONFLICT" } });
|
|
1308
1292
|
}
|
|
1293
|
+
let oldSlug;
|
|
1294
|
+
if (body.slug && existing?.slug && existing.slug !== body.slug) oldSlug = existing.slug;
|
|
1309
1295
|
const updated = await trxRepo.update(collection, resolvedId, {
|
|
1310
1296
|
data: body.data,
|
|
1311
1297
|
slug: body.slug,
|
|
@@ -1319,6 +1305,7 @@ async function handleContentUpdate(db, collection, id, body) {
|
|
|
1319
1305
|
if (oldSlug && body.slug) {
|
|
1320
1306
|
const collectionRow = await trx.selectFrom("_emdash_collections").select("url_pattern").where("slug", "=", collection).executeTakeFirst();
|
|
1321
1307
|
await new RedirectRepository(trx).createAutoRedirect(collection, oldSlug, body.slug, resolvedId, collectionRow?.url_pattern ?? null);
|
|
1308
|
+
invalidateRedirectCache();
|
|
1322
1309
|
}
|
|
1323
1310
|
if (isI18nEnabled() && body.data && updated.translationGroup) await syncNonTranslatableFields(trx, collection, updated.id, updated.translationGroup, body.data);
|
|
1324
1311
|
if (body.seo && hasSeo) updated.seo = await new SeoRepository(trx).upsert(collection, resolvedId, body.seo);
|
|
@@ -1334,6 +1321,16 @@ async function handleContentUpdate(db, collection, id, body) {
|
|
|
1334
1321
|
}
|
|
1335
1322
|
};
|
|
1336
1323
|
} catch (error) {
|
|
1324
|
+
if (error instanceof Error && "apiError" in error) {
|
|
1325
|
+
const { code } = error.apiError;
|
|
1326
|
+
return {
|
|
1327
|
+
success: false,
|
|
1328
|
+
error: {
|
|
1329
|
+
code,
|
|
1330
|
+
message: error.message
|
|
1331
|
+
}
|
|
1332
|
+
};
|
|
1333
|
+
}
|
|
1337
1334
|
console.error("Content update error:", error);
|
|
1338
1335
|
return {
|
|
1339
1336
|
success: false,
|
|
@@ -5131,12 +5128,31 @@ var CronExecutor = class {
|
|
|
5131
5128
|
hookFailed = true;
|
|
5132
5129
|
console.error(`[cron] Hook failed for ${task.plugin_id}:${task.task_name}:`, error);
|
|
5133
5130
|
}
|
|
5134
|
-
if (task.is_oneshot) if (hookFailed)
|
|
5131
|
+
if (task.is_oneshot) if (hookFailed) {
|
|
5132
|
+
const meta = parsedData?.__emdash != null && typeof parsedData.__emdash === "object" ? parsedData.__emdash : void 0;
|
|
5133
|
+
const raw = meta?.retryCount;
|
|
5134
|
+
const retryCount = typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? Math.floor(raw) : 0;
|
|
5135
|
+
const MAX_ONESHOT_RETRIES = 5;
|
|
5136
|
+
if (retryCount >= MAX_ONESHOT_RETRIES) {
|
|
5137
|
+
console.error(`[cron] One-shot task ${task.plugin_id}:${task.task_name} exceeded ${MAX_ONESHOT_RETRIES} retries, removing`);
|
|
5138
|
+
await sql`
|
|
5139
|
+
DELETE FROM _emdash_cron_tasks WHERE id = ${task.id}
|
|
5140
|
+
`.execute(this.db);
|
|
5141
|
+
} else {
|
|
5142
|
+
const backoffMs = 6e4 * Math.pow(2, retryCount);
|
|
5143
|
+
await sql`
|
|
5135
5144
|
UPDATE _emdash_cron_tasks
|
|
5136
|
-
SET status = 'idle', locked_at = NULL, next_run_at = ${new Date(Date.now() +
|
|
5145
|
+
SET status = 'idle', locked_at = NULL, next_run_at = ${new Date(Date.now() + backoffMs).toISOString()}, data = ${JSON.stringify({
|
|
5146
|
+
...parsedData,
|
|
5147
|
+
__emdash: {
|
|
5148
|
+
...meta,
|
|
5149
|
+
retryCount: retryCount + 1
|
|
5150
|
+
}
|
|
5151
|
+
})}
|
|
5137
5152
|
WHERE id = ${task.id}
|
|
5138
5153
|
`.execute(this.db);
|
|
5139
|
-
|
|
5154
|
+
}
|
|
5155
|
+
} else await sql`
|
|
5140
5156
|
DELETE FROM _emdash_cron_tasks WHERE id = ${task.id}
|
|
5141
5157
|
`.execute(this.db);
|
|
5142
5158
|
else await sql`
|
|
@@ -5400,9 +5416,13 @@ function createContentAccess(db) {
|
|
|
5400
5416
|
const result = {
|
|
5401
5417
|
id: item.id,
|
|
5402
5418
|
type: item.type,
|
|
5419
|
+
slug: item.slug,
|
|
5420
|
+
status: item.status,
|
|
5403
5421
|
data: item.data,
|
|
5404
5422
|
createdAt: item.createdAt,
|
|
5405
|
-
updatedAt: item.updatedAt
|
|
5423
|
+
updatedAt: item.updatedAt,
|
|
5424
|
+
locale: item.locale,
|
|
5425
|
+
publishedAt: item.publishedAt
|
|
5406
5426
|
};
|
|
5407
5427
|
if (await seoRepo.isEnabled(collection)) result.seo = await seoRepo.get(collection, item.id);
|
|
5408
5428
|
return result;
|
|
@@ -5424,9 +5444,13 @@ function createContentAccess(db) {
|
|
|
5424
5444
|
const items = result.items.map((item) => ({
|
|
5425
5445
|
id: item.id,
|
|
5426
5446
|
type: item.type,
|
|
5447
|
+
slug: item.slug,
|
|
5448
|
+
status: item.status,
|
|
5427
5449
|
data: item.data,
|
|
5428
5450
|
createdAt: item.createdAt,
|
|
5429
|
-
updatedAt: item.updatedAt
|
|
5451
|
+
updatedAt: item.updatedAt,
|
|
5452
|
+
locale: item.locale,
|
|
5453
|
+
publishedAt: item.publishedAt
|
|
5430
5454
|
}));
|
|
5431
5455
|
if (items.length > 0 && await seoRepo.isEnabled(collection)) {
|
|
5432
5456
|
const seoMap = await seoRepo.getMany(collection, items.map((i) => i.id));
|
|
@@ -5468,9 +5492,13 @@ function createContentAccessWithWrite(db) {
|
|
|
5468
5492
|
const result = {
|
|
5469
5493
|
id: item.id,
|
|
5470
5494
|
type: item.type,
|
|
5495
|
+
slug: item.slug,
|
|
5496
|
+
status: item.status,
|
|
5471
5497
|
data: item.data,
|
|
5472
5498
|
createdAt: item.createdAt,
|
|
5473
|
-
updatedAt: item.updatedAt
|
|
5499
|
+
updatedAt: item.updatedAt,
|
|
5500
|
+
locale: item.locale,
|
|
5501
|
+
publishedAt: item.publishedAt
|
|
5474
5502
|
};
|
|
5475
5503
|
if (hasSeo) result.seo = seo !== void 0 ? await trxSeoRepo.upsert(collection, item.id, seo) : await trxSeoRepo.get(collection, item.id);
|
|
5476
5504
|
return result;
|
|
@@ -5490,9 +5518,13 @@ function createContentAccessWithWrite(db) {
|
|
|
5490
5518
|
const result = {
|
|
5491
5519
|
id: item.id,
|
|
5492
5520
|
type: item.type,
|
|
5521
|
+
slug: item.slug,
|
|
5522
|
+
status: item.status,
|
|
5493
5523
|
data: item.data,
|
|
5494
5524
|
createdAt: item.createdAt,
|
|
5495
|
-
updatedAt: item.updatedAt
|
|
5525
|
+
updatedAt: item.updatedAt,
|
|
5526
|
+
locale: item.locale,
|
|
5527
|
+
publishedAt: item.publishedAt
|
|
5496
5528
|
};
|
|
5497
5529
|
if (hasSeo) result.seo = seo !== void 0 ? await trxSeoRepo.upsert(collection, item.id, seo) : await trxSeoRepo.get(collection, item.id);
|
|
5498
5530
|
return result;
|
|
@@ -5553,17 +5585,18 @@ function createMediaAccessWithWrite(db, getUploadUrlFn, storage) {
|
|
|
5553
5585
|
getUploadUrl: getUploadUrlFn,
|
|
5554
5586
|
async upload(filename, contentType, bytes) {
|
|
5555
5587
|
if (!storage) throw new Error("Media upload() requires a storage backend. Configure storage in PluginContextFactoryOptions.");
|
|
5556
|
-
const
|
|
5588
|
+
const keyPrefix = ulid();
|
|
5557
5589
|
const basename = filename.split("/").pop() ?? filename;
|
|
5558
5590
|
const dotIdx = basename.lastIndexOf(".");
|
|
5559
|
-
const storageKey = `${
|
|
5591
|
+
const storageKey = `${keyPrefix}${dotIdx > 0 ? basename.slice(dotIdx).toLowerCase() : ""}`;
|
|
5560
5592
|
await storage.upload({
|
|
5561
5593
|
key: storageKey,
|
|
5562
5594
|
body: new Uint8Array(bytes),
|
|
5563
5595
|
contentType
|
|
5564
5596
|
});
|
|
5597
|
+
let media;
|
|
5565
5598
|
try {
|
|
5566
|
-
await mediaRepo.create({
|
|
5599
|
+
media = await mediaRepo.create({
|
|
5567
5600
|
filename: basename,
|
|
5568
5601
|
mimeType: contentType,
|
|
5569
5602
|
size: bytes.byteLength,
|
|
@@ -5577,7 +5610,7 @@ function createMediaAccessWithWrite(db, getUploadUrlFn, storage) {
|
|
|
5577
5610
|
throw error;
|
|
5578
5611
|
}
|
|
5579
5612
|
return {
|
|
5580
|
-
mediaId,
|
|
5613
|
+
mediaId: media.id,
|
|
5581
5614
|
storageKey,
|
|
5582
5615
|
url: `/_emdash/api/media/file/${storageKey}`
|
|
5583
5616
|
};
|
|
@@ -5589,6 +5622,11 @@ function createMediaAccessWithWrite(db, getUploadUrlFn, storage) {
|
|
|
5589
5622
|
}
|
|
5590
5623
|
/** Maximum number of redirects to follow in plugin HTTP access */
|
|
5591
5624
|
const MAX_PLUGIN_REDIRECTS = 5;
|
|
5625
|
+
/**
|
|
5626
|
+
* Check if a hostname matches any pattern in the allowed list.
|
|
5627
|
+
* Patterns: "*" matches all, "*.example.com" matches subdomains AND bare "example.com",
|
|
5628
|
+
* "api.example.com" matches exactly.
|
|
5629
|
+
*/
|
|
5592
5630
|
function isHostAllowed(host, allowedHosts) {
|
|
5593
5631
|
return allowedHosts.some((pattern) => {
|
|
5594
5632
|
if (pattern === "*") return true;
|
|
@@ -5986,6 +6024,8 @@ var HookPipeline = class HookPipeline {
|
|
|
5986
6024
|
while (remaining.length > 0) {
|
|
5987
6025
|
const ready = remaining.filter((hook) => hook.dependencies.every((dep) => sorted.some((s) => s.pluginId === dep)));
|
|
5988
6026
|
if (ready.length === 0) {
|
|
6027
|
+
const pluginIds = remaining.map((h) => h.pluginId).join(", ");
|
|
6028
|
+
console.warn(`[hooks] Hook dependency cycle or missing dependency detected among plugins: ${pluginIds}. Falling back to priority order.`);
|
|
5989
6029
|
remaining.sort((a, b) => a.priority - b.priority);
|
|
5990
6030
|
sorted.push(...remaining);
|
|
5991
6031
|
break;
|
|
@@ -6001,7 +6041,13 @@ var HookPipeline = class HookPipeline {
|
|
|
6001
6041
|
* Execute a hook with timeout
|
|
6002
6042
|
*/
|
|
6003
6043
|
async executeWithTimeout(fn, timeout) {
|
|
6004
|
-
|
|
6044
|
+
let timer;
|
|
6045
|
+
const timeoutPromise = new Promise((_, reject) => timer = setTimeout(() => reject(/* @__PURE__ */ new Error(`Hook timeout after ${timeout}ms`)), timeout));
|
|
6046
|
+
try {
|
|
6047
|
+
return await Promise.race([fn(), timeoutPromise]);
|
|
6048
|
+
} finally {
|
|
6049
|
+
clearTimeout(timer);
|
|
6050
|
+
}
|
|
6005
6051
|
}
|
|
6006
6052
|
/**
|
|
6007
6053
|
* Run plugin:install hooks
|
|
@@ -6163,7 +6209,8 @@ var HookPipeline = class HookPipeline {
|
|
|
6163
6209
|
const { handler } = hook;
|
|
6164
6210
|
const event = {
|
|
6165
6211
|
id,
|
|
6166
|
-
collection
|
|
6212
|
+
collection,
|
|
6213
|
+
permanent: false
|
|
6167
6214
|
};
|
|
6168
6215
|
const ctx = this.getContext(hook.pluginId);
|
|
6169
6216
|
const start = Date.now();
|
|
@@ -6194,14 +6241,15 @@ var HookPipeline = class HookPipeline {
|
|
|
6194
6241
|
/**
|
|
6195
6242
|
* Run content:afterDelete hooks
|
|
6196
6243
|
*/
|
|
6197
|
-
async runContentAfterDelete(id, collection) {
|
|
6244
|
+
async runContentAfterDelete(id, collection, permanent) {
|
|
6198
6245
|
const hooks = this.getTypedHooks("content:afterDelete");
|
|
6199
6246
|
const results = [];
|
|
6200
6247
|
for (const hook of hooks) {
|
|
6201
6248
|
const { handler } = hook;
|
|
6202
6249
|
const event = {
|
|
6203
6250
|
id,
|
|
6204
|
-
collection
|
|
6251
|
+
collection,
|
|
6252
|
+
permanent
|
|
6205
6253
|
};
|
|
6206
6254
|
const ctx = this.getContext(hook.pluginId);
|
|
6207
6255
|
const start = Date.now();
|
|
@@ -6969,11 +7017,12 @@ var PluginRouteHandler = class {
|
|
|
6969
7017
|
},
|
|
6970
7018
|
status: error.status
|
|
6971
7019
|
};
|
|
7020
|
+
console.error(`[plugin:${this.plugin.id}] Route handler failed:`, error);
|
|
6972
7021
|
return {
|
|
6973
7022
|
success: false,
|
|
6974
7023
|
error: {
|
|
6975
7024
|
code: "INTERNAL_ERROR",
|
|
6976
|
-
message:
|
|
7025
|
+
message: "An internal error occurred"
|
|
6977
7026
|
},
|
|
6978
7027
|
status: 500
|
|
6979
7028
|
};
|
|
@@ -7258,9 +7307,9 @@ var PluginManager = class {
|
|
|
7258
7307
|
/**
|
|
7259
7308
|
* Run content:afterDelete hooks across all active plugins
|
|
7260
7309
|
*/
|
|
7261
|
-
async runContentAfterDelete(id, collection) {
|
|
7310
|
+
async runContentAfterDelete(id, collection, permanent) {
|
|
7262
7311
|
this.ensureInitialized();
|
|
7263
|
-
return this.hookPipeline.runContentAfterDelete(id, collection);
|
|
7312
|
+
return this.hookPipeline.runContentAfterDelete(id, collection, permanent);
|
|
7264
7313
|
}
|
|
7265
7314
|
/**
|
|
7266
7315
|
* Run content:afterPublish hooks across all active plugins
|
|
@@ -8938,7 +8987,7 @@ async function getTermsForEntries(collection, entryIds, taxonomyName) {
|
|
|
8938
8987
|
* Get entries by term (wraps getEmDashCollection)
|
|
8939
8988
|
*/
|
|
8940
8989
|
async function getEntriesByTerm(collection, taxonomyName, termSlug) {
|
|
8941
|
-
const { getEmDashCollection } = await import("./query-
|
|
8990
|
+
const { getEmDashCollection } = await import("./query-B6Vu0d2i.mjs").then((n) => n.o);
|
|
8942
8991
|
const { entries } = await getEmDashCollection(collection, { where: { [taxonomyName]: termSlug } });
|
|
8943
8992
|
return entries;
|
|
8944
8993
|
}
|
|
@@ -9344,9 +9393,9 @@ function escapeQuery(query) {
|
|
|
9344
9393
|
if (!query || typeof query !== "string") return "";
|
|
9345
9394
|
query = query.trim();
|
|
9346
9395
|
if (query.length === 0) return "";
|
|
9396
|
+
if (query.startsWith("\"") && query.endsWith("\"") && query.length >= 2) return `"${query.slice(1, -1).replace(DOUBLE_QUOTE_PATTERN, "\"\"")}"`;
|
|
9347
9397
|
const escaped = query.replace(DOUBLE_QUOTE_PATTERN, "\"\"");
|
|
9348
9398
|
if (FTS_OPERATORS_PATTERN.test(query)) return escaped;
|
|
9349
|
-
if (query.startsWith("\"") && query.endsWith("\"")) return query;
|
|
9350
9399
|
const terms = escaped.split(WHITESPACE_SPLIT_PATTERN).filter((t) => t.length > 0);
|
|
9351
9400
|
if (terms.length === 0) return "";
|
|
9352
9401
|
return terms.map((t) => `"${t}"*`).join(" ");
|
|
@@ -9447,4 +9496,4 @@ function extractSearchableFields(entry, fields) {
|
|
|
9447
9496
|
|
|
9448
9497
|
//#endregion
|
|
9449
9498
|
export { sanitizeHeadersForSandbox as $, getAllSources as A, handleContentGet as At, createNoopSandboxRunner as B, handleContentUnschedule as Bt, isPreviewRequest as C, handleContentCompare as Ct, parseWxrDate as D, handleContentDelete as Dt, wordpressRestSource as E, handleContentCreate as Et, registerSource as F, handleContentPublish as Ft, DEV_CONSOLE_EMAIL_PLUGIN_ID as G, image as Gt, createPluginManager as H, validateRev as Ht, importReusableBlocksAsSections as I, handleContentRestore as It, HookPipeline as J, devConsoleEmailDeliver as K, isStandardPluginDefinition as L, handleContentSchedule as Lt, getSource as M, handleContentList as Mt, getUrlSources as N, handleContentListTrashed as Nt, wxrSource as O, handleContentDiscardDraft as Ot, probeUrl as P, handleContentPermanentDelete as Pt, extractRequestMeta as Q, NoopSandboxRunner as R, handleContentTranslations as Rt, getPreviewToken as S, hashString as St, getPreviewUrl as T, handleContentCountTrashed as Tt, PluginRouteError as U, portableText as Ut, PluginManager as V, handleContentUpdate as Vt, PluginRouteRegistry as W, reference as Wt, resolveExclusiveHooks as X, createHookPipeline as Y, CronExecutor as Z, getTermsForEntries as _, handleRevisionGet as _t, search as a, isSafeHref as at, getCommentCount as b, generateManifest as bt, getWidgetArea as c, getSection as ct, getEntriesByTerm as d, getCollectionInfo as dt, definePlugin as et, getEntryTerms as f, handleMediaCreate as ft, getTerm as g, handleMediaUpdate as gt, getTaxonomyTerms as h, handleMediaList as ht, getSuggestions as i, prosemirrorToPortableText as it, getFileSources as j, handleContentGetIncludingTrashed as jt, clearSources as k, handleContentDuplicate as kt, getWidgetAreas as l, getSections as lt, getTaxonomyDefs as m, handleMediaGet as mt, extractSearchableFields as n, parseWxrString as nt, searchCollection as o, sanitizeHref as ot, getTaxonomyDef as p, handleMediaDelete as pt, EmailPipeline as q, getSearchStats as r, portableTextToProsemirror as rt, searchWithDb as s, loadBundleFromR2 as st, extractPlainText as t, parseWxr as tt, getWidgetComponents as u, PluginStateRepository as ut, getMenu as v, handleRevisionList as vt, buildPreviewUrl as w, handleContentCountScheduled as wt, getComments as x, computeContentHash as xt, getMenus as y, handleRevisionRestore as yt, SandboxNotAvailableError as z, handleContentUnpublish as zt };
|
|
9450
|
-
//# sourceMappingURL=search-
|
|
9499
|
+
//# sourceMappingURL=search-B5p9D36n.mjs.map
|