emdash 0.10.0 → 0.11.1
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/{apply-UsrFuO7l.mjs → apply-Ded_1vng.mjs} +36 -25
- package/dist/{apply-UsrFuO7l.mjs.map → apply-Ded_1vng.mjs.map} +1 -1
- package/dist/astro/index.d.mts +5 -5
- package/dist/astro/index.mjs +1 -1
- package/dist/astro/middleware/auth.d.mts +5 -5
- package/dist/astro/middleware/redirect.mjs +2 -2
- package/dist/astro/middleware.d.mts.map +1 -1
- package/dist/astro/middleware.mjs +83 -33
- package/dist/astro/middleware.mjs.map +1 -1
- package/dist/astro/types.d.mts +10 -7
- package/dist/astro/types.d.mts.map +1 -1
- package/dist/{byline-C3vnhIpU.mjs → byline-gFn1r0vA.mjs} +2 -2
- package/dist/{byline-C3vnhIpU.mjs.map → byline-gFn1r0vA.mjs.map} +1 -1
- package/dist/{bylines-esI7ioa9.mjs → bylines-DTFI8nDM.mjs} +4 -4
- package/dist/{bylines-esI7ioa9.mjs.map → bylines-DTFI8nDM.mjs.map} +1 -1
- package/dist/{cache-fTzxgMFJ.mjs → cache-BAJbeoZ8.mjs} +2 -2
- package/dist/{cache-fTzxgMFJ.mjs.map → cache-BAJbeoZ8.mjs.map} +1 -1
- package/dist/{chunks-Da2-b-oA.mjs → chunks-BK1oZS-l.mjs} +2 -2
- package/dist/{chunks-Da2-b-oA.mjs.map → chunks-BK1oZS-l.mjs.map} +1 -1
- package/dist/cli/index.mjs +102 -27
- package/dist/cli/index.mjs.map +1 -1
- package/dist/{content-C7G4QXkK.mjs → content-CERxPUN0.mjs} +2 -2
- package/dist/{content-C7G4QXkK.mjs.map → content-CERxPUN0.mjs.map} +1 -1
- package/dist/database/instrumentation.d.mts +6 -4
- package/dist/database/instrumentation.d.mts.map +1 -1
- package/dist/database/instrumentation.mjs +19 -7
- package/dist/database/instrumentation.mjs.map +1 -1
- package/dist/db/index.d.mts +2 -2
- package/dist/db/index.mjs +1 -1
- package/dist/{index-DjPMOfO0.d.mts → index-BogfvE-z.d.mts} +32 -24
- package/dist/index-BogfvE-z.d.mts.map +1 -0
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +19 -19
- package/dist/{load-sXRuM7Us.mjs → load-DR1VwFXR.mjs} +2 -2
- package/dist/{load-sXRuM7Us.mjs.map → load-DR1VwFXR.mjs.map} +1 -1
- package/dist/{loader-Bx2_9-5e.mjs → loader-ou_PXAjg.mjs} +2 -2
- package/dist/{loader-Bx2_9-5e.mjs.map → loader-ou_PXAjg.mjs.map} +1 -1
- package/dist/media/local-runtime.d.mts +5 -5
- package/dist/media/local-runtime.mjs +1 -1
- package/dist/{media-D8FbNsl0.mjs → media-1fFhub9c.mjs} +21 -9
- package/dist/media-1fFhub9c.mjs.map +1 -0
- package/dist/page/index.d.mts +2 -2
- package/dist/plugins/adapt-sandbox-entry.d.mts +5 -5
- package/dist/plugins/adapt-sandbox-entry.mjs +1 -1
- package/dist/{query-Bo-msrmu.mjs → query-8c_meo_K.mjs} +10 -10
- package/dist/{query-Bo-msrmu.mjs.map → query-8c_meo_K.mjs.map} +1 -1
- package/dist/{registry-Beb7wxFc.mjs → registry-Do34mz_P.mjs} +6 -5
- package/dist/registry-Do34mz_P.mjs.map +1 -0
- package/dist/{request-cache-C-tIpYIw.mjs → request-cache-D4I69LeL.mjs} +6 -2
- package/dist/request-cache-D4I69LeL.mjs.map +1 -0
- package/dist/request-context.d.mts +27 -1
- package/dist/request-context.d.mts.map +1 -1
- package/dist/request-context.mjs +16 -3
- package/dist/request-context.mjs.map +1 -1
- package/dist/{runner-DMnlIkh4.mjs → runner-DIcU2UCC.mjs} +174 -152
- package/dist/runner-DIcU2UCC.mjs.map +1 -0
- package/dist/{runner-Clwe4Mme.d.mts → runner-Iu3IZSDM.d.mts} +2 -2
- package/dist/{runner-Clwe4Mme.d.mts.map → runner-Iu3IZSDM.d.mts.map} +1 -1
- package/dist/runtime.d.mts +5 -5
- package/dist/runtime.mjs +1 -1
- package/dist/{search-DkN-BqsS.mjs → search-DuWhx4NG.mjs} +172 -30
- package/dist/search-DuWhx4NG.mjs.map +1 -0
- package/dist/seed/index.d.mts +2 -2
- package/dist/seed/index.mjs +10 -10
- package/dist/{taxonomies-CTtewrSQ.mjs → taxonomies-Bw76xAxo.mjs} +6 -6
- package/dist/{taxonomies-CTtewrSQ.mjs.map → taxonomies-Bw76xAxo.mjs.map} +1 -1
- package/dist/{taxonomy-DSxx2K2L.mjs → taxonomy-D6NvlKo8.mjs} +3 -3
- package/dist/{taxonomy-DSxx2K2L.mjs.map → taxonomy-D6NvlKo8.mjs.map} +1 -1
- package/dist/{types-Eg829jj9.mjs → types-56BKbld_.mjs} +1 -1
- package/dist/types-56BKbld_.mjs.map +1 -0
- package/dist/{types-Dtx1mSMX.d.mts → types-BQx6ZXpR.d.mts} +2 -1
- package/dist/types-BQx6ZXpR.d.mts.map +1 -0
- package/dist/{types-Dl1fgFjn.d.mts → types-BTe41zL6.d.mts} +4 -3
- package/dist/types-BTe41zL6.d.mts.map +1 -0
- package/dist/types-DiI8NOG_.mjs +16 -0
- package/dist/types-DiI8NOG_.mjs.map +1 -0
- package/dist/{types-D19uBYWn.d.mts → types-IjUrQMVe.d.mts} +21 -245
- package/dist/types-IjUrQMVe.d.mts.map +1 -0
- package/dist/{validate-DHGwADqO.d.mts → validate-CcVQQpmH.d.mts} +7 -3
- package/dist/validate-CcVQQpmH.d.mts.map +1 -0
- package/dist/{validate-CBIbxM3L.mjs → validate-UK4Ja1uo.mjs} +3 -3
- package/dist/{validate-CBIbxM3L.mjs.map → validate-UK4Ja1uo.mjs.map} +1 -1
- package/dist/{validation-B1NYiEos.mjs → validation-Vc5DQkJa.mjs} +4 -4
- package/dist/{validation-B1NYiEos.mjs.map → validation-Vc5DQkJa.mjs.map} +1 -1
- package/dist/version-JjSqv90m.mjs +7 -0
- package/dist/{version-CMD42IRC.mjs.map → version-JjSqv90m.mjs.map} +1 -1
- package/dist/{zod-generator-BNJDQBSZ.mjs → zod-generator-CHnJUP2l.mjs} +1 -1
- package/dist/{zod-generator-BNJDQBSZ.mjs.map → zod-generator-CHnJUP2l.mjs.map} +1 -1
- package/package.json +9 -8
- package/src/api/errors.ts +5 -0
- package/src/api/handlers/content.ts +9 -0
- package/src/api/handlers/media-allowlist.ts +40 -0
- package/src/api/handlers/media.ts +1 -1
- package/src/api/handlers/menus.ts +158 -28
- package/src/api/handlers/validate-media-fields.ts +125 -0
- package/src/api/schemas/media.ts +23 -3
- package/src/api/schemas/schema.ts +11 -2
- package/src/astro/middleware.ts +46 -11
- package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +1 -1
- package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +1 -1
- package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +1 -1
- package/src/astro/routes/api/content/[collection]/[id]/publish.ts +1 -1
- package/src/astro/routes/api/content/[collection]/[id]/restore.ts +1 -1
- package/src/astro/routes/api/content/[collection]/[id]/schedule.ts +2 -2
- package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +1 -1
- package/src/astro/routes/api/content/[collection]/[id].ts +2 -2
- package/src/astro/routes/api/content/[collection]/index.ts +1 -1
- package/src/astro/routes/api/media/upload-url.ts +10 -4
- package/src/astro/routes/api/media.ts +12 -4
- package/src/astro/types.ts +5 -1
- package/src/auth/rate-limit.ts +3 -3
- package/src/cli/commands/bundle-utils.ts +81 -6
- package/src/cli/commands/bundle.ts +18 -15
- package/src/cli/commands/export-seed.ts +57 -3
- package/src/database/instrumentation.ts +22 -8
- package/src/database/migrations/016_api_tokens.ts +18 -3
- package/src/database/migrations/037_credential_algorithm.ts +18 -0
- package/src/database/migrations/runner.ts +2 -0
- package/src/database/repositories/media.ts +40 -10
- package/src/database/types.ts +2 -1
- package/src/emdash-runtime.ts +16 -3
- package/src/fields/file.ts +7 -6
- package/src/fields/image.ts +12 -11
- package/src/fields/types.ts +3 -0
- package/src/index.ts +1 -1
- package/src/mcp/server.ts +37 -8
- package/src/media/mime.ts +75 -0
- package/src/plugins/types.ts +81 -191
- package/src/request-cache.ts +6 -2
- package/src/request-context.ts +42 -2
- package/src/schema/registry.ts +5 -5
- package/src/schema/types.ts +3 -2
- package/src/seed/apply.ts +25 -8
- package/src/seed/types.ts +4 -0
- package/dist/index-DjPMOfO0.d.mts.map +0 -1
- package/dist/media-D8FbNsl0.mjs.map +0 -1
- package/dist/registry-Beb7wxFc.mjs.map +0 -1
- package/dist/request-cache-C-tIpYIw.mjs.map +0 -1
- package/dist/runner-DMnlIkh4.mjs.map +0 -1
- package/dist/search-DkN-BqsS.mjs.map +0 -1
- package/dist/types-CoO6mpV3.mjs +0 -68
- package/dist/types-CoO6mpV3.mjs.map +0 -1
- package/dist/types-D19uBYWn.d.mts.map +0 -1
- package/dist/types-Dl1fgFjn.d.mts.map +0 -1
- package/dist/types-Dtx1mSMX.d.mts.map +0 -1
- package/dist/types-Eg829jj9.mjs.map +0 -1
- package/dist/validate-DHGwADqO.d.mts.map +0 -1
- package/dist/version-CMD42IRC.mjs +0 -7
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import { n as validateJsonFieldName, r as validatePluginIdentifier, t as validateIdentifier } from "./validate-VPnKoIzW.mjs";
|
|
2
2
|
import { s as jsonExtractExpr } from "./dialect-helpers-BKCvISIQ.mjs";
|
|
3
3
|
import { r as isI18nEnabled } from "./config-CVssduLe.mjs";
|
|
4
|
-
import { a as slugify, r as RevisionRepository, t as ContentRepository } from "./content-
|
|
4
|
+
import { a as slugify, r as RevisionRepository, t as ContentRepository } from "./content-CERxPUN0.mjs";
|
|
5
5
|
import { r as encodeBase64, t as decodeBase64 } from "./base64-MBPo9ozB.mjs";
|
|
6
6
|
import { i as encodeCursor, n as InvalidCursorError, r as decodeCursor, t as EmDashValidationError } from "./types-BIgulNsW.mjs";
|
|
7
|
-
import { t as MediaRepository } from "./media-
|
|
7
|
+
import { t as MediaRepository } from "./media-1fFhub9c.mjs";
|
|
8
8
|
import { t as OptionsRepository } from "./options-nPxWnrya.mjs";
|
|
9
9
|
import { t as withTransaction } from "./transaction-D44LBXvU.mjs";
|
|
10
10
|
import { t as RedirectRepository } from "./redirect-C5H7VGIX.mjs";
|
|
11
|
-
import { n as chunks, t as SQL_BATCH_SIZE } from "./chunks-
|
|
12
|
-
import { t as BylineRepository } from "./byline-
|
|
13
|
-
import { r as invalidateRedirectCache } from "./cache-
|
|
11
|
+
import { n as chunks, t as SQL_BATCH_SIZE } from "./chunks-BK1oZS-l.mjs";
|
|
12
|
+
import { t as BylineRepository } from "./byline-gFn1r0vA.mjs";
|
|
13
|
+
import { r as invalidateRedirectCache } from "./cache-BAJbeoZ8.mjs";
|
|
14
14
|
import { t as isMissingTableError } from "./db-errors-B7P2pSCn.mjs";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { a as ssrfSafeFetch, i as resolveAndValidateExternalUrl, o as stripCredentialHeaders, r as SsrfError, s as validateExternalUrl } from "./apply-
|
|
20
|
-
import { d as resolveLocale, f as resolveLocaleChain } from "./taxonomies-
|
|
15
|
+
import { n as requestCached } from "./request-cache-D4I69LeL.mjs";
|
|
16
|
+
import { r as hashString } from "./zod-generator-CHnJUP2l.mjs";
|
|
17
|
+
import { i as FTSManager, n as SchemaRegistry } from "./registry-Do34mz_P.mjs";
|
|
18
|
+
import { r as getDb } from "./loader-ou_PXAjg.mjs";
|
|
19
|
+
import { a as ssrfSafeFetch, i as resolveAndValidateExternalUrl, o as stripCredentialHeaders, r as SsrfError, s as validateExternalUrl } from "./apply-Ded_1vng.mjs";
|
|
20
|
+
import { d as resolveLocale, f as resolveLocaleChain } from "./taxonomies-Bw76xAxo.mjs";
|
|
21
21
|
import { i as pluginManifestSchema } from "./manifest-schema-CXAbd1vH.mjs";
|
|
22
|
-
import { i as normalizeCapabilities } from "./types-
|
|
22
|
+
import { i as normalizeCapabilities } from "./types-DiI8NOG_.mjs";
|
|
23
23
|
import { t as generatePreviewToken } from "./tokens-CyRDPVW2.mjs";
|
|
24
24
|
import { sql } from "kysely";
|
|
25
25
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -739,9 +739,6 @@ var PluginStorageRepository = class {
|
|
|
739
739
|
|
|
740
740
|
//#endregion
|
|
741
741
|
//#region src/fields/image.ts
|
|
742
|
-
/**
|
|
743
|
-
* Image field schema
|
|
744
|
-
*/
|
|
745
742
|
const imageSchema = z.object({
|
|
746
743
|
id: z.string(),
|
|
747
744
|
src: z.string(),
|
|
@@ -749,17 +746,39 @@ const imageSchema = z.object({
|
|
|
749
746
|
width: z.number().optional(),
|
|
750
747
|
height: z.number().optional()
|
|
751
748
|
});
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
* References media items from the media library
|
|
755
|
-
*/
|
|
756
|
-
function image(options) {
|
|
749
|
+
function image(options = {}) {
|
|
750
|
+
const validation = options.allowedTypes && options.allowedTypes.length > 0 ? { allowedMimeTypes: [...options.allowedTypes] } : void 0;
|
|
757
751
|
return {
|
|
758
752
|
type: "image",
|
|
759
753
|
columnType: "TEXT",
|
|
760
|
-
schema: options
|
|
754
|
+
schema: options.required === false ? imageSchema.optional() : imageSchema,
|
|
761
755
|
options,
|
|
762
|
-
ui: { widget: "image" }
|
|
756
|
+
ui: { widget: "image" },
|
|
757
|
+
validation
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
//#endregion
|
|
762
|
+
//#region src/fields/file.ts
|
|
763
|
+
function file(options = {}) {
|
|
764
|
+
const fileObjSchema = z.object({
|
|
765
|
+
id: z.string(),
|
|
766
|
+
url: z.string(),
|
|
767
|
+
filename: z.string(),
|
|
768
|
+
mimeType: z.string(),
|
|
769
|
+
size: z.number()
|
|
770
|
+
});
|
|
771
|
+
return {
|
|
772
|
+
type: "file",
|
|
773
|
+
columnType: "TEXT",
|
|
774
|
+
schema: options.required ? fileObjSchema : fileObjSchema.optional(),
|
|
775
|
+
options,
|
|
776
|
+
ui: {
|
|
777
|
+
widget: "file",
|
|
778
|
+
helpText: options.helpText,
|
|
779
|
+
maxSize: options.maxSize
|
|
780
|
+
},
|
|
781
|
+
validation: options.allowedTypes && options.allowedTypes.length > 0 ? { allowedMimeTypes: [...options.allowedTypes] } : void 0
|
|
763
782
|
};
|
|
764
783
|
}
|
|
765
784
|
|
|
@@ -978,6 +997,115 @@ function validateRev(rev, item) {
|
|
|
978
997
|
return { valid: true };
|
|
979
998
|
}
|
|
980
999
|
|
|
1000
|
+
//#endregion
|
|
1001
|
+
//#region src/media/mime.ts
|
|
1002
|
+
function normalizeMime(mime) {
|
|
1003
|
+
return mime.split(";")[0].trim().toLowerCase();
|
|
1004
|
+
}
|
|
1005
|
+
function matchesMimeAllowlist(mime, allowList) {
|
|
1006
|
+
const normalized = normalizeMime(mime);
|
|
1007
|
+
for (const entry of allowList) {
|
|
1008
|
+
if (!entry || !entry.includes("/")) continue;
|
|
1009
|
+
const normalizedEntry = normalizeMime(entry);
|
|
1010
|
+
if (normalizedEntry.endsWith("/")) {
|
|
1011
|
+
if (normalized.startsWith(normalizedEntry)) return true;
|
|
1012
|
+
} else if (normalized === normalizedEntry) return true;
|
|
1013
|
+
}
|
|
1014
|
+
return false;
|
|
1015
|
+
}
|
|
1016
|
+
/**
|
|
1017
|
+
* Extract the `allowedMimeTypes` list from a `_emdash_fields.validation` row
|
|
1018
|
+
* (raw JSON string). Returns null when the value is missing, malformed, or the
|
|
1019
|
+
* list is empty — callers treat that as "no field-specific constraint".
|
|
1020
|
+
*/
|
|
1021
|
+
function parseAllowedMimeTypes(rawValidation) {
|
|
1022
|
+
if (!rawValidation) return null;
|
|
1023
|
+
try {
|
|
1024
|
+
const parsed = JSON.parse(rawValidation);
|
|
1025
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
1026
|
+
const list = parsed.allowedMimeTypes;
|
|
1027
|
+
if (!Array.isArray(list) || list.length === 0) return null;
|
|
1028
|
+
return list.filter((entry) => typeof entry === "string");
|
|
1029
|
+
} catch {
|
|
1030
|
+
return null;
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
//#endregion
|
|
1035
|
+
//#region src/api/handlers/validate-media-fields.ts
|
|
1036
|
+
function asMediaRef(value) {
|
|
1037
|
+
if (value === null || value === void 0) return null;
|
|
1038
|
+
if (typeof value !== "object" || Array.isArray(value)) return null;
|
|
1039
|
+
return value;
|
|
1040
|
+
}
|
|
1041
|
+
function fail(message) {
|
|
1042
|
+
return {
|
|
1043
|
+
success: false,
|
|
1044
|
+
error: {
|
|
1045
|
+
code: "INVALID_MIME_FOR_FIELD",
|
|
1046
|
+
message
|
|
1047
|
+
}
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
async function loadMediaFieldsForCollection(db, collectionSlug) {
|
|
1051
|
+
const rows = await db.selectFrom("_emdash_fields").innerJoin("_emdash_collections", "_emdash_collections.id", "_emdash_fields.collection_id").select([
|
|
1052
|
+
"_emdash_fields.slug",
|
|
1053
|
+
"_emdash_fields.type",
|
|
1054
|
+
"_emdash_fields.validation"
|
|
1055
|
+
]).where("_emdash_collections.slug", "=", collectionSlug).where("_emdash_fields.type", "in", ["file", "image"]).execute();
|
|
1056
|
+
const out = [];
|
|
1057
|
+
for (const row of rows) {
|
|
1058
|
+
const list = parseAllowedMimeTypes(row.validation);
|
|
1059
|
+
if (!list) continue;
|
|
1060
|
+
out.push({
|
|
1061
|
+
slug: row.slug,
|
|
1062
|
+
type: row.type,
|
|
1063
|
+
allowedMimeTypes: list
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
1066
|
+
return out;
|
|
1067
|
+
}
|
|
1068
|
+
async function validateMediaFields(db, collectionSlug, data) {
|
|
1069
|
+
const fields = await requestCached(`mediaFields:${collectionSlug}`, () => loadMediaFieldsForCollection(db, collectionSlug));
|
|
1070
|
+
if (fields.length === 0) return {
|
|
1071
|
+
success: true,
|
|
1072
|
+
data: true
|
|
1073
|
+
};
|
|
1074
|
+
const localIds = /* @__PURE__ */ new Set();
|
|
1075
|
+
for (const field of fields) {
|
|
1076
|
+
const ref = asMediaRef(data[field.slug]);
|
|
1077
|
+
if (!ref) continue;
|
|
1078
|
+
if ((typeof ref.provider === "string" ? ref.provider : "local") === "local" && typeof ref.id === "string") localIds.add(ref.id);
|
|
1079
|
+
}
|
|
1080
|
+
const idList = [...localIds];
|
|
1081
|
+
const mimeById = /* @__PURE__ */ new Map();
|
|
1082
|
+
if (idList.length > 0) for (const batch of chunks(idList, SQL_BATCH_SIZE)) {
|
|
1083
|
+
const rows = await db.selectFrom("media").select(["id", "mime_type"]).where("id", "in", batch).execute();
|
|
1084
|
+
for (const r of rows) mimeById.set(r.id, r.mime_type);
|
|
1085
|
+
}
|
|
1086
|
+
for (const field of fields) {
|
|
1087
|
+
const value = data[field.slug];
|
|
1088
|
+
if (value === null || value === void 0) continue;
|
|
1089
|
+
const ref = asMediaRef(value);
|
|
1090
|
+
if (!ref) continue;
|
|
1091
|
+
const provider = typeof ref.provider === "string" ? ref.provider : "local";
|
|
1092
|
+
let mime;
|
|
1093
|
+
if (provider === "local") {
|
|
1094
|
+
if (typeof ref.id !== "string") return fail(`Field '${field.slug}' references media with an invalid id`);
|
|
1095
|
+
mime = mimeById.get(ref.id);
|
|
1096
|
+
if (!mime) return fail(`Field '${field.slug}' references media with unknown MIME type`);
|
|
1097
|
+
} else {
|
|
1098
|
+
if (typeof ref.mimeType !== "string") return fail(`Field '${field.slug}' requires a mimeType declaration for non-local media`);
|
|
1099
|
+
mime = ref.mimeType;
|
|
1100
|
+
}
|
|
1101
|
+
if (!matchesMimeAllowlist(mime, field.allowedMimeTypes)) return fail(`Field '${field.slug}' does not accept ${mime}`);
|
|
1102
|
+
}
|
|
1103
|
+
return {
|
|
1104
|
+
success: true,
|
|
1105
|
+
data: true
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
|
|
981
1109
|
//#endregion
|
|
982
1110
|
//#region src/api/handlers/content.ts
|
|
983
1111
|
/**
|
|
@@ -1255,6 +1383,8 @@ async function handleContentCreate(db, collection, body) {
|
|
|
1255
1383
|
message: `Collection "${collection}" does not have SEO enabled. Remove the seo field or enable SEO on this collection.`
|
|
1256
1384
|
}
|
|
1257
1385
|
};
|
|
1386
|
+
const mimeCheck = await validateMediaFields(db, collection, body.data);
|
|
1387
|
+
if (!mimeCheck.success) return mimeCheck;
|
|
1258
1388
|
const item = await withTransaction(db, async (trx) => {
|
|
1259
1389
|
const repo = new ContentRepository(trx);
|
|
1260
1390
|
const bylineRepo = new BylineRepository(trx);
|
|
@@ -1280,7 +1410,7 @@ async function handleContentCreate(db, collection, body) {
|
|
|
1280
1410
|
}
|
|
1281
1411
|
await hydrateBylines(trx, collection, created);
|
|
1282
1412
|
if (body.translationOf) {
|
|
1283
|
-
const { TaxonomyRepository } = await import("./taxonomy-
|
|
1413
|
+
const { TaxonomyRepository } = await import("./taxonomy-D6NvlKo8.mjs").then((n) => n.n);
|
|
1284
1414
|
await new TaxonomyRepository(trx).copyEntryTerms(collection, body.translationOf, created.id);
|
|
1285
1415
|
}
|
|
1286
1416
|
if (body.seo && hasSeo) created.seo = await new SeoRepository(trx).upsert(collection, created.id, body.seo);
|
|
@@ -1353,6 +1483,10 @@ async function handleContentUpdate(db, collection, id, body) {
|
|
|
1353
1483
|
message: `Collection "${collection}" does not have SEO enabled. Remove the seo field or enable SEO on this collection.`
|
|
1354
1484
|
}
|
|
1355
1485
|
};
|
|
1486
|
+
if (body.data) {
|
|
1487
|
+
const mimeCheck = await validateMediaFields(db, collection, body.data);
|
|
1488
|
+
if (!mimeCheck.success) return mimeCheck;
|
|
1489
|
+
}
|
|
1356
1490
|
const resolvedId = await resolveId(new ContentRepository(db), collection, id) ?? id;
|
|
1357
1491
|
const item = await withTransaction(db, async (trx) => {
|
|
1358
1492
|
const trxRepo = new ContentRepository(trx);
|
|
@@ -2869,7 +3003,14 @@ const contentTranslationsResponseSchema = z$1.object({
|
|
|
2869
3003
|
|
|
2870
3004
|
//#endregion
|
|
2871
3005
|
//#region src/api/schemas/media.ts
|
|
2872
|
-
|
|
3006
|
+
/**
|
|
3007
|
+
* Accepts a comma-separated string (from URL query params) or an array of
|
|
3008
|
+
* strings (from JSON body or programmatic use) and normalises to string[].
|
|
3009
|
+
*/
|
|
3010
|
+
const mimeTypeFilter = z$1.union([z$1.string(), z$1.array(z$1.string())]).transform((v) => {
|
|
3011
|
+
return (Array.isArray(v) ? v : v.split(",")).map((s) => s.trim()).filter((s) => s.length > 0);
|
|
3012
|
+
}).optional();
|
|
3013
|
+
const mediaListQuery = cursorPaginationQuery.extend({ mimeType: mimeTypeFilter }).meta({ id: "MediaListQuery" });
|
|
2873
3014
|
const mediaUpdateBody = z$1.object({
|
|
2874
3015
|
alt: z$1.string().optional(),
|
|
2875
3016
|
caption: z$1.string().optional(),
|
|
@@ -2885,7 +3026,7 @@ const mediaConfirmBody = z$1.object({
|
|
|
2885
3026
|
}).meta({ id: "MediaConfirmBody" });
|
|
2886
3027
|
const mediaProviderListQuery = cursorPaginationQuery.extend({
|
|
2887
3028
|
query: z$1.string().optional(),
|
|
2888
|
-
mimeType:
|
|
3029
|
+
mimeType: mimeTypeFilter
|
|
2889
3030
|
}).meta({ id: "MediaProviderListQuery" });
|
|
2890
3031
|
const mediaStatusSchema = z$1.enum([
|
|
2891
3032
|
"pending",
|
|
@@ -2983,7 +3124,8 @@ const fieldValidation = z$1.object({
|
|
|
2983
3124
|
options: z$1.array(z$1.string()).optional(),
|
|
2984
3125
|
subFields: z$1.array(repeaterSubFieldSchema).min(1).optional(),
|
|
2985
3126
|
minItems: z$1.number().int().min(0).optional(),
|
|
2986
|
-
maxItems: z$1.number().int().min(1).optional()
|
|
3127
|
+
maxItems: z$1.number().int().min(1).optional(),
|
|
3128
|
+
allowedMimeTypes: z$1.array(z$1.string().regex(/^[a-z0-9][a-z0-9!#$&^_+\-.]*\/[a-z0-9!#$&^_+\-.]*$/i, "Invalid MIME type")).min(1, "allowedMimeTypes must not be empty — omit the field to allow all types").max(64, "allowedMimeTypes may contain at most 64 entries").optional()
|
|
2987
3129
|
}).optional();
|
|
2988
3130
|
const fieldWidgetOptions = z$1.record(z$1.string(), z$1.unknown()).optional();
|
|
2989
3131
|
const createCollectionBody = z$1.object({
|
|
@@ -3021,7 +3163,7 @@ const createFieldBody = z$1.object({
|
|
|
3021
3163
|
required: z$1.boolean().optional(),
|
|
3022
3164
|
unique: z$1.boolean().optional(),
|
|
3023
3165
|
defaultValue: z$1.unknown().optional(),
|
|
3024
|
-
validation: fieldValidation,
|
|
3166
|
+
validation: fieldValidation.nullable(),
|
|
3025
3167
|
widget: z$1.string().optional(),
|
|
3026
3168
|
options: fieldWidgetOptions,
|
|
3027
3169
|
sortOrder: z$1.number().int().min(0).optional(),
|
|
@@ -3033,7 +3175,7 @@ const updateFieldBody = z$1.object({
|
|
|
3033
3175
|
required: z$1.boolean().optional(),
|
|
3034
3176
|
unique: z$1.boolean().optional(),
|
|
3035
3177
|
defaultValue: z$1.unknown().optional(),
|
|
3036
|
-
validation: fieldValidation,
|
|
3178
|
+
validation: fieldValidation.nullable(),
|
|
3037
3179
|
widget: z$1.string().optional(),
|
|
3038
3180
|
options: fieldWidgetOptions,
|
|
3039
3181
|
sortOrder: z$1.number().int().min(0).optional(),
|
|
@@ -9751,5 +9893,5 @@ function extractSearchableFields(entry, fields) {
|
|
|
9751
9893
|
}
|
|
9752
9894
|
|
|
9753
9895
|
//#endregion
|
|
9754
|
-
export { isSafeHref as $, NoopSandboxRunner as A, handleContentTranslations as At, HookPipeline as B, getAllSources as C, handleContentGetIncludingTrashed as Ct, probeUrl as D, handleContentPublish as Dt, getUrlSources as E, handleContentPermanentDelete as Et, PluginRouteError as F, portableText as Ft, sanitizeHeadersForSandbox as G, resolveExclusiveHooks as H, PluginRouteRegistry as I, reference as It, parseWxr as J, getTrustedProxyHeaders as K, DEV_CONSOLE_EMAIL_PLUGIN_ID as L,
|
|
9755
|
-
//# sourceMappingURL=search-
|
|
9896
|
+
export { isSafeHref as $, NoopSandboxRunner as A, handleContentTranslations as At, HookPipeline as B, getAllSources as C, handleContentGetIncludingTrashed as Ct, probeUrl as D, handleContentPublish as Dt, getUrlSources as E, handleContentPermanentDelete as Et, PluginRouteError as F, portableText as Ft, sanitizeHeadersForSandbox as G, resolveExclusiveHooks as H, PluginRouteRegistry as I, reference as It, parseWxr as J, getTrustedProxyHeaders as K, DEV_CONSOLE_EMAIL_PLUGIN_ID as L, file as Lt, createNoopSandboxRunner as M, handleContentUnschedule as Mt, PluginManager as N, handleContentUpdate as Nt, registerSource as O, handleContentRestore as Ot, createPluginManager as P, validateRev as Pt, prosemirrorToPortableText as Q, devConsoleEmailDeliver as R, image as Rt, clearSources as S, handleContentGet as St, getSource as T, handleContentListTrashed as Tt, CronExecutor as U, createHookPipeline as V, extractRequestMeta as W, after as X, parseWxrString as Y, portableTextToProsemirror as Z, buildPreviewUrl as _, handleContentCountTrashed as _t, search as a, getCollectionInfo as at, parseWxrDate as b, handleContentDiscardDraft as bt, getWidgetArea as c, handleMediaGet as ct, getMenu as d, handleRevisionGet as dt, sanitizeHref as et, getMenus as f, handleRevisionList as ft, isPreviewRequest as g, handleContentCountScheduled as gt, getPreviewToken as h, handleContentCompare as ht, getSuggestions as i, PluginStateRepository as it, SandboxNotAvailableError as j, handleContentUnpublish as jt, importReusableBlocksAsSections as k, handleContentSchedule as kt, getWidgetAreas as l, handleMediaList as lt, getComments as m, generateManifest as mt, extractSearchableFields as n, getSection as nt, searchCollection as o, handleMediaCreate as ot, getCommentCount as p, handleRevisionRestore as pt, definePlugin as q, getSearchStats as r, getSections as rt, searchWithDb as s, handleMediaDelete as st, extractPlainText as t, loadBundleFromR2 as tt, getWidgetComponents as u, handleMediaUpdate as ut, getPreviewUrl as v, handleContentCreate as vt, getFileSources as w, handleContentList as wt, wxrSource as x, handleContentDuplicate as xt, wordpressRestSource as y, handleContentDelete as yt, EmailPipeline as z };
|
|
9897
|
+
//# sourceMappingURL=search-DuWhx4NG.mjs.map
|