@easy-cms/core 1.28.0 → 1.29.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.
@@ -26,9 +26,12 @@ import {
26
26
  imageDimensions,
27
27
  isHasMany,
28
28
  isPassingError,
29
+ isPolymorphic,
29
30
  isPrivateKey,
30
31
  mimeAllowed,
31
32
  mimeAllowedBy,
33
+ polymorphicValue,
34
+ relationTargets,
32
35
  rowFields,
33
36
  sizeKey,
34
37
  sniffMimeType,
@@ -38,7 +41,7 @@ import {
38
41
  warnDeprecated,
39
42
  withCharset,
40
43
  withPrivacy
41
- } from "./chunk-SYUQX2G6.js";
44
+ } from "./chunk-NASM44FJ.js";
42
45
 
43
46
  // src/access.ts
44
47
  var isSystemAdmin = (user) => user?.role === "admin" && !user.apiKey && user.scoped !== true;
@@ -2804,20 +2807,31 @@ async function normalizeValue(field, raw, path, options, fail, errors, reference
2804
2807
  }
2805
2808
  case "upload":
2806
2809
  case "relationship": {
2807
- const target = field.type === "upload" ? "media" : field.to;
2810
+ const targets = relationTargets(field);
2811
+ const poly = isPolymorphic(field);
2808
2812
  const many = field.hasMany === true;
2809
2813
  const values = many ? raw : [raw];
2810
- if (!Array.isArray(values)) return fail("must be an array of ids");
2814
+ if (!Array.isArray(values))
2815
+ return fail(poly ? "must be an array of { relationTo, value }" : "must be an array of ids");
2811
2816
  if (many && field.minRows !== void 0 && values.length < field.minRows)
2812
2817
  return fail(`must have at least ${itemsOf(field, field.minRows)}`);
2813
2818
  if (many && field.maxRows !== void 0 && values.length > field.maxRows)
2814
2819
  return fail(`must have at most ${itemsOf(field, field.maxRows)}`);
2815
- const ids = [];
2820
+ const out = [];
2816
2821
  for (const item of values) {
2817
- const id = parseId(isPlainObject(item) ? item.id : item);
2822
+ const pair = poly ? polymorphicValue(item) : void 0;
2823
+ if (poly && (!pair || !targets.includes(pair.relationTo)))
2824
+ return fail(
2825
+ pair ? `can't link to "${pair.relationTo}": use one of ${targets.map((t) => `"${t}"`).join(", ")}` : `must be ${many ? "a list of" : ""} { relationTo, value } with relationTo one of ${targets.map((t) => `"${t}"`).join(", ")}`
2826
+ );
2827
+ const target = pair ? pair.relationTo : targets[0];
2828
+ const rawId = pair ? pair.value : item;
2829
+ const id = parseId(isPlainObject(rawId) ? rawId.id : rawId);
2818
2830
  if (id === void 0)
2819
- return fail(`must be ${many ? "ids" : "an id"} of "${target}" documents`);
2820
- ids.push(id);
2831
+ return fail(
2832
+ poly ? `must have the id of a "${target}" document as value` : `must be ${many ? "ids" : "an id"} of "${target}" documents`
2833
+ );
2834
+ out.push(pair ? { relationTo: target, value: id } : id);
2821
2835
  references2.push({
2822
2836
  field: path,
2823
2837
  collection: target,
@@ -2827,7 +2841,7 @@ async function normalizeValue(field, raw, path, options, fail, errors, reference
2827
2841
  ...field.type === "upload" && field.folder && field.folderOnly ? { folderOnly: field.folder } : {}
2828
2842
  });
2829
2843
  }
2830
- return many ? ids : ids[0];
2844
+ return many ? out : out[0];
2831
2845
  }
2832
2846
  case "array": {
2833
2847
  if (!Array.isArray(raw)) return fail("must be an array");
@@ -4021,9 +4035,34 @@ function collectSlots(fields, data, bySlug, slots, linkURL) {
4021
4035
  }
4022
4036
  });
4023
4037
  }
4038
+ } else if (isPolymorphic(field)) {
4039
+ const many = Array.isArray(value);
4040
+ const items = (many ? value : [value]).map(polymorphicValue);
4041
+ if (items.some((item) => item === void 0)) continue;
4042
+ const pairs = items;
4043
+ const found = /* @__PURE__ */ new Map();
4044
+ let waiting = 0;
4045
+ for (const relationTo of new Set(pairs.map((p) => p.relationTo))) {
4046
+ if (!bySlug.has(relationTo)) continue;
4047
+ waiting++;
4048
+ slots.push({
4049
+ collection: relationTo,
4050
+ ids: pairs.filter((p) => p.relationTo === relationTo).map((p) => p.value),
4051
+ assign: (byId) => {
4052
+ found.set(relationTo, byId);
4053
+ if (--waiting > 0) return;
4054
+ const filled = pairs.map((p) => {
4055
+ if (!bySlug.has(p.relationTo)) return p;
4056
+ const doc = found.get(p.relationTo)?.get(p.value);
4057
+ return doc ? { relationTo: p.relationTo, value: doc } : void 0;
4058
+ }).filter((p) => p !== void 0);
4059
+ data[field.name] = many ? filled : filled[0] ?? null;
4060
+ }
4061
+ });
4062
+ }
4024
4063
  } else if (field.type === "relationship" || field.type === "upload") {
4025
4064
  if (typeof value === "object" && !Array.isArray(value)) continue;
4026
- const collection2 = field.type === "upload" ? "media" : field.to;
4065
+ const collection2 = relationTargets(field)[0];
4027
4066
  if (!bySlug.has(collection2)) continue;
4028
4067
  if (Array.isArray(value)) {
4029
4068
  const ids = value;
@@ -7346,16 +7385,24 @@ function validateField(field, path, siblings, collectionSlugs, add) {
7346
7385
  }
7347
7386
  }
7348
7387
  break;
7349
- case "relationship":
7350
- if (typeof field.to !== "string" || !collectionSlugs.has(field.to)) {
7351
- add(
7352
- `${path}.to`,
7353
- `unknown collection ${JSON.stringify(field.to)}`,
7354
- `use one of: ${[...collectionSlugs].join(", ")}`
7355
- );
7388
+ case "relationship": {
7389
+ const to = field.to;
7390
+ if (Array.isArray(to)) {
7391
+ if (to.length === 0) add(`${path}.to`, "needs at least one collection");
7392
+ if (new Set(to).size !== to.length) add(`${path}.to`, "names a collection twice");
7393
+ }
7394
+ for (const target of Array.isArray(to) ? to : [to]) {
7395
+ if (typeof target !== "string" || !collectionSlugs.has(target)) {
7396
+ add(
7397
+ `${path}.to`,
7398
+ `unknown collection ${JSON.stringify(target)}`,
7399
+ `use one of: ${[...collectionSlugs].join(", ")}`
7400
+ );
7401
+ }
7356
7402
  }
7357
7403
  validateManyRange(field, path, add);
7358
7404
  break;
7405
+ }
7359
7406
  case "upload":
7360
7407
  validateManyRange(field, path, add);
7361
7408
  if (field.folder !== void 0 && !FOLDER_KEY.test(String(field.folder)))
@@ -7932,7 +7979,7 @@ function cacheableResponse(request, body, status, headers, times, tags) {
7932
7979
  }
7933
7980
 
7934
7981
  // src/version.ts
7935
- var VERSION = true ? "1.28.0" : "0.0.0-dev";
7982
+ var VERSION = true ? "1.29.0" : "0.0.0-dev";
7936
7983
 
7937
7984
  // src/telemetry.ts
7938
7985
  var DB_CALLS = /* @__PURE__ */ new Set([
@@ -11048,9 +11095,14 @@ var EasyCMS = class {
11048
11095
  for (const ref of references2) {
11049
11096
  const filter = ref.filterOptions;
11050
11097
  if (!filter) continue;
11051
- if (!allowed2.has(filter))
11052
- allowed2.set(filter, await filter({ id: selfId, user, cms, context }));
11053
- const where = allowed2.get(filter);
11098
+ const byCollection = allowed2.get(filter) ?? /* @__PURE__ */ new Map();
11099
+ allowed2.set(filter, byCollection);
11100
+ if (!byCollection.has(ref.collection))
11101
+ byCollection.set(
11102
+ ref.collection,
11103
+ await filter({ id: selfId, relationTo: ref.collection, user, cms, context })
11104
+ );
11105
+ const where = byCollection.get(ref.collection);
11054
11106
  if (where === true) continue;
11055
11107
  const target = this.config.collections.find((c) => c.slug === ref.collection);
11056
11108
  const localization = this.config.localization;
@@ -11487,8 +11539,8 @@ function ruleFields(fields) {
11487
11539
  }
11488
11540
  function references(fields, out = /* @__PURE__ */ new Set()) {
11489
11541
  for (const field of fields) {
11490
- if (field.type === "relationship") out.add(field.to);
11491
- else if (field.type === "upload") out.add("media");
11542
+ if (field.type === "relationship" || field.type === "upload")
11543
+ for (const target of relationTargets(field)) out.add(target);
11492
11544
  else if (field.type === "group" || field.type === "array") references(field.fields, out);
11493
11545
  else if (field.type === "blocks") for (const b of field.blocks) references(b.fields, out);
11494
11546
  }
@@ -12350,7 +12402,7 @@ async function serializeFields(fields, checks, localized, folderId, who) {
12350
12402
  if (field.from) f.from = field.from;
12351
12403
  break;
12352
12404
  case "relationship":
12353
- f.to = field.to;
12405
+ f.to = typeof field.to === "string" ? field.to : [...field.to];
12354
12406
  if (field.hasMany) f.hasMany = true;
12355
12407
  if (field.minRows !== void 0) f.minRows = field.minRows;
12356
12408
  if (field.maxRows !== void 0) f.maxRows = field.maxRows;
@@ -12902,13 +12954,12 @@ async function pickerFilter(cms, url, target, user, context = {}) {
12902
12954
  const slug2 = dot > 0 ? spec.slice(0, dot) : "";
12903
12955
  const owner = forCollection !== null ? cms.config.collections.find((c) => c.slug === slug2) : cms.config.globals.find((g) => g.slug === slug2);
12904
12956
  const field = owner ? fieldAt2(owner.fields, spec.slice(dot + 1)) : void 0;
12905
- const to = field?.type === "upload" ? "media" : field?.type === "relationship" ? field.to : null;
12906
- if (!field || field.type !== "relationship" && field.type !== "upload" || to !== target)
12957
+ if (!field || field.type !== "relationship" && field.type !== "upload" || !relationTargets(field).includes(target))
12907
12958
  throw new QueryError(`filterFor: no relationship to "${target}" at "${spec}"`);
12908
12959
  if (!field.filterOptions) return void 0;
12909
12960
  const rawId = url.searchParams.get("filterId");
12910
12961
  const id = rawId === null || rawId === "" ? void 0 : /^\d+$/.test(rawId) ? Number(rawId) : rawId;
12911
- const where = await field.filterOptions({ id, user, cms, context });
12962
+ const where = await field.filterOptions({ id, relationTo: target, user, cms, context });
12912
12963
  return where === true ? void 0 : where;
12913
12964
  }
12914
12965
 
@@ -333,6 +333,17 @@ function mimeAllowedBy(mimeType, patterns) {
333
333
  });
334
334
  }
335
335
  var SVG = "image/svg+xml";
336
+ var isPolymorphic = (field) => field.type === "relationship" && Array.isArray(field.to);
337
+ function relationTargets(field) {
338
+ if (field.type === "upload") return ["media"];
339
+ if (field.type !== "relationship") return [];
340
+ return typeof field.to === "string" ? [field.to] : field.to;
341
+ }
342
+ function polymorphicValue(value) {
343
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
344
+ const { relationTo } = value;
345
+ return typeof relationTo === "string" ? { relationTo, value: value.value } : void 0;
346
+ }
336
347
  var hasRows = (field) => field.type === "array" || field.type === "blocks";
337
348
  function rowFields(field, row) {
338
349
  if (field.type === "array") return field.fields;
@@ -592,6 +603,9 @@ export {
592
603
  uniqueWithinOf,
593
604
  isHasMany,
594
605
  mimeAllowedBy,
606
+ isPolymorphic,
607
+ relationTargets,
608
+ polymorphicValue,
595
609
  hasRows,
596
610
  rowFields,
597
611
  TRIGRAM_LIKE_MIN,
@@ -933,6 +933,8 @@ interface UploadField extends BaseField<'upload', never> {
933
933
  interface FilterOptionsArgs {
934
934
  /** The document being edited; `undefined` while it is being created. */
935
935
  readonly id: ID | undefined;
936
+ /** The collection the choices come from: one of the field's `to`. */
937
+ readonly relationTo: string;
936
938
  readonly user: AuthUser | null;
937
939
  readonly cms: EasyCMS;
938
940
  /** The request's context (`onRequest`), `{}` when there is none. */
@@ -944,8 +946,11 @@ interface FilterOptionsArgs {
944
946
  */
945
947
  type FilterOptions = (args: FilterOptionsArgs) => Where | true | Promise<Where | true>;
946
948
  interface RelationshipField extends BaseField<'relationship', never> {
947
- /** Slug of the target collection. */
948
- readonly to: string;
949
+ /**
950
+ * Slug of the target collection, or several: then each value is `{ relationTo, value }`, the
951
+ * collection and the document's id (#327).
952
+ */
953
+ readonly to: string | readonly string[];
949
954
  readonly hasMany?: boolean;
950
955
  /** With `hasMany`: the fewest documents. */
951
956
  readonly minRows?: number;
@@ -989,6 +994,17 @@ declare const isHasMany: (field: Field) => boolean;
989
994
  * carry scripts and is allowed only when listed by name: `image/svg+xml`).
990
995
  */
991
996
  declare function mimeAllowedBy(mimeType: string, patterns: readonly string[]): boolean;
997
+ /** A relationship to several collections: its values are `{ relationTo, value }` (#327). */
998
+ declare const isPolymorphic: (field: Field) => field is RelationshipField & {
999
+ readonly to: readonly string[];
1000
+ };
1001
+ /** The collections a relationship or upload field points to. */
1002
+ declare function relationTargets(field: Field): readonly string[];
1003
+ /** A `{ relationTo, value }` of a relationship to several collections, or `undefined`. */
1004
+ declare function polymorphicValue(value: unknown): {
1005
+ relationTo: string;
1006
+ value: unknown;
1007
+ } | undefined;
992
1008
  /** Fields whose value is a list of rows: `array` and `blocks`. */
993
1009
  declare const hasRows: (field: Field) => field is ArrayField | BlocksField;
994
1010
  /** The fields of one row of an `array` or `blocks` field (`undefined` for an unknown block). */
@@ -1162,6 +1178,14 @@ type GlobalBySlug<C extends Config, S> = WithPluginFields<C, Extract<NonNullable
1162
1178
  type RelationValue<C extends Config, S, A extends boolean> = [CollectionBySlug<C, S>] extends [
1163
1179
  never
1164
1180
  ] ? ID | Record<string, unknown> : ID | CollectionDocument<C, S & string, A>;
1181
+ /**
1182
+ * A relationship to several collections (#327): `{ relationTo, value }` per collection, so
1183
+ * checking `relationTo` narrows `value`.
1184
+ */
1185
+ type PolymorphicValue<C extends Config, To, V extends 'output' | 'input', A extends boolean> = To extends readonly (infer S)[] ? S extends string ? {
1186
+ relationTo: S;
1187
+ value: V extends 'input' ? ID : RelationValue<C, S, A>;
1188
+ } : never : never;
1165
1189
  /** The content locales of a config (`localization.locales`); `string` when not literal. */
1166
1190
  type LocaleOf<C extends Config> = C extends {
1167
1191
  readonly localization: {
@@ -1174,6 +1198,11 @@ type LocaleOf<C extends Config> = C extends {
1174
1198
  */
1175
1199
  type LocaleMap<F extends Field, C extends Config> = {
1176
1200
  [L in LocaleOf<C>]?: (F extends {
1201
+ readonly type: 'relationship';
1202
+ readonly to: infer To extends readonly string[];
1203
+ } ? F extends {
1204
+ readonly hasMany: true;
1205
+ } ? PolymorphicValue<C, To, 'input', false>[] : PolymorphicValue<C, To, 'input', false> : F extends {
1177
1206
  readonly type: 'relationship' | 'upload';
1178
1207
  } ? F extends {
1179
1208
  readonly hasMany: true;
@@ -1232,6 +1261,11 @@ type OneLocaleValue<F extends Field, C extends Config, A extends boolean> = F ex
1232
1261
  } ? F extends {
1233
1262
  readonly hasMany: true;
1234
1263
  } ? (ID | MediaDocument)[] : ID | MediaDocument : F extends {
1264
+ readonly type: 'relationship';
1265
+ readonly to: infer To extends readonly string[];
1266
+ } ? F extends {
1267
+ readonly hasMany: true;
1268
+ } ? PolymorphicValue<C, To, 'output', A>[] : PolymorphicValue<C, To, 'output', A> : F extends {
1235
1269
  readonly type: 'relationship';
1236
1270
  readonly to: infer S;
1237
1271
  } ? F extends {
@@ -1328,6 +1362,11 @@ type CollectionDocument<C extends Config, S extends CollectionSlug<C>, AllLocale
1328
1362
  type GlobalDocument<C extends Config, S extends GlobalSlug<C>, AllLocales extends boolean = false> = InferGlobal<GlobalBySlug<C, S>, C, AllLocales>;
1329
1363
  type InputValue<F extends Field> = F extends {
1330
1364
  readonly type: 'relationship';
1365
+ readonly to: infer To extends readonly string[];
1366
+ } ? F extends {
1367
+ readonly hasMany: true;
1368
+ } ? readonly PolymorphicValue<Config, To, 'input', false>[] : PolymorphicValue<Config, To, 'input', false> : F extends {
1369
+ readonly type: 'relationship';
1331
1370
  } ? F extends {
1332
1371
  readonly hasMany: true;
1333
1372
  } ? readonly ID[] : ID : F extends {
@@ -3821,5 +3860,5 @@ interface ResolvedConfig extends Omit<Config, 'cors' | 'localization' | 'routes'
3821
3860
  */
3822
3861
  declare function defineConfig<const TConfig extends Config>(config: TConfig): TConfig;
3823
3862
 
3824
- export { ADAPTER_API_VERSION as A, EasyCMS as E, AuditLog as _, Auth as a1, EasyCMSError as aI, FIELD_TYPES as aP, ConfigError as ar, ForbiddenError as b7, PLUGIN_API_VERSION as bE, PayloadTooLargeError as bJ, QueryError as bP, ROLE_OPERATIONS as bQ, Roles as b_, NotFoundError as by, silentLogger as c$, SchemaError as c1, ValidationError as cB, WEBHOOK_EVENTS as cF, anyone as cJ, consoleEmail as cK, consoleLogger as cL, createEasyCMS as cM, defineConfig as cN, defineFieldType as cO, definePlugin as cP, diskStorage as cQ, hasRows as cR, isAdmin as cS, isHasMany as cT, isSignedIn as cU, isStaff as cV, isSystemAdmin as cW, jsonLogger as cX, memorySearch as cY, mimeAllowedBy as cZ, rowFields as c_, SingleSignOn as cg, TRIGRAM_LIKE_MIN as cn, TooManyRequestsError as cr, UnauthorizedError as cu, uniqueWithinOf as d0, API_KEYS as d1, API_KEY_GLOBAL_OPERATIONS as d2, API_KEY_OPERATIONS as d3, DEFAULT_MAX_VERSIONS as d4, DEFAULT_PASSWORD_EMAILS as d5, FIELD_TYPE_BASES as d6, FOLDER_LEVELS as d7, MediaFolders as d8, SSO_COOKIE as d9, codeOfStatus as db, isJsonLogger as dc, keyAllows as dd, logFormat as de, secretsOf as df, ADMIN_ICONS as j };
3825
- export type { AuditPage as $, AdminRoles as B, Config as C, AdminSso as D, Field as F, GlobalSlug as G, AdminSwitcher as H, ID as I, AdminViewAccess as J, AfterChangeHook as K, LocalizationConfig as L, AfterDeleteHook as M, AfterReadHook as N, ApiKeyContext as O, PaginatedDocs as P, ApiKeyGlobalOperation as Q, ResolvedConfig as R, ApiKeyOperation as S, ApiKeyPermissions as T, UncountedDocs as U, ArrayField as V, Where as W, AuditChange as X, AuditConfig as Y, AuditEntry as Z, CollectionSlug as a, FieldsInput as a$, AuditVerification as a0, AuthConfig as a2, AuthProvider as a3, AuthProviderProfile as a4, AuthProviderRequest as a5, AuthUser as a6, BackupsConfig as a7, BeforeChangeHook as a8, BeforeDeleteHook as a9, DatabaseAdapter as aA, DatabaseInitArgs as aB, DatabaseTransfer as aC, DateField as aD, DepthOptions as aE, DirectUpload as aF, DiskStorageOptions as aG, DocumentOf as aH, EmailAdapter as aJ, EmailField as aK, EmailMessage as aL, Endpoint as aM, EndpointRequest as aN, ErrorCode as aO, FieldAccess as aQ, FieldAccessFn as aR, FieldAdmin as aS, FieldRule as aT, FieldType as aU, FieldTypeBase as aV, FieldTypeDefinition as aW, FieldTypeValidateContext as aX, FieldValidate as aY, FieldValidateContext as aZ, FieldValue as a_, BeforeValidateHook as aa, Block as ab, BlocksField as ac, BooleanField as ad, BuiltinApiKeysCollection as ae, BuiltinMediaCollection as af, BuiltinMediaFoldersCollection as ag, BuiltinUsersCollection as ah, BundleHints as ai, CliCommand as aj, CollectionAccess as ak, CollectionAdmin as al, CollectionCalendarAdmin as am, CollectionConfig as an, CollectionHooks as ao, CollectionListAdmin as ap, CollectionSearch as aq, ConfigIssue as as, ContainerAdmin as at, CreateInput as au, CreateMigrationResult as av, CustomField as aw, CustomFieldTypes as ax, DashboardWidget as ay, Database as az, CollectionDocument as b, RoutesConfig as b$, FieldsValue as b0, FilterOptionsArgs as b1, FindAfterArgs as b2, FindArgs as b3, FindOptions as b4, FolderLevel as b5, FolderPermissions as b6, GlobalAccess as b8, GlobalConfig as b9, OnRequest as bA, OnRequestArgs as bB, Operation as bC, OutboxRow as bD, PasswordEmail as bF, PasswordEmailArgs as bG, PasswordEmailFn as bH, PasswordLinkOptions as bI, Plugin as bK, PluginInfo as bL, PluginTypes as bM, PreviewTarget as bN, PreviewURL as bO, RawDocument as bR, ReadOptions as bS, RelationshipField as bT, RequestContext as bU, RichTextDocument as bV, RichTextField as bW, Role as bX, RoleOperation as bY, RolePermissions as bZ, GlobalHooks as ba, GlobalInput as bb, GroupField as bc, ImageSize as bd, IncrementOptions as be, InferCollection as bf, InferGlobal as bg, JobConfig as bh, JsonField as bi, KeysetPage as bj, Label as bk, LayoutNode as bl, LivePreview as bm, LocaleOf as bn, LogDetails as bo, Logger as bp, LoginArgs as bq, LogsConfig as br, MediaDocument as bs, MediaSize as bt, MembersConfig as bu, MembersSignup as bv, MigrationInfo as bw, NavGroup as bx, NumberField as bz, CursorDocs as c, ScheduledPublish as c0, SchemaMode as c2, SearchAdapter as c3, SearchEntry as c4, SearchHits as c5, SearchOptions as c6, SearchQuery as c7, SearchResults as c8, SearchSetting as c9, UserIdentity as cA, Version as cC, VersionSummary as cD, VersionsConfig as cE, WebhookConfig as cG, WebhookEvent as cH, WhereOperators as cI, SelectField as ca, SelectOption as cb, Session as cc, SidebarPanel as cd, SignupArgs as ce, SignupResult as cf, SlugField as ch, SlugOf as ci, SsoOutcome as cj, SsoProviderRef as ck, StorageAdapter as cl, StoredFile as cm, TelemetryConfig as co, TextField as cp, TextareaField as cq, TypedPlugin as cs, UiField as ct, UpdateInput as cv, UpdateOptions as cw, UploadConfig as cx, UploadField as cy, UploadFromURLConfig as cz, GlobalDocument as d, Secrets as da, FieldError as e, FilterOptions as f, CreateEasyCMSOptions as g, EmailSetting as h, WebhookPayload as i, Access as k, AccessArgs as l, AccessOptions as m, AdminBrand as n, AdminCommand as o, AdminComponent as p, AdminConfig as q, AdminFieldArgs as r, AdminIcon as s, AdminLocale as t, AdminPage as u, AdminRole as v, AdminRoleChange as w, AdminRoleField as x, AdminRoleTarget as y, AdminRoleView as z };
3863
+ export { ADAPTER_API_VERSION as A, EasyCMS as E, AuditLog as _, Auth as a1, EasyCMSError as aI, FIELD_TYPES as aP, ConfigError as ar, ForbiddenError as b7, PLUGIN_API_VERSION as bE, PayloadTooLargeError as bJ, QueryError as bP, ROLE_OPERATIONS as bQ, Roles as b_, NotFoundError as by, polymorphicValue as c$, SchemaError as c1, ValidationError as cB, WEBHOOK_EVENTS as cF, anyone as cJ, consoleEmail as cK, consoleLogger as cL, createEasyCMS as cM, defineConfig as cN, defineFieldType as cO, definePlugin as cP, diskStorage as cQ, hasRows as cR, isAdmin as cS, isHasMany as cT, isPolymorphic as cU, isSignedIn as cV, isStaff as cW, isSystemAdmin as cX, jsonLogger as cY, memorySearch as cZ, mimeAllowedBy as c_, SingleSignOn as cg, TRIGRAM_LIKE_MIN as cn, TooManyRequestsError as cr, UnauthorizedError as cu, relationTargets as d0, rowFields as d1, silentLogger as d2, uniqueWithinOf as d3, API_KEYS as d4, API_KEY_GLOBAL_OPERATIONS as d5, API_KEY_OPERATIONS as d6, DEFAULT_MAX_VERSIONS as d7, DEFAULT_PASSWORD_EMAILS as d8, FIELD_TYPE_BASES as d9, FOLDER_LEVELS as da, MediaFolders as db, SSO_COOKIE as dc, codeOfStatus as de, isJsonLogger as df, keyAllows as dg, logFormat as dh, secretsOf as di, ADMIN_ICONS as j };
3864
+ export type { AuditPage as $, AdminRoles as B, Config as C, AdminSso as D, Field as F, GlobalSlug as G, AdminSwitcher as H, ID as I, AdminViewAccess as J, AfterChangeHook as K, LocalizationConfig as L, AfterDeleteHook as M, AfterReadHook as N, ApiKeyContext as O, PaginatedDocs as P, ApiKeyGlobalOperation as Q, ResolvedConfig as R, ApiKeyOperation as S, ApiKeyPermissions as T, UncountedDocs as U, ArrayField as V, Where as W, AuditChange as X, AuditConfig as Y, AuditEntry as Z, CollectionSlug as a, FieldsInput as a$, AuditVerification as a0, AuthConfig as a2, AuthProvider as a3, AuthProviderProfile as a4, AuthProviderRequest as a5, AuthUser as a6, BackupsConfig as a7, BeforeChangeHook as a8, BeforeDeleteHook as a9, DatabaseAdapter as aA, DatabaseInitArgs as aB, DatabaseTransfer as aC, DateField as aD, DepthOptions as aE, DirectUpload as aF, DiskStorageOptions as aG, DocumentOf as aH, EmailAdapter as aJ, EmailField as aK, EmailMessage as aL, Endpoint as aM, EndpointRequest as aN, ErrorCode as aO, FieldAccess as aQ, FieldAccessFn as aR, FieldAdmin as aS, FieldRule as aT, FieldType as aU, FieldTypeBase as aV, FieldTypeDefinition as aW, FieldTypeValidateContext as aX, FieldValidate as aY, FieldValidateContext as aZ, FieldValue as a_, BeforeValidateHook as aa, Block as ab, BlocksField as ac, BooleanField as ad, BuiltinApiKeysCollection as ae, BuiltinMediaCollection as af, BuiltinMediaFoldersCollection as ag, BuiltinUsersCollection as ah, BundleHints as ai, CliCommand as aj, CollectionAccess as ak, CollectionAdmin as al, CollectionCalendarAdmin as am, CollectionConfig as an, CollectionHooks as ao, CollectionListAdmin as ap, CollectionSearch as aq, ConfigIssue as as, ContainerAdmin as at, CreateInput as au, CreateMigrationResult as av, CustomField as aw, CustomFieldTypes as ax, DashboardWidget as ay, Database as az, CollectionDocument as b, RoutesConfig as b$, FieldsValue as b0, FilterOptionsArgs as b1, FindAfterArgs as b2, FindArgs as b3, FindOptions as b4, FolderLevel as b5, FolderPermissions as b6, GlobalAccess as b8, GlobalConfig as b9, OnRequest as bA, OnRequestArgs as bB, Operation as bC, OutboxRow as bD, PasswordEmail as bF, PasswordEmailArgs as bG, PasswordEmailFn as bH, PasswordLinkOptions as bI, Plugin as bK, PluginInfo as bL, PluginTypes as bM, PreviewTarget as bN, PreviewURL as bO, RawDocument as bR, ReadOptions as bS, RelationshipField as bT, RequestContext as bU, RichTextDocument as bV, RichTextField as bW, Role as bX, RoleOperation as bY, RolePermissions as bZ, GlobalHooks as ba, GlobalInput as bb, GroupField as bc, ImageSize as bd, IncrementOptions as be, InferCollection as bf, InferGlobal as bg, JobConfig as bh, JsonField as bi, KeysetPage as bj, Label as bk, LayoutNode as bl, LivePreview as bm, LocaleOf as bn, LogDetails as bo, Logger as bp, LoginArgs as bq, LogsConfig as br, MediaDocument as bs, MediaSize as bt, MembersConfig as bu, MembersSignup as bv, MigrationInfo as bw, NavGroup as bx, NumberField as bz, CursorDocs as c, ScheduledPublish as c0, SchemaMode as c2, SearchAdapter as c3, SearchEntry as c4, SearchHits as c5, SearchOptions as c6, SearchQuery as c7, SearchResults as c8, SearchSetting as c9, UserIdentity as cA, Version as cC, VersionSummary as cD, VersionsConfig as cE, WebhookConfig as cG, WebhookEvent as cH, WhereOperators as cI, SelectField as ca, SelectOption as cb, Session as cc, SidebarPanel as cd, SignupArgs as ce, SignupResult as cf, SlugField as ch, SlugOf as ci, SsoOutcome as cj, SsoProviderRef as ck, StorageAdapter as cl, StoredFile as cm, TelemetryConfig as co, TextField as cp, TextareaField as cq, TypedPlugin as cs, UiField as ct, UpdateInput as cv, UpdateOptions as cw, UploadConfig as cx, UploadField as cy, UploadFromURLConfig as cz, GlobalDocument as d, Secrets as dd, FieldError as e, FilterOptions as f, CreateEasyCMSOptions as g, EmailSetting as h, WebhookPayload as i, Access as k, AccessArgs as l, AccessOptions as m, AdminBrand as n, AdminCommand as o, AdminComponent as p, AdminConfig as q, AdminFieldArgs as r, AdminIcon as s, AdminLocale as t, AdminPage as u, AdminRole as v, AdminRoleChange as w, AdminRoleField as x, AdminRoleTarget as y, AdminRoleView as z };
@@ -1,4 +1,4 @@
1
- import { I as ID, C as Config, E as EasyCMS, L as LocalizationConfig, F as Field, e as FieldError, f as FilterOptions, g as CreateEasyCMSOptions, R as ResolvedConfig } from './config-BLNPAco2.js';
1
+ import { I as ID, C as Config, E as EasyCMS, L as LocalizationConfig, F as Field, e as FieldError, f as FilterOptions, g as CreateEasyCMSOptions, R as ResolvedConfig } from './config-CmK2kPvg.js';
2
2
 
3
3
  /** Decrypts a file from `encryptBackup`; throws for another key or a changed file. */
4
4
  declare function decryptBackup(data: Uint8Array, encryptionKey: string): Uint8Array;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { P as PaginatedDocs, I as ID, h as EmailSetting, i as WebhookPayload } from './config-BLNPAco2.js';
2
- export { A as ADAPTER_API_VERSION, j as ADMIN_ICONS, k as Access, l as AccessArgs, m as AccessOptions, n as AdminBrand, o as AdminCommand, p as AdminComponent, q as AdminConfig, r as AdminFieldArgs, s as AdminIcon, t as AdminLocale, u as AdminPage, v as AdminRole, w as AdminRoleChange, x as AdminRoleField, y as AdminRoleTarget, z as AdminRoleView, B as AdminRoles, D as AdminSso, H as AdminSwitcher, J as AdminViewAccess, K as AfterChangeHook, M as AfterDeleteHook, N as AfterReadHook, O as ApiKeyContext, Q as ApiKeyGlobalOperation, S as ApiKeyOperation, T as ApiKeyPermissions, V as ArrayField, X as AuditChange, Y as AuditConfig, Z as AuditEntry, _ as AuditLog, $ as AuditPage, a0 as AuditVerification, a1 as Auth, a2 as AuthConfig, a3 as AuthProvider, a4 as AuthProviderProfile, a5 as AuthProviderRequest, a6 as AuthUser, a7 as BackupsConfig, a8 as BeforeChangeHook, a9 as BeforeDeleteHook, aa as BeforeValidateHook, ab as Block, ac as BlocksField, ad as BooleanField, ae as BuiltinApiKeysCollection, af as BuiltinMediaCollection, ag as BuiltinMediaFoldersCollection, ah as BuiltinUsersCollection, ai as BundleHints, aj as CliCommand, ak as CollectionAccess, al as CollectionAdmin, am as CollectionCalendarAdmin, an as CollectionConfig, b as CollectionDocument, ao as CollectionHooks, ap as CollectionListAdmin, aq as CollectionSearch, a as CollectionSlug, C as Config, ar as ConfigError, as as ConfigIssue, at as ContainerAdmin, g as CreateEasyCMSOptions, au as CreateInput, av as CreateMigrationResult, c as CursorDocs, aw as CustomField, ax as CustomFieldTypes, ay as DashboardWidget, az as Database, aA as DatabaseAdapter, aB as DatabaseInitArgs, aC as DatabaseTransfer, aD as DateField, aE as DepthOptions, aF as DirectUpload, aG as DiskStorageOptions, aH as DocumentOf, E as EasyCMS, aI as EasyCMSError, aJ as EmailAdapter, aK as EmailField, aL as EmailMessage, aM as Endpoint, aN as EndpointRequest, aO as ErrorCode, aP as FIELD_TYPES, F as Field, aQ as FieldAccess, aR as FieldAccessFn, aS as FieldAdmin, e as FieldError, aT as FieldRule, aU as FieldType, aV as FieldTypeBase, aW as FieldTypeDefinition, aX as FieldTypeValidateContext, aY as FieldValidate, aZ as FieldValidateContext, a_ as FieldValue, a$ as FieldsInput, b0 as FieldsValue, f as FilterOptions, b1 as FilterOptionsArgs, b2 as FindAfterArgs, b3 as FindArgs, b4 as FindOptions, b5 as FolderLevel, b6 as FolderPermissions, b7 as ForbiddenError, b8 as GlobalAccess, b9 as GlobalConfig, d as GlobalDocument, ba as GlobalHooks, bb as GlobalInput, G as GlobalSlug, bc as GroupField, bd as ImageSize, be as IncrementOptions, bf as InferCollection, bg as InferGlobal, bh as JobConfig, bi as JsonField, bj as KeysetPage, bk as Label, bl as LayoutNode, bm as LivePreview, bn as LocaleOf, L as LocalizationConfig, bo as LogDetails, bp as Logger, bq as LoginArgs, br as LogsConfig, bs as MediaDocument, bt as MediaSize, bu as MembersConfig, bv as MembersSignup, bw as MigrationInfo, bx as NavGroup, by as NotFoundError, bz as NumberField, bA as OnRequest, bB as OnRequestArgs, bC as Operation, bD as OutboxRow, bE as PLUGIN_API_VERSION, bF as PasswordEmail, bG as PasswordEmailArgs, bH as PasswordEmailFn, bI as PasswordLinkOptions, bJ as PayloadTooLargeError, bK as Plugin, bL as PluginInfo, bM as PluginTypes, bN as PreviewTarget, bO as PreviewURL, bP as QueryError, bQ as ROLE_OPERATIONS, bR as RawDocument, bS as ReadOptions, bT as RelationshipField, bU as RequestContext, R as ResolvedConfig, bV as RichTextDocument, bW as RichTextField, bX as Role, bY as RoleOperation, bZ as RolePermissions, b_ as Roles, b$ as RoutesConfig, c0 as ScheduledPublish, c1 as SchemaError, c2 as SchemaMode, c3 as SearchAdapter, c4 as SearchEntry, c5 as SearchHits, c6 as SearchOptions, c7 as SearchQuery, c8 as SearchResults, c9 as SearchSetting, ca as SelectField, cb as SelectOption, cc as Session, cd as SidebarPanel, ce as SignupArgs, cf as SignupResult, cg as SingleSignOn, ch as SlugField, ci as SlugOf, cj as SsoOutcome, ck as SsoProviderRef, cl as StorageAdapter, cm as StoredFile, cn as TRIGRAM_LIKE_MIN, co as TelemetryConfig, cp as TextField, cq as TextareaField, cr as TooManyRequestsError, cs as TypedPlugin, ct as UiField, cu as UnauthorizedError, U as UncountedDocs, cv as UpdateInput, cw as UpdateOptions, cx as UploadConfig, cy as UploadField, cz as UploadFromURLConfig, cA as UserIdentity, cB as ValidationError, cC as Version, cD as VersionSummary, cE as VersionsConfig, cF as WEBHOOK_EVENTS, cG as WebhookConfig, cH as WebhookEvent, W as Where, cI as WhereOperators, cJ as anyone, cK as consoleEmail, cL as consoleLogger, cM as createEasyCMS, cN as defineConfig, cO as defineFieldType, cP as definePlugin, cQ as diskStorage, cR as hasRows, cS as isAdmin, cT as isHasMany, cU as isSignedIn, cV as isStaff, cW as isSystemAdmin, cX as jsonLogger, cY as memorySearch, cZ as mimeAllowedBy, c_ as rowFields, c$ as silentLogger, d0 as uniqueWithinOf } from './config-BLNPAco2.js';
3
- export { A as ADMIN_API_VERSION, a as AdminCollection, b as AdminComponentRef, c as AdminElementProps, d as AdminField, e as AdminGlobal, f as AdminLayoutNode, g as AdminNavGroup, h as AdminNavItem, i as AdminNavNode, j as AdminPageRef, k as AdminPageRoute, l as AdminSchema, m as AdminWidgetRef, S as SetFieldDetail, w as warnDeprecated } from './plugin-B7pTgG5F.js';
4
- export { A as AdminBackup, a as AdminBackups, b as ApiHandlerOptions, B as BackupState, L as LoadConfigOptions, R as RestHandler, c as RestHandlerOptions, d as createApiHandler, e as createRestHandler, l as loadConfig, r as resolveConfig, s as sharedEasyCMS, f as slugify } from './handler-d7cT0k4l.js';
1
+ import { P as PaginatedDocs, I as ID, h as EmailSetting, i as WebhookPayload } from './config-CmK2kPvg.js';
2
+ export { A as ADAPTER_API_VERSION, j as ADMIN_ICONS, k as Access, l as AccessArgs, m as AccessOptions, n as AdminBrand, o as AdminCommand, p as AdminComponent, q as AdminConfig, r as AdminFieldArgs, s as AdminIcon, t as AdminLocale, u as AdminPage, v as AdminRole, w as AdminRoleChange, x as AdminRoleField, y as AdminRoleTarget, z as AdminRoleView, B as AdminRoles, D as AdminSso, H as AdminSwitcher, J as AdminViewAccess, K as AfterChangeHook, M as AfterDeleteHook, N as AfterReadHook, O as ApiKeyContext, Q as ApiKeyGlobalOperation, S as ApiKeyOperation, T as ApiKeyPermissions, V as ArrayField, X as AuditChange, Y as AuditConfig, Z as AuditEntry, _ as AuditLog, $ as AuditPage, a0 as AuditVerification, a1 as Auth, a2 as AuthConfig, a3 as AuthProvider, a4 as AuthProviderProfile, a5 as AuthProviderRequest, a6 as AuthUser, a7 as BackupsConfig, a8 as BeforeChangeHook, a9 as BeforeDeleteHook, aa as BeforeValidateHook, ab as Block, ac as BlocksField, ad as BooleanField, ae as BuiltinApiKeysCollection, af as BuiltinMediaCollection, ag as BuiltinMediaFoldersCollection, ah as BuiltinUsersCollection, ai as BundleHints, aj as CliCommand, ak as CollectionAccess, al as CollectionAdmin, am as CollectionCalendarAdmin, an as CollectionConfig, b as CollectionDocument, ao as CollectionHooks, ap as CollectionListAdmin, aq as CollectionSearch, a as CollectionSlug, C as Config, ar as ConfigError, as as ConfigIssue, at as ContainerAdmin, g as CreateEasyCMSOptions, au as CreateInput, av as CreateMigrationResult, c as CursorDocs, aw as CustomField, ax as CustomFieldTypes, ay as DashboardWidget, az as Database, aA as DatabaseAdapter, aB as DatabaseInitArgs, aC as DatabaseTransfer, aD as DateField, aE as DepthOptions, aF as DirectUpload, aG as DiskStorageOptions, aH as DocumentOf, E as EasyCMS, aI as EasyCMSError, aJ as EmailAdapter, aK as EmailField, aL as EmailMessage, aM as Endpoint, aN as EndpointRequest, aO as ErrorCode, aP as FIELD_TYPES, F as Field, aQ as FieldAccess, aR as FieldAccessFn, aS as FieldAdmin, e as FieldError, aT as FieldRule, aU as FieldType, aV as FieldTypeBase, aW as FieldTypeDefinition, aX as FieldTypeValidateContext, aY as FieldValidate, aZ as FieldValidateContext, a_ as FieldValue, a$ as FieldsInput, b0 as FieldsValue, f as FilterOptions, b1 as FilterOptionsArgs, b2 as FindAfterArgs, b3 as FindArgs, b4 as FindOptions, b5 as FolderLevel, b6 as FolderPermissions, b7 as ForbiddenError, b8 as GlobalAccess, b9 as GlobalConfig, d as GlobalDocument, ba as GlobalHooks, bb as GlobalInput, G as GlobalSlug, bc as GroupField, bd as ImageSize, be as IncrementOptions, bf as InferCollection, bg as InferGlobal, bh as JobConfig, bi as JsonField, bj as KeysetPage, bk as Label, bl as LayoutNode, bm as LivePreview, bn as LocaleOf, L as LocalizationConfig, bo as LogDetails, bp as Logger, bq as LoginArgs, br as LogsConfig, bs as MediaDocument, bt as MediaSize, bu as MembersConfig, bv as MembersSignup, bw as MigrationInfo, bx as NavGroup, by as NotFoundError, bz as NumberField, bA as OnRequest, bB as OnRequestArgs, bC as Operation, bD as OutboxRow, bE as PLUGIN_API_VERSION, bF as PasswordEmail, bG as PasswordEmailArgs, bH as PasswordEmailFn, bI as PasswordLinkOptions, bJ as PayloadTooLargeError, bK as Plugin, bL as PluginInfo, bM as PluginTypes, bN as PreviewTarget, bO as PreviewURL, bP as QueryError, bQ as ROLE_OPERATIONS, bR as RawDocument, bS as ReadOptions, bT as RelationshipField, bU as RequestContext, R as ResolvedConfig, bV as RichTextDocument, bW as RichTextField, bX as Role, bY as RoleOperation, bZ as RolePermissions, b_ as Roles, b$ as RoutesConfig, c0 as ScheduledPublish, c1 as SchemaError, c2 as SchemaMode, c3 as SearchAdapter, c4 as SearchEntry, c5 as SearchHits, c6 as SearchOptions, c7 as SearchQuery, c8 as SearchResults, c9 as SearchSetting, ca as SelectField, cb as SelectOption, cc as Session, cd as SidebarPanel, ce as SignupArgs, cf as SignupResult, cg as SingleSignOn, ch as SlugField, ci as SlugOf, cj as SsoOutcome, ck as SsoProviderRef, cl as StorageAdapter, cm as StoredFile, cn as TRIGRAM_LIKE_MIN, co as TelemetryConfig, cp as TextField, cq as TextareaField, cr as TooManyRequestsError, cs as TypedPlugin, ct as UiField, cu as UnauthorizedError, U as UncountedDocs, cv as UpdateInput, cw as UpdateOptions, cx as UploadConfig, cy as UploadField, cz as UploadFromURLConfig, cA as UserIdentity, cB as ValidationError, cC as Version, cD as VersionSummary, cE as VersionsConfig, cF as WEBHOOK_EVENTS, cG as WebhookConfig, cH as WebhookEvent, W as Where, cI as WhereOperators, cJ as anyone, cK as consoleEmail, cL as consoleLogger, cM as createEasyCMS, cN as defineConfig, cO as defineFieldType, cP as definePlugin, cQ as diskStorage, cR as hasRows, cS as isAdmin, cT as isHasMany, cU as isPolymorphic, cV as isSignedIn, cW as isStaff, cX as isSystemAdmin, cY as jsonLogger, cZ as memorySearch, c_ as mimeAllowedBy, c$ as polymorphicValue, d0 as relationTargets, d1 as rowFields, d2 as silentLogger, d3 as uniqueWithinOf } from './config-CmK2kPvg.js';
3
+ export { A as ADMIN_API_VERSION, a as AdminCollection, b as AdminComponentRef, c as AdminElementProps, d as AdminField, e as AdminGlobal, f as AdminLayoutNode, g as AdminNavGroup, h as AdminNavItem, i as AdminNavNode, j as AdminPageRef, k as AdminPageRoute, l as AdminSchema, m as AdminWidgetRef, S as SetFieldDetail, w as warnDeprecated } from './plugin-DiOWfqBa.js';
4
+ export { A as AdminBackup, a as AdminBackups, b as ApiHandlerOptions, B as BackupState, L as LoadConfigOptions, R as RestHandler, c as RestHandlerOptions, d as createApiHandler, e as createRestHandler, l as loadConfig, r as resolveConfig, s as sharedEasyCMS, f as slugify } from './handler-h6UUfhGg.js';
5
5
  export { FieldCondition, matchesCondition } from './conditions.js';
6
6
 
7
7
  type DeliveryKind = 'webhook' | 'email';
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ import {
28
28
  silentLogger,
29
29
  slugify,
30
30
  verifyWebhook
31
- } from "./chunk-QRHRDJN5.js";
31
+ } from "./chunk-CTOLHSXG.js";
32
32
  import {
33
33
  matchesCondition
34
34
  } from "./chunk-U266LV4M.js";
@@ -53,7 +53,7 @@ import {
53
53
  defineFieldType,
54
54
  definePlugin,
55
55
  warnDeprecated
56
- } from "./chunk-SYUQX2G6.js";
56
+ } from "./chunk-NASM44FJ.js";
57
57
  export {
58
58
  ADAPTER_API_VERSION,
59
59
  ADMIN_API_VERSION,
@@ -1,6 +1,6 @@
1
1
  import { Config, Database, EasyCMS, NavGroup, CollectionConfig, ID, RawDocument, Field, ResolvedConfig, ConfigIssue } from './index.js';
2
- export { d1 as API_KEYS, d2 as API_KEY_GLOBAL_OPERATIONS, d3 as API_KEY_OPERATIONS, d4 as DEFAULT_MAX_VERSIONS, d5 as DEFAULT_PASSWORD_EMAILS, d6 as FIELD_TYPE_BASES, d7 as FOLDER_LEVELS, d8 as MediaFolders, d9 as SSO_COOKIE, da as Secrets, cn as TRIGRAM_LIKE_MIN, db as codeOfStatus, cR as hasRows, cT as isHasMany, dc as isJsonLogger, dd as keyAllows, de as logFormat, cZ as mimeAllowedBy, c_ as rowFields, df as secretsOf, d0 as uniqueWithinOf } from './config-BLNPAco2.js';
3
- export { C as CONFIG_FILE_NAMES, g as CSRF_COOKIE, h as CSRF_HEADER, D as DEFAULT_ADMIN_PATH, i as DEFAULT_API_PATH, j as DEFAULT_MAX_FILE_SIZE, k as DEFAULT_TOKEN_EXPIRATION, m as applyDefaults, n as applyPlugins, o as createRootEndpointHandler, p as decryptBackup, q as fillMissing, t as findConfigFile, u as forwardedClientIp, v as generateSlugs, w as importConfig, x as isEmail, y as mergeForUpdate, z as parseId, E as platformClientIp, F as readCookie, G as validateFields, H as writeBackupFile } from './handler-d7cT0k4l.js';
2
+ export { d4 as API_KEYS, d5 as API_KEY_GLOBAL_OPERATIONS, d6 as API_KEY_OPERATIONS, d7 as DEFAULT_MAX_VERSIONS, d8 as DEFAULT_PASSWORD_EMAILS, d9 as FIELD_TYPE_BASES, da as FOLDER_LEVELS, db as MediaFolders, dc as SSO_COOKIE, dd as Secrets, cn as TRIGRAM_LIKE_MIN, de as codeOfStatus, cR as hasRows, cT as isHasMany, df as isJsonLogger, cU as isPolymorphic, dg as keyAllows, dh as logFormat, c_ as mimeAllowedBy, c$ as polymorphicValue, d0 as relationTargets, d1 as rowFields, di as secretsOf, d3 as uniqueWithinOf } from './config-CmK2kPvg.js';
3
+ export { C as CONFIG_FILE_NAMES, g as CSRF_COOKIE, h as CSRF_HEADER, D as DEFAULT_ADMIN_PATH, i as DEFAULT_API_PATH, j as DEFAULT_MAX_FILE_SIZE, k as DEFAULT_TOKEN_EXPIRATION, m as applyDefaults, n as applyPlugins, o as createRootEndpointHandler, p as decryptBackup, q as fillMissing, t as findConfigFile, u as forwardedClientIp, v as generateSlugs, w as importConfig, x as isEmail, y as mergeForUpdate, z as parseId, E as platformClientIp, F as readCookie, G as validateFields, H as writeBackupFile } from './handler-h6UUfhGg.js';
4
4
  export { conditionIssues } from './conditions.js';
5
5
 
6
6
  /** The session cookie the REST API sets at login. */
package/dist/internal.js CHANGED
@@ -58,7 +58,7 @@ import {
58
58
  verifyPassword,
59
59
  verifyTurnstile,
60
60
  writeBackupFile
61
- } from "./chunk-QRHRDJN5.js";
61
+ } from "./chunk-CTOLHSXG.js";
62
62
  import {
63
63
  conditionIssues
64
64
  } from "./chunk-U266LV4M.js";
@@ -72,12 +72,15 @@ import {
72
72
  hasRows,
73
73
  imageDimensions,
74
74
  isHasMany,
75
+ isPolymorphic,
75
76
  mimeAllowed,
76
77
  mimeAllowedBy,
78
+ polymorphicValue,
79
+ relationTargets,
77
80
  rowFields,
78
81
  sniffMimeType,
79
82
  uniqueWithinOf
80
- } from "./chunk-SYUQX2G6.js";
83
+ } from "./chunk-NASM44FJ.js";
81
84
 
82
85
  // src/typegen.ts
83
86
  var pascal = (name) => name.split(/[^A-Za-z0-9]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
@@ -88,6 +91,7 @@ function singularize(word) {
88
91
  return word.replace(/s$/i, "");
89
92
  }
90
93
  var quote = (value) => JSON.stringify(value);
94
+ var idOr = (type) => type ? `ID | ${type}` : "ID";
91
95
  var key = (name) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : quote(name);
92
96
  function names(config) {
93
97
  const taken = /* @__PURE__ */ new Set(["ID", "RichTextDocument", "MediaSize", "Collections", "Globals"]);
@@ -137,8 +141,9 @@ function fieldType(field, n, indent) {
137
141
  return field.hasMany ? `(${one})[]` : one;
138
142
  }
139
143
  case "relationship": {
140
- const target = n.collections.get(field.to);
141
- const one = target ? `ID | ${target}` : "ID";
144
+ const one = typeof field.to === "string" ? idOr(n.collections.get(field.to)) : field.to.map(
145
+ (slug) => `{ relationTo: ${quote(slug)}; value: ${idOr(n.collections.get(slug))} }`
146
+ ).join(" | ");
142
147
  return field.hasMany ? `(${one})[]` : one;
143
148
  }
144
149
  case "group":
@@ -303,6 +308,7 @@ export {
303
308
  isEmail,
304
309
  isHasMany,
305
310
  isJsonLogger,
311
+ isPolymorphic,
306
312
  keyAllows,
307
313
  logFormat,
308
314
  mergeForUpdate,
@@ -310,9 +316,11 @@ export {
310
316
  mimeAllowedBy,
311
317
  parseId,
312
318
  platformClientIp,
319
+ polymorphicValue,
313
320
  populate,
314
321
  rateKeys,
315
322
  readCookie,
323
+ relationTargets,
316
324
  resolveAdminModule,
317
325
  rowFields,
318
326
  secretsOf,
@@ -1,4 +1,4 @@
1
- import { bk as Label, F as Field, I as ID, t as AdminLocale, H as AdminSwitcher, ck as SsoProviderRef } from './config-BLNPAco2.js';
1
+ import { bk as Label, F as Field, I as ID, t as AdminLocale, H as AdminSwitcher, ck as SsoProviderRef } from './config-CmK2kPvg.js';
2
2
  import { FieldCondition } from './conditions.js';
3
3
 
4
4
  /** A Web Component from an admin module, with its `props` (plain JSON). */
@@ -67,7 +67,8 @@ interface AdminField {
67
67
  value: string;
68
68
  }[];
69
69
  hasMany?: boolean;
70
- to?: string;
70
+ /** Several for a relationship to several collections (#327). */
71
+ to?: string | string[];
71
72
  /** An upload's allowed file types, e.g. `image/*`. */
72
73
  mimeTypes?: string[];
73
74
  /** An upload's media folder (`folder`): where its picker opens; `only`: nowhere else. */
package/dist/plugin.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { j as ADMIN_ICONS, p as AdminComponent, s as AdminIcon, a6 as AuthUser, aj as CliCommand, ak as CollectionAccess, an as CollectionConfig, C as Config, ar as ConfigError, ay as DashboardWidget, aI as EasyCMSError, aM as Endpoint, aN as EndpointRequest, aO as ErrorCode, F as Field, aQ as FieldAccess, e as FieldError, aV as FieldTypeBase, aW as FieldTypeDefinition, aX as FieldTypeValidateContext, b7 as ForbiddenError, b9 as GlobalConfig, I as ID, bh as JobConfig, bk as Label, bx as NavGroup, by as NotFoundError, bA as OnRequest, bB as OnRequestArgs, bE as PLUGIN_API_VERSION, bJ as PayloadTooLargeError, bK as Plugin, bL as PluginInfo, bM as PluginTypes, bP as QueryError, bU as RequestContext, cr as TooManyRequestsError, cs as TypedPlugin, cu as UnauthorizedError, cB as ValidationError, W as Where, cO as defineFieldType, cP as definePlugin } from './config-BLNPAco2.js';
2
- export { A as ADMIN_API_VERSION, c as AdminElementProps, k as AdminPageRoute, S as SetFieldDetail, w as warnDeprecated } from './plugin-B7pTgG5F.js';
1
+ export { j as ADMIN_ICONS, p as AdminComponent, s as AdminIcon, a6 as AuthUser, aj as CliCommand, ak as CollectionAccess, an as CollectionConfig, C as Config, ar as ConfigError, ay as DashboardWidget, aI as EasyCMSError, aM as Endpoint, aN as EndpointRequest, aO as ErrorCode, F as Field, aQ as FieldAccess, e as FieldError, aV as FieldTypeBase, aW as FieldTypeDefinition, aX as FieldTypeValidateContext, b7 as ForbiddenError, b9 as GlobalConfig, I as ID, bh as JobConfig, bk as Label, bx as NavGroup, by as NotFoundError, bA as OnRequest, bB as OnRequestArgs, bE as PLUGIN_API_VERSION, bJ as PayloadTooLargeError, bK as Plugin, bL as PluginInfo, bM as PluginTypes, bP as QueryError, bU as RequestContext, cr as TooManyRequestsError, cs as TypedPlugin, cu as UnauthorizedError, cB as ValidationError, W as Where, cO as defineFieldType, cP as definePlugin } from './config-CmK2kPvg.js';
2
+ export { A as ADMIN_API_VERSION, c as AdminElementProps, k as AdminPageRoute, S as SetFieldDetail, w as warnDeprecated } from './plugin-DiOWfqBa.js';
3
3
  import './conditions.js';
package/dist/plugin.js CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  defineFieldType,
17
17
  definePlugin,
18
18
  warnDeprecated
19
- } from "./chunk-SYUQX2G6.js";
19
+ } from "./chunk-NASM44FJ.js";
20
20
  export {
21
21
  ADMIN_API_VERSION,
22
22
  ADMIN_ICONS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easy-cms/core",
3
- "version": "1.28.0",
3
+ "version": "1.29.0",
4
4
  "description": "Embedded, code-first headless CMS for Nuxt and Next.js",
5
5
  "license": "MIT",
6
6
  "type": "module",