emdash 0.2.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-N6BF7RCD.d.mts → adapters-C2BzVy0p.d.mts} +1 -1
- package/dist/{adapters-N6BF7RCD.d.mts.map → adapters-C2BzVy0p.d.mts.map} +1 -1
- package/dist/{apply-wmVEOSbR.mjs → apply-Cma_PiF6.mjs} +38 -23
- package/dist/apply-Cma_PiF6.mjs.map +1 -0
- package/dist/astro/index.d.mts +25 -11
- package/dist/astro/index.d.mts.map +1 -1
- package/dist/astro/index.mjs +38 -25
- 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 +20 -8
- 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 +52 -45
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/types.d.mts +9 -9
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/{byline-1WQPlISL.mjs → byline-WuOq9MFJ.mjs} +5 -4
- package/dist/byline-WuOq9MFJ.mjs.map +1 -0
- package/dist/{bylines-BYdTYmia.mjs → bylines-C_Wsnz4L.mjs} +38 -6
- 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 +13 -13
- 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/{content-BmXndhdi.mjs → content-BsBoyj8G.mjs} +20 -3
- package/dist/content-BsBoyj8G.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/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/{dialect-helpers-B9uSp2GJ.mjs → dialect-helpers-DhTzaUxP.mjs} +4 -1
- package/dist/dialect-helpers-DhTzaUxP.mjs.map +1 -0
- 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-UHEVQMus.d.mts → index-CRg3PWfZ.d.mts} +59 -33
- package/dist/index-CRg3PWfZ.d.mts.map +1 -0
- package/dist/index.d.mts +11 -11
- package/dist/index.mjs +20 -20
- 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-CHb2v0jm.mjs → loader-BYzwzORf.mjs} +4 -2
- package/dist/loader-BYzwzORf.mjs.map +1 -0
- 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-CYeM2rPt.mjs → mode-CyPLdO3C.mjs} +1 -1
- package/dist/{mode-CYeM2rPt.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-bOx1xCTY.d.mts → placeholder-BBCtpTES.d.mts} +1 -1
- package/dist/{placeholder-bOx1xCTY.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-5Hcv_5ER.mjs → query-B6Vu0d2i.mjs} +35 -16
- package/dist/{query-5Hcv_5ER.mjs.map → query-B6Vu0d2i.mjs.map} +1 -1
- package/dist/{redirect-DIfIni3r.mjs → redirect-7lGhLBNZ.mjs} +10 -93
- package/dist/redirect-7lGhLBNZ.mjs.map +1 -0
- package/dist/{registry-1EvbAfsC.mjs → registry-BgnP3ysR.mjs} +27 -37
- package/dist/registry-BgnP3ysR.mjs.map +1 -0
- package/dist/{runner-BoN0-FPi.mjs → runner-Cd-_WyDo.mjs} +18 -6
- package/dist/runner-Cd-_WyDo.mjs.map +1 -0
- package/dist/{runner-DTqkzOzc.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 +2 -2
- package/dist/{search-BsYMed12.mjs → search-B5p9D36n.mjs} +108 -57
- package/dist/search-B5p9D36n.mjs.map +1 -0
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +10 -10
- 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 +11 -3
- package/dist/storage/s3.d.mts.map +1 -1
- package/dist/storage/s3.mjs +76 -15
- package/dist/storage/s3.mjs.map +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-Bl8cTdYt.mjs → transport-BtcQ-Z7T.mjs} +1 -1
- package/dist/{transport-Bl8cTdYt.mjs.map → transport-BtcQ-Z7T.mjs.map} +1 -1
- package/dist/{transport-COOs9GSE.d.mts → transport-CKQA_G44.d.mts} +1 -1
- package/dist/{transport-COOs9GSE.d.mts.map → transport-CKQA_G44.d.mts.map} +1 -1
- package/dist/{types-7-UjSEyB.d.mts → types-B6BzlZxx.d.mts} +1 -1
- package/dist/{types-7-UjSEyB.d.mts.map → types-B6BzlZxx.d.mts.map} +1 -1
- package/dist/{types-6dqxBqsH.d.mts → types-BYWYxLcp.d.mts} +109 -5
- package/dist/types-BYWYxLcp.d.mts.map +1 -0
- package/dist/{types-CIsTnQvJ.d.mts → types-BmkQR1En.d.mts} +1 -1
- package/dist/{types-CIsTnQvJ.d.mts.map → types-BmkQR1En.d.mts.map} +1 -1
- package/dist/{types-BljtYPSd.d.mts → types-DNZpaCBk.d.mts} +14 -6
- package/dist/types-DNZpaCBk.d.mts.map +1 -0
- package/dist/{types-Bec-r_3_.mjs → types-Dz9_WMS6.mjs} +1 -1
- package/dist/types-Dz9_WMS6.mjs.map +1 -0
- package/dist/{types-CcreFIIH.d.mts → types-gLYVCXCQ.d.mts} +1 -1
- package/dist/{types-CcreFIIH.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-B7KP7VLM.d.mts → validate-CcNRWH6I.d.mts} +4 -4
- package/dist/{validate-B7KP7VLM.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/{validate-CqRJb_xU.mjs → validate-VPnKoIzW.mjs} +11 -11
- package/dist/{validate-CqRJb_xU.mjs.map → validate-VPnKoIzW.mjs.map} +1 -1
- package/dist/version-DlTDRdpv.mjs +7 -0
- package/dist/version-DlTDRdpv.mjs.map +1 -0
- package/package.json +7 -5
- package/src/api/handlers/content.ts +36 -25
- package/src/api/handlers/menus.ts +19 -16
- package/src/api/handlers/redirects.ts +95 -3
- package/src/api/schemas/redirects.ts +1 -0
- package/src/astro/integration/index.ts +2 -3
- package/src/astro/integration/runtime.ts +8 -14
- package/src/astro/integration/vite-config.ts +14 -4
- package/src/astro/middleware/redirect.ts +30 -15
- package/src/astro/middleware.ts +11 -19
- package/src/astro/routes/admin.astro +2 -2
- 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/comments/[collection]/[contentId]/index.ts +2 -0
- package/src/astro/routes/api/import/wordpress/rewrite-urls.ts +2 -0
- package/src/astro/routes/api/manifest.ts +3 -1
- 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/astro/storage/adapters.ts +19 -5
- package/src/astro/storage/types.ts +12 -4
- package/src/astro/types.ts +1 -0
- package/src/bylines/index.ts +50 -2
- package/src/cleanup.ts +3 -3
- package/src/cli/commands/bundle-utils.ts +5 -5
- package/src/database/dialect-helpers.ts +3 -0
- 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/database/repositories/content.ts +5 -0
- package/src/database/repositories/redirect.ts +13 -0
- package/src/database/validate.ts +10 -10
- package/src/emdash-runtime.ts +23 -9
- package/src/index.ts +3 -0
- package/src/loader.ts +2 -0
- package/src/mcp/server.ts +40 -67
- package/src/menus/index.ts +4 -0
- 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/redirects/loops.ts +318 -0
- package/src/schema/registry.ts +3 -0
- package/src/search/fts-manager.ts +24 -11
- package/src/search/query.ts +8 -9
- package/src/seed/apply.ts +49 -28
- package/src/storage/s3.ts +94 -25
- package/src/storage/types.ts +13 -5
- package/src/utils/slugify.ts +11 -0
- package/src/version.ts +12 -0
- package/src/visual-editing/toolbar.ts +11 -1
- package/dist/apply-wmVEOSbR.mjs.map +0 -1
- package/dist/byline-1WQPlISL.mjs.map +0 -1
- package/dist/bylines-BYdTYmia.mjs.map +0 -1
- package/dist/content-BmXndhdi.mjs.map +0 -1
- package/dist/dialect-helpers-B9uSp2GJ.mjs.map +0 -1
- package/dist/index-UHEVQMus.d.mts.map +0 -1
- package/dist/loader-CHb2v0jm.mjs.map +0 -1
- package/dist/redirect-DIfIni3r.mjs.map +0 -1
- package/dist/registry-1EvbAfsC.mjs.map +0 -1
- package/dist/runner-BoN0-FPi.mjs.map +0 -1
- package/dist/runner-DTqkzOzc.d.mts.map +0 -1
- package/dist/search-BsYMed12.mjs.map +0 -1
- package/dist/types-6dqxBqsH.d.mts.map +0 -1
- package/dist/types-Bec-r_3_.mjs.map +0 -1
- package/dist/types-BljtYPSd.d.mts.map +0 -1
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { n as validateJsonFieldName, r as validatePluginIdentifier, t as validateIdentifier } from "./validate-VPnKoIzW.mjs";
|
|
2
|
+
import { o as jsonExtractExpr } from "./dialect-helpers-DhTzaUxP.mjs";
|
|
3
|
+
import { a as slugify, r as RevisionRepository, t as ContentRepository } from "./content-BsBoyj8G.mjs";
|
|
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,
|
|
@@ -3662,7 +3659,8 @@ const redirectSchema = z$1.object({
|
|
|
3662
3659
|
}).meta({ id: "Redirect" });
|
|
3663
3660
|
const redirectListResponseSchema = z$1.object({
|
|
3664
3661
|
items: z$1.array(redirectSchema),
|
|
3665
|
-
nextCursor: z$1.string().optional()
|
|
3662
|
+
nextCursor: z$1.string().optional(),
|
|
3663
|
+
loopRedirectIds: z$1.array(z$1.string()).optional()
|
|
3666
3664
|
}).meta({ id: "RedirectListResponse" });
|
|
3667
3665
|
const notFoundEntrySchema = z$1.object({
|
|
3668
3666
|
id: z$1.string(),
|
|
@@ -5130,12 +5128,31 @@ var CronExecutor = class {
|
|
|
5130
5128
|
hookFailed = true;
|
|
5131
5129
|
console.error(`[cron] Hook failed for ${task.plugin_id}:${task.task_name}:`, error);
|
|
5132
5130
|
}
|
|
5133
|
-
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`
|
|
5134
5144
|
UPDATE _emdash_cron_tasks
|
|
5135
|
-
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
|
+
})}
|
|
5136
5152
|
WHERE id = ${task.id}
|
|
5137
5153
|
`.execute(this.db);
|
|
5138
|
-
|
|
5154
|
+
}
|
|
5155
|
+
} else await sql`
|
|
5139
5156
|
DELETE FROM _emdash_cron_tasks WHERE id = ${task.id}
|
|
5140
5157
|
`.execute(this.db);
|
|
5141
5158
|
else await sql`
|
|
@@ -5399,9 +5416,13 @@ function createContentAccess(db) {
|
|
|
5399
5416
|
const result = {
|
|
5400
5417
|
id: item.id,
|
|
5401
5418
|
type: item.type,
|
|
5419
|
+
slug: item.slug,
|
|
5420
|
+
status: item.status,
|
|
5402
5421
|
data: item.data,
|
|
5403
5422
|
createdAt: item.createdAt,
|
|
5404
|
-
updatedAt: item.updatedAt
|
|
5423
|
+
updatedAt: item.updatedAt,
|
|
5424
|
+
locale: item.locale,
|
|
5425
|
+
publishedAt: item.publishedAt
|
|
5405
5426
|
};
|
|
5406
5427
|
if (await seoRepo.isEnabled(collection)) result.seo = await seoRepo.get(collection, item.id);
|
|
5407
5428
|
return result;
|
|
@@ -5423,9 +5444,13 @@ function createContentAccess(db) {
|
|
|
5423
5444
|
const items = result.items.map((item) => ({
|
|
5424
5445
|
id: item.id,
|
|
5425
5446
|
type: item.type,
|
|
5447
|
+
slug: item.slug,
|
|
5448
|
+
status: item.status,
|
|
5426
5449
|
data: item.data,
|
|
5427
5450
|
createdAt: item.createdAt,
|
|
5428
|
-
updatedAt: item.updatedAt
|
|
5451
|
+
updatedAt: item.updatedAt,
|
|
5452
|
+
locale: item.locale,
|
|
5453
|
+
publishedAt: item.publishedAt
|
|
5429
5454
|
}));
|
|
5430
5455
|
if (items.length > 0 && await seoRepo.isEnabled(collection)) {
|
|
5431
5456
|
const seoMap = await seoRepo.getMany(collection, items.map((i) => i.id));
|
|
@@ -5467,9 +5492,13 @@ function createContentAccessWithWrite(db) {
|
|
|
5467
5492
|
const result = {
|
|
5468
5493
|
id: item.id,
|
|
5469
5494
|
type: item.type,
|
|
5495
|
+
slug: item.slug,
|
|
5496
|
+
status: item.status,
|
|
5470
5497
|
data: item.data,
|
|
5471
5498
|
createdAt: item.createdAt,
|
|
5472
|
-
updatedAt: item.updatedAt
|
|
5499
|
+
updatedAt: item.updatedAt,
|
|
5500
|
+
locale: item.locale,
|
|
5501
|
+
publishedAt: item.publishedAt
|
|
5473
5502
|
};
|
|
5474
5503
|
if (hasSeo) result.seo = seo !== void 0 ? await trxSeoRepo.upsert(collection, item.id, seo) : await trxSeoRepo.get(collection, item.id);
|
|
5475
5504
|
return result;
|
|
@@ -5489,9 +5518,13 @@ function createContentAccessWithWrite(db) {
|
|
|
5489
5518
|
const result = {
|
|
5490
5519
|
id: item.id,
|
|
5491
5520
|
type: item.type,
|
|
5521
|
+
slug: item.slug,
|
|
5522
|
+
status: item.status,
|
|
5492
5523
|
data: item.data,
|
|
5493
5524
|
createdAt: item.createdAt,
|
|
5494
|
-
updatedAt: item.updatedAt
|
|
5525
|
+
updatedAt: item.updatedAt,
|
|
5526
|
+
locale: item.locale,
|
|
5527
|
+
publishedAt: item.publishedAt
|
|
5495
5528
|
};
|
|
5496
5529
|
if (hasSeo) result.seo = seo !== void 0 ? await trxSeoRepo.upsert(collection, item.id, seo) : await trxSeoRepo.get(collection, item.id);
|
|
5497
5530
|
return result;
|
|
@@ -5552,17 +5585,18 @@ function createMediaAccessWithWrite(db, getUploadUrlFn, storage) {
|
|
|
5552
5585
|
getUploadUrl: getUploadUrlFn,
|
|
5553
5586
|
async upload(filename, contentType, bytes) {
|
|
5554
5587
|
if (!storage) throw new Error("Media upload() requires a storage backend. Configure storage in PluginContextFactoryOptions.");
|
|
5555
|
-
const
|
|
5588
|
+
const keyPrefix = ulid();
|
|
5556
5589
|
const basename = filename.split("/").pop() ?? filename;
|
|
5557
5590
|
const dotIdx = basename.lastIndexOf(".");
|
|
5558
|
-
const storageKey = `${
|
|
5591
|
+
const storageKey = `${keyPrefix}${dotIdx > 0 ? basename.slice(dotIdx).toLowerCase() : ""}`;
|
|
5559
5592
|
await storage.upload({
|
|
5560
5593
|
key: storageKey,
|
|
5561
5594
|
body: new Uint8Array(bytes),
|
|
5562
5595
|
contentType
|
|
5563
5596
|
});
|
|
5597
|
+
let media;
|
|
5564
5598
|
try {
|
|
5565
|
-
await mediaRepo.create({
|
|
5599
|
+
media = await mediaRepo.create({
|
|
5566
5600
|
filename: basename,
|
|
5567
5601
|
mimeType: contentType,
|
|
5568
5602
|
size: bytes.byteLength,
|
|
@@ -5576,7 +5610,7 @@ function createMediaAccessWithWrite(db, getUploadUrlFn, storage) {
|
|
|
5576
5610
|
throw error;
|
|
5577
5611
|
}
|
|
5578
5612
|
return {
|
|
5579
|
-
mediaId,
|
|
5613
|
+
mediaId: media.id,
|
|
5580
5614
|
storageKey,
|
|
5581
5615
|
url: `/_emdash/api/media/file/${storageKey}`
|
|
5582
5616
|
};
|
|
@@ -5588,6 +5622,11 @@ function createMediaAccessWithWrite(db, getUploadUrlFn, storage) {
|
|
|
5588
5622
|
}
|
|
5589
5623
|
/** Maximum number of redirects to follow in plugin HTTP access */
|
|
5590
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
|
+
*/
|
|
5591
5630
|
function isHostAllowed(host, allowedHosts) {
|
|
5592
5631
|
return allowedHosts.some((pattern) => {
|
|
5593
5632
|
if (pattern === "*") return true;
|
|
@@ -5985,6 +6024,8 @@ var HookPipeline = class HookPipeline {
|
|
|
5985
6024
|
while (remaining.length > 0) {
|
|
5986
6025
|
const ready = remaining.filter((hook) => hook.dependencies.every((dep) => sorted.some((s) => s.pluginId === dep)));
|
|
5987
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.`);
|
|
5988
6029
|
remaining.sort((a, b) => a.priority - b.priority);
|
|
5989
6030
|
sorted.push(...remaining);
|
|
5990
6031
|
break;
|
|
@@ -6000,7 +6041,13 @@ var HookPipeline = class HookPipeline {
|
|
|
6000
6041
|
* Execute a hook with timeout
|
|
6001
6042
|
*/
|
|
6002
6043
|
async executeWithTimeout(fn, timeout) {
|
|
6003
|
-
|
|
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
|
+
}
|
|
6004
6051
|
}
|
|
6005
6052
|
/**
|
|
6006
6053
|
* Run plugin:install hooks
|
|
@@ -6162,7 +6209,8 @@ var HookPipeline = class HookPipeline {
|
|
|
6162
6209
|
const { handler } = hook;
|
|
6163
6210
|
const event = {
|
|
6164
6211
|
id,
|
|
6165
|
-
collection
|
|
6212
|
+
collection,
|
|
6213
|
+
permanent: false
|
|
6166
6214
|
};
|
|
6167
6215
|
const ctx = this.getContext(hook.pluginId);
|
|
6168
6216
|
const start = Date.now();
|
|
@@ -6193,14 +6241,15 @@ var HookPipeline = class HookPipeline {
|
|
|
6193
6241
|
/**
|
|
6194
6242
|
* Run content:afterDelete hooks
|
|
6195
6243
|
*/
|
|
6196
|
-
async runContentAfterDelete(id, collection) {
|
|
6244
|
+
async runContentAfterDelete(id, collection, permanent) {
|
|
6197
6245
|
const hooks = this.getTypedHooks("content:afterDelete");
|
|
6198
6246
|
const results = [];
|
|
6199
6247
|
for (const hook of hooks) {
|
|
6200
6248
|
const { handler } = hook;
|
|
6201
6249
|
const event = {
|
|
6202
6250
|
id,
|
|
6203
|
-
collection
|
|
6251
|
+
collection,
|
|
6252
|
+
permanent
|
|
6204
6253
|
};
|
|
6205
6254
|
const ctx = this.getContext(hook.pluginId);
|
|
6206
6255
|
const start = Date.now();
|
|
@@ -6968,11 +7017,12 @@ var PluginRouteHandler = class {
|
|
|
6968
7017
|
},
|
|
6969
7018
|
status: error.status
|
|
6970
7019
|
};
|
|
7020
|
+
console.error(`[plugin:${this.plugin.id}] Route handler failed:`, error);
|
|
6971
7021
|
return {
|
|
6972
7022
|
success: false,
|
|
6973
7023
|
error: {
|
|
6974
7024
|
code: "INTERNAL_ERROR",
|
|
6975
|
-
message:
|
|
7025
|
+
message: "An internal error occurred"
|
|
6976
7026
|
},
|
|
6977
7027
|
status: 500
|
|
6978
7028
|
};
|
|
@@ -7257,9 +7307,9 @@ var PluginManager = class {
|
|
|
7257
7307
|
/**
|
|
7258
7308
|
* Run content:afterDelete hooks across all active plugins
|
|
7259
7309
|
*/
|
|
7260
|
-
async runContentAfterDelete(id, collection) {
|
|
7310
|
+
async runContentAfterDelete(id, collection, permanent) {
|
|
7261
7311
|
this.ensureInitialized();
|
|
7262
|
-
return this.hookPipeline.runContentAfterDelete(id, collection);
|
|
7312
|
+
return this.hookPipeline.runContentAfterDelete(id, collection, permanent);
|
|
7263
7313
|
}
|
|
7264
7314
|
/**
|
|
7265
7315
|
* Run content:afterPublish hooks across all active plugins
|
|
@@ -8762,6 +8812,7 @@ function interpolateUrlPattern(pattern, slug, id) {
|
|
|
8762
8812
|
async function resolveContentUrl(collection, entryId, db, urlPatterns) {
|
|
8763
8813
|
if (!entryId) return null;
|
|
8764
8814
|
try {
|
|
8815
|
+
validateIdentifier(collection, "menu item collection");
|
|
8765
8816
|
const row = (await sql`
|
|
8766
8817
|
SELECT slug FROM ${sql.ref(`ec_${collection}`)} WHERE id = ${entryId} LIMIT 1
|
|
8767
8818
|
`.execute(db)).rows[0];
|
|
@@ -8936,7 +8987,7 @@ async function getTermsForEntries(collection, entryIds, taxonomyName) {
|
|
|
8936
8987
|
* Get entries by term (wraps getEmDashCollection)
|
|
8937
8988
|
*/
|
|
8938
8989
|
async function getEntriesByTerm(collection, taxonomyName, termSlug) {
|
|
8939
|
-
const { getEmDashCollection } = await import("./query-
|
|
8990
|
+
const { getEmDashCollection } = await import("./query-B6Vu0d2i.mjs").then((n) => n.o);
|
|
8940
8991
|
const { entries } = await getEmDashCollection(collection, { where: { [taxonomyName]: termSlug } });
|
|
8941
8992
|
return entries;
|
|
8942
8993
|
}
|
|
@@ -9342,9 +9393,9 @@ function escapeQuery(query) {
|
|
|
9342
9393
|
if (!query || typeof query !== "string") return "";
|
|
9343
9394
|
query = query.trim();
|
|
9344
9395
|
if (query.length === 0) return "";
|
|
9396
|
+
if (query.startsWith("\"") && query.endsWith("\"") && query.length >= 2) return `"${query.slice(1, -1).replace(DOUBLE_QUOTE_PATTERN, "\"\"")}"`;
|
|
9345
9397
|
const escaped = query.replace(DOUBLE_QUOTE_PATTERN, "\"\"");
|
|
9346
9398
|
if (FTS_OPERATORS_PATTERN.test(query)) return escaped;
|
|
9347
|
-
if (query.startsWith("\"") && query.endsWith("\"")) return query;
|
|
9348
9399
|
const terms = escaped.split(WHITESPACE_SPLIT_PATTERN).filter((t) => t.length > 0);
|
|
9349
9400
|
if (terms.length === 0) return "";
|
|
9350
9401
|
return terms.map((t) => `"${t}"*`).join(" ");
|
|
@@ -9445,4 +9496,4 @@ function extractSearchableFields(entry, fields) {
|
|
|
9445
9496
|
|
|
9446
9497
|
//#endregion
|
|
9447
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 };
|
|
9448
|
-
//# sourceMappingURL=search-
|
|
9499
|
+
//# sourceMappingURL=search-B5p9D36n.mjs.map
|