@easy-cms/core 1.33.0 → 1.34.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.
@@ -748,6 +748,16 @@ var AiProviderError = class extends Error {
748
748
  this.status = status;
749
749
  }
750
750
  };
751
+ var CORE_AI_FEATURES = [
752
+ {
753
+ id: "alt-text",
754
+ label: { en: "Alt text", th: "\u0E40\u0E02\u0E35\u0E22\u0E19 alt text" },
755
+ description: {
756
+ en: "Describes an image in the media library",
757
+ th: "\u0E1A\u0E23\u0E23\u0E22\u0E32\u0E22\u0E23\u0E39\u0E1B\u0E43\u0E19\u0E04\u0E25\u0E31\u0E07\u0E2A\u0E37\u0E48\u0E2D"
758
+ }
759
+ }
760
+ ];
751
761
  var SETTINGS = "ai";
752
762
  var DEFAULT_LIMIT = 100;
753
763
  var TIMEOUT = 6e4;
@@ -983,6 +993,55 @@ var Ai = class {
983
993
  ]);
984
994
  return { data: Buffer.from(file.body).toString("base64"), mediaType };
985
995
  }
996
+ /** For the admin's AI buttons: whether they work, and how many requests are left today. */
997
+ async status(user) {
998
+ const enabled = await Promise.all(
999
+ this.features.map(async (f) => await this.enabled(f.id) ? f.id : null)
1000
+ );
1001
+ return {
1002
+ connected: (await this.connections()).length > 0,
1003
+ features: enabled.filter((id) => id !== null),
1004
+ ...await this.remaining(user)
1005
+ };
1006
+ }
1007
+ /** The language to write in: the content locale being edited, else the default one. */
1008
+ language(locale) {
1009
+ const code = locale ?? this.config.localization?.defaultLocale ?? this.config.admin.locale ?? "en";
1010
+ try {
1011
+ return new Intl.DisplayNames(["en"], { type: "language" }).of(code) ?? code;
1012
+ } catch {
1013
+ return code;
1014
+ }
1015
+ }
1016
+ /**
1017
+ * Alt text for an image in the media library (`alt-text`), for the user to review before saving:
1018
+ * what it shows, in one sentence of at most 125 characters.
1019
+ */
1020
+ async altText(id, options) {
1021
+ const access = await this.cms.documentPermissions(
1022
+ MEDIA,
1023
+ String(id),
1024
+ options.user,
1025
+ options.context ?? {}
1026
+ );
1027
+ if (!access.update) throw new ForbiddenError("You may not change this file");
1028
+ const result = await this.generate(
1029
+ {
1030
+ feature: "alt-text",
1031
+ system: [
1032
+ "You write alt text for images on a website: one plain sentence saying what the image",
1033
+ 'shows, for people who cannot see it. Do not start with "Image of" or "Picture of".',
1034
+ `At most 125 characters. Write it in ${this.language(options.locale)}.`,
1035
+ "Answer with the alt text only, without quotes."
1036
+ ].join(" "),
1037
+ prompt: "Write the alt text for this image.",
1038
+ images: [{ media: id }],
1039
+ maxTokens: 200
1040
+ },
1041
+ { user: options.user, about: { collection: MEDIA, id } }
1042
+ );
1043
+ return { alt: shorten(result.text.trim().replace(/^["'“]+|["'”]+$/g, ""), 125) };
1044
+ }
986
1045
  // --- Admins ----------------------------------------------------------------------------------
987
1046
  /** Settings → Integrations, AI: the main connection, the features, the limit and this month. */
988
1047
  async overview(now = /* @__PURE__ */ new Date()) {
@@ -1154,6 +1213,12 @@ var Ai = class {
1154
1213
  }
1155
1214
  }
1156
1215
  };
1216
+ function shorten(text4, max) {
1217
+ if (text4.length <= max) return text4;
1218
+ const cut2 = text4.slice(0, max);
1219
+ const space = cut2.lastIndexOf(" ");
1220
+ return (space > max * 0.6 ? cut2.slice(0, space) : cut2).replace(/[\s,;:]+$/, "");
1221
+ }
1157
1222
  function stripFence(text4) {
1158
1223
  const trimmed = text4.trim();
1159
1224
  const match = /^```(?:json)?\s*\n([\s\S]*?)\n?```$/.exec(trimmed);
@@ -9178,7 +9243,7 @@ function validateAi(config, add) {
9178
9243
  const feature = raw ?? {};
9179
9244
  if (typeof feature.id !== "string" || !/^[a-z0-9][a-z0-9-]*$/.test(feature.id))
9180
9245
  add(`aiFeatures[${i}].id`, 'must be lowercase letters, digits and "-"', "e.g. id: 'alt-text'");
9181
- else if (seen.has(feature.id) || feature.id === "test")
9246
+ else if (seen.has(feature.id) || feature.id === "test" || feature.id === "alt-text")
9182
9247
  add(`aiFeatures[${i}].id`, `"${feature.id}" is taken`);
9183
9248
  else seen.add(feature.id);
9184
9249
  if (!isLabel(feature.label)) add(`aiFeatures[${i}].label`, "must be a string or { en, th }");
@@ -9303,7 +9368,7 @@ async function resolveConfig(input) {
9303
9368
  globals: config.globals ?? [],
9304
9369
  endpoints: config.endpoints ?? [],
9305
9370
  integrations: resolvedIntegrations(config),
9306
- aiFeatures: config.ai ? config.aiFeatures ?? [] : [],
9371
+ aiFeatures: config.ai ? [...CORE_AI_FEATURES, ...config.aiFeatures ?? []] : [],
9307
9372
  cliCommands: config.cliCommands ?? [],
9308
9373
  // Easy CMS's own events (#356), for webhooks and `cms.on`.
9309
9374
  events: [.../* @__PURE__ */ new Set([...config.events ?? [], ...SYSTEM_EVENTS])],
@@ -9422,7 +9487,7 @@ function cacheableResponse(request, body, status, headers, times, tags) {
9422
9487
  }
9423
9488
 
9424
9489
  // src/version.ts
9425
- var VERSION = true ? "1.33.0" : "0.0.0-dev";
9490
+ var VERSION = true ? "1.34.0" : "0.0.0-dev";
9426
9491
 
9427
9492
  // src/telemetry.ts
9428
9493
  var DB_CALLS = /* @__PURE__ */ new Set([
@@ -15646,6 +15711,28 @@ async function route(cms, ctx, method, path, options) {
15646
15711
  }
15647
15712
  throw methodNotAllowed(ctx, "PATCH, DELETE");
15648
15713
  }
15714
+ if (first === "admin" && second === "ai" && segments.length === 3) {
15715
+ if (!ctx.user) throw new UnauthorizedError();
15716
+ if (!cms.ai) throw new HttpError("Not found", 404);
15717
+ if (third === "status") {
15718
+ if (method !== "GET") throw methodNotAllowed(ctx, "GET");
15719
+ return { body: await cms.ai.status(ctx.user) };
15720
+ }
15721
+ if (third === "alt-text") {
15722
+ if (method !== "POST") throw methodNotAllowed(ctx, "POST");
15723
+ const body = await readJson(ctx.request);
15724
+ if (typeof body.media !== "string" && typeof body.media !== "number")
15725
+ throw new ValidationError("media", [{ field: "media", message: "is required" }]);
15726
+ return {
15727
+ body: await cms.ai.altText(body.media, {
15728
+ user: ctx.user,
15729
+ locale: typeof body.locale === "string" ? body.locale : null,
15730
+ context: ctx.context
15731
+ })
15732
+ };
15733
+ }
15734
+ throw new HttpError("Not found", 404);
15735
+ }
15649
15736
  if (first === "admin" && second === "ai" && segments.length === 2) {
15650
15737
  if (!ctx.user) throw new UnauthorizedError();
15651
15738
  if (!cms.ai) throw new HttpError("Not found", 404);
@@ -3092,6 +3092,16 @@ interface AdminAi {
3092
3092
  }[];
3093
3093
  };
3094
3094
  }
3095
+ /** What the admin needs to show AI buttons (`GET <api>/admin/ai/status`). */
3096
+ interface AiStatus {
3097
+ /** A provider is connected. */
3098
+ connected: boolean;
3099
+ /** Features that are on. */
3100
+ features: string[];
3101
+ /** Requests the user made today, and may make. */
3102
+ used: number;
3103
+ limit: number;
3104
+ }
3095
3105
  declare class Ai {
3096
3106
  private readonly cms;
3097
3107
  private readonly ai;
@@ -3135,6 +3145,21 @@ declare class Ai {
3135
3145
  private call;
3136
3146
  /** An image as base64: given, or read from a media document. */
3137
3147
  private image;
3148
+ /** For the admin's AI buttons: whether they work, and how many requests are left today. */
3149
+ status(user: AuthUser): Promise<AiStatus>;
3150
+ /** The language to write in: the content locale being edited, else the default one. */
3151
+ private language;
3152
+ /**
3153
+ * Alt text for an image in the media library (`alt-text`), for the user to review before saving:
3154
+ * what it shows, in one sentence of at most 125 characters.
3155
+ */
3156
+ altText(id: ID, options: {
3157
+ user: AuthUser;
3158
+ locale?: string | null;
3159
+ context?: Record<string, unknown>;
3160
+ }): Promise<{
3161
+ alt: string;
3162
+ }>;
3138
3163
  /** Settings → Integrations, AI: the main connection, the features, the limit and this month. */
3139
3164
  overview(now?: Date): Promise<AdminAi>;
3140
3165
  /** Tokens and requests of each connection this month, for the cards. */
@@ -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-BZ4fsHL4.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-3opRDa7L.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-BZ4fsHL4.js';
2
- export { A as ADAPTER_API_VERSION, j as ADMIN_ICONS, k as Access, l as AccessArgs, m as AccessOptions, n as AdminAi, o as AdminBrand, p as AdminCommand, q as AdminComponent, r as AdminConfig, s as AdminFieldArgs, t as AdminIcon, u as AdminLocale, v as AdminPage, w as AdminRole, x as AdminRoleChange, y as AdminRoleField, z as AdminRoleTarget, B as AdminRoleView, D as AdminRoles, H as AdminSso, J as AdminSwitcher, K as AdminViewAccess, M as AfterChangeHook, N as AfterDeleteHook, O as AfterReadHook, Q as Ai, S as AiConfig, T as AiFeatureConfig, V as AiImage, X as AiProvider, Y as AiProviderError, Z as AiProviderRequest, _ as AiProviderResult, $ as AiRequest, a0 as AiResult, a1 as ApiKeyContext, a2 as ApiKeyGlobalOperation, a3 as ApiKeyOperation, a4 as ApiKeyPermissions, a5 as ArrayField, a6 as AuditChange, a7 as AuditConfig, a8 as AuditEntry, a9 as AuditLog, aa as AuditPage, ab as AuditVerification, ac as Auth, ad as AuthConfig, ae as AuthProvider, af as AuthProviderProfile, ag as AuthProviderRequest, ah as AuthUser, ai as BackupsConfig, aj as BeforeChangeHook, ak as BeforeDeleteHook, al as BeforeValidateHook, am as Block, an as BlockSummaryArgs, ao as BlocksField, ap as BooleanField, aq as BuiltinApiKeysCollection, ar as BuiltinMediaCollection, as as BuiltinMediaFoldersCollection, at as BuiltinUsersCollection, au as BundleHints, av as CliCommand, aw as CollectionAccess, ax as CollectionAdmin, ay as CollectionCalendarAdmin, az as CollectionConfig, b as CollectionDocument, aA as CollectionHooks, aB as CollectionListAdmin, aC as CollectionSearch, a as CollectionSlug, aD as CollectionView, C as Config, aE as ConfigError, aF as ConfigIssue, aG as ContainerAdmin, g as CreateEasyCMSOptions, aH as CreateInput, aI as CreateMigrationResult, c as CursorDocs, aJ as CustomField, aK as CustomFieldTypes, aL as DashboardWidget, aM as Database, aN as DatabaseAdapter, aO as DatabaseInitArgs, aP as DatabaseTransfer, aQ as DateField, aR as DepthOptions, aS as DirectUpload, aT as DiskStorageOptions, aU as DocumentOf, E as EasyCMS, aV as EasyCMSError, aW as EmailAdapter, aX as EmailField, aY as EmailMessage, aZ as Endpoint, a_ as EndpointRequest, a$ as ErrorCode, b0 as EventListener, b1 as EventMessage, b2 as FIELD_TYPES, F as Field, b3 as FieldAccess, b4 as FieldAccessFn, b5 as FieldAdmin, e as FieldError, b6 as FieldRule, b7 as FieldType, b8 as FieldTypeBase, b9 as FieldTypeDefinition, ba as FieldTypeValidateContext, bb as FieldValidate, bc as FieldValidateContext, bd as FieldValue, be as FieldsInput, bf as FieldsValue, f as FilterOptions, bg as FilterOptionsArgs, bh as FindAfterArgs, bi as FindArgs, bj as FindOptions, bk as FolderLevel, bl as FolderPermissions, bm as ForbiddenError, bn as GlobalAccess, bo as GlobalConfig, d as GlobalDocument, bp as GlobalHooks, bq as GlobalInput, G as GlobalSlug, br as GroupField, bs as ImageSize, bt as IncrementOptions, bu as InferCollection, bv as InferGlobal, bw as IntegrationCategory, bx as IntegrationConfig, by as IntegrationConnection, bz as IntegrationField, bA as IntegrationLogo, bB as IntegrationOAuthResult, bC as IntegrationTestResult, bD as JobConfig, bE as JsonField, bF as KeysetPage, bG as Label, bH as LayoutNode, bI as LivePreview, bJ as LocaleOf, L as LocalizationConfig, bK as LogDetails, bL as Logger, bM as LoginArgs, bN as LogsConfig, bO as MediaDocument, bP as MediaSize, bQ as MembersConfig, bR as MembersSignup, bS as MigrationInfo, bT as NavGroup, bU as NotFoundError, bV as NumberField, bW as OnRequest, bX as OnRequestArgs, bY as Operation, bZ as OutboxRow, b_ as PLUGIN_API_VERSION, b$ as PasswordEmail, c0 as PasswordEmailArgs, c1 as PasswordEmailFn, c2 as PasswordLinkOptions, c3 as PayloadTooLargeError, c4 as Plugin, c5 as PluginInfo, c6 as PluginTypes, c7 as PreviewTarget, c8 as PreviewURL, c9 as QueryError, ca as ROLE_OPERATIONS, cb as RawDocument, cc as ReadOptions, cd as RelationshipField, ce as RequestContext, R as ResolvedConfig, cf as RichTextBlock, cg as RichTextBlocks, ch as RichTextDocument, ci as RichTextField, cj as Role, ck as RoleOperation, cl as RolePermissions, cm as Roles, cn as RoutesConfig, co as ScheduledPublish, cp as SchemaError, cq as SchemaMode, cr as SearchAdapter, cs as SearchEntry, ct as SearchHits, cu as SearchOptions, cv as SearchQuery, cw as SearchResults, cx as SearchSetting, cy as SelectField, cz as SelectOption, cA as Session, cB as SidebarPanel, cC as SignupArgs, cD as SignupResult, cE as SingleSignOn, cF as SlugField, cG as SlugOf, cH as SsoOutcome, cI as SsoProviderRef, cJ as StorageAdapter, cK as StoredFile, cL as TRIGRAM_LIKE_MIN, cM as TelemetryConfig, cN as TextField, cO as TextareaField, cP as TooManyRequestsError, cQ as TypedPlugin, cR as UiField, cS as UnauthorizedError, U as UncountedDocs, cT as UpdateInput, cU as UpdateOptions, cV as UploadConfig, cW as UploadField, cX as UploadFromURLConfig, cY as UserIdentity, cZ as ValidationError, c_ as Version, c$ as VersionSummary, d0 as VersionsConfig, d1 as WEBHOOK_EVENTS, d2 as WebhookConfig, d3 as WebhookEvent, W as Where, d4 as WhereOperators, d5 as anyone, d6 as consoleEmail, d7 as consoleLogger, d8 as createEasyCMS, d9 as defineConfig, da as defineFieldType, db as definePlugin, dc as diskStorage, dd as hasRows, de as isAdmin, df as isHasMany, dg as isPolymorphic, dh as isSignedIn, di as isStaff, dj as isSystemAdmin, dk as jsonLogger, dl as memorySearch, dm as mimeAllowedBy, dn as polymorphicValue, dp as relationTargets, dq as rowFields, dr as silentLogger, ds as uniqueWithinOf } from './config-BZ4fsHL4.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-GcNICm6a.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-CMTJ99sx.js';
1
+ import { P as PaginatedDocs, I as ID, h as EmailSetting, i as WebhookPayload } from './config-3opRDa7L.js';
2
+ export { A as ADAPTER_API_VERSION, j as ADMIN_ICONS, k as Access, l as AccessArgs, m as AccessOptions, n as AdminAi, o as AdminBrand, p as AdminCommand, q as AdminComponent, r as AdminConfig, s as AdminFieldArgs, t as AdminIcon, u as AdminLocale, v as AdminPage, w as AdminRole, x as AdminRoleChange, y as AdminRoleField, z as AdminRoleTarget, B as AdminRoleView, D as AdminRoles, H as AdminSso, J as AdminSwitcher, K as AdminViewAccess, M as AfterChangeHook, N as AfterDeleteHook, O as AfterReadHook, Q as Ai, S as AiConfig, T as AiFeatureConfig, V as AiImage, X as AiProvider, Y as AiProviderError, Z as AiProviderRequest, _ as AiProviderResult, $ as AiRequest, a0 as AiResult, a1 as ApiKeyContext, a2 as ApiKeyGlobalOperation, a3 as ApiKeyOperation, a4 as ApiKeyPermissions, a5 as ArrayField, a6 as AuditChange, a7 as AuditConfig, a8 as AuditEntry, a9 as AuditLog, aa as AuditPage, ab as AuditVerification, ac as Auth, ad as AuthConfig, ae as AuthProvider, af as AuthProviderProfile, ag as AuthProviderRequest, ah as AuthUser, ai as BackupsConfig, aj as BeforeChangeHook, ak as BeforeDeleteHook, al as BeforeValidateHook, am as Block, an as BlockSummaryArgs, ao as BlocksField, ap as BooleanField, aq as BuiltinApiKeysCollection, ar as BuiltinMediaCollection, as as BuiltinMediaFoldersCollection, at as BuiltinUsersCollection, au as BundleHints, av as CliCommand, aw as CollectionAccess, ax as CollectionAdmin, ay as CollectionCalendarAdmin, az as CollectionConfig, b as CollectionDocument, aA as CollectionHooks, aB as CollectionListAdmin, aC as CollectionSearch, a as CollectionSlug, aD as CollectionView, C as Config, aE as ConfigError, aF as ConfigIssue, aG as ContainerAdmin, g as CreateEasyCMSOptions, aH as CreateInput, aI as CreateMigrationResult, c as CursorDocs, aJ as CustomField, aK as CustomFieldTypes, aL as DashboardWidget, aM as Database, aN as DatabaseAdapter, aO as DatabaseInitArgs, aP as DatabaseTransfer, aQ as DateField, aR as DepthOptions, aS as DirectUpload, aT as DiskStorageOptions, aU as DocumentOf, E as EasyCMS, aV as EasyCMSError, aW as EmailAdapter, aX as EmailField, aY as EmailMessage, aZ as Endpoint, a_ as EndpointRequest, a$ as ErrorCode, b0 as EventListener, b1 as EventMessage, b2 as FIELD_TYPES, F as Field, b3 as FieldAccess, b4 as FieldAccessFn, b5 as FieldAdmin, e as FieldError, b6 as FieldRule, b7 as FieldType, b8 as FieldTypeBase, b9 as FieldTypeDefinition, ba as FieldTypeValidateContext, bb as FieldValidate, bc as FieldValidateContext, bd as FieldValue, be as FieldsInput, bf as FieldsValue, f as FilterOptions, bg as FilterOptionsArgs, bh as FindAfterArgs, bi as FindArgs, bj as FindOptions, bk as FolderLevel, bl as FolderPermissions, bm as ForbiddenError, bn as GlobalAccess, bo as GlobalConfig, d as GlobalDocument, bp as GlobalHooks, bq as GlobalInput, G as GlobalSlug, br as GroupField, bs as ImageSize, bt as IncrementOptions, bu as InferCollection, bv as InferGlobal, bw as IntegrationCategory, bx as IntegrationConfig, by as IntegrationConnection, bz as IntegrationField, bA as IntegrationLogo, bB as IntegrationOAuthResult, bC as IntegrationTestResult, bD as JobConfig, bE as JsonField, bF as KeysetPage, bG as Label, bH as LayoutNode, bI as LivePreview, bJ as LocaleOf, L as LocalizationConfig, bK as LogDetails, bL as Logger, bM as LoginArgs, bN as LogsConfig, bO as MediaDocument, bP as MediaSize, bQ as MembersConfig, bR as MembersSignup, bS as MigrationInfo, bT as NavGroup, bU as NotFoundError, bV as NumberField, bW as OnRequest, bX as OnRequestArgs, bY as Operation, bZ as OutboxRow, b_ as PLUGIN_API_VERSION, b$ as PasswordEmail, c0 as PasswordEmailArgs, c1 as PasswordEmailFn, c2 as PasswordLinkOptions, c3 as PayloadTooLargeError, c4 as Plugin, c5 as PluginInfo, c6 as PluginTypes, c7 as PreviewTarget, c8 as PreviewURL, c9 as QueryError, ca as ROLE_OPERATIONS, cb as RawDocument, cc as ReadOptions, cd as RelationshipField, ce as RequestContext, R as ResolvedConfig, cf as RichTextBlock, cg as RichTextBlocks, ch as RichTextDocument, ci as RichTextField, cj as Role, ck as RoleOperation, cl as RolePermissions, cm as Roles, cn as RoutesConfig, co as ScheduledPublish, cp as SchemaError, cq as SchemaMode, cr as SearchAdapter, cs as SearchEntry, ct as SearchHits, cu as SearchOptions, cv as SearchQuery, cw as SearchResults, cx as SearchSetting, cy as SelectField, cz as SelectOption, cA as Session, cB as SidebarPanel, cC as SignupArgs, cD as SignupResult, cE as SingleSignOn, cF as SlugField, cG as SlugOf, cH as SsoOutcome, cI as SsoProviderRef, cJ as StorageAdapter, cK as StoredFile, cL as TRIGRAM_LIKE_MIN, cM as TelemetryConfig, cN as TextField, cO as TextareaField, cP as TooManyRequestsError, cQ as TypedPlugin, cR as UiField, cS as UnauthorizedError, U as UncountedDocs, cT as UpdateInput, cU as UpdateOptions, cV as UploadConfig, cW as UploadField, cX as UploadFromURLConfig, cY as UserIdentity, cZ as ValidationError, c_ as Version, c$ as VersionSummary, d0 as VersionsConfig, d1 as WEBHOOK_EVENTS, d2 as WebhookConfig, d3 as WebhookEvent, W as Where, d4 as WhereOperators, d5 as anyone, d6 as consoleEmail, d7 as consoleLogger, d8 as createEasyCMS, d9 as defineConfig, da as defineFieldType, db as definePlugin, dc as diskStorage, dd as hasRows, de as isAdmin, df as isHasMany, dg as isPolymorphic, dh as isSignedIn, di as isStaff, dj as isSystemAdmin, dk as jsonLogger, dl as memorySearch, dm as mimeAllowedBy, dn as polymorphicValue, dp as relationTargets, dq as rowFields, dr as silentLogger, ds as uniqueWithinOf } from './config-3opRDa7L.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-D7ra0pjj.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-Ce-WEeAh.js';
5
5
  export { FieldCondition, matchesCondition } from './conditions.js';
6
6
 
7
7
  type DeliveryKind = 'webhook' | 'email';
package/dist/index.js CHANGED
@@ -29,7 +29,7 @@ import {
29
29
  silentLogger,
30
30
  slugify,
31
31
  verifyWebhook
32
- } from "./chunk-KUEGUD2X.js";
32
+ } from "./chunk-OBVILNIV.js";
33
33
  import {
34
34
  matchesCondition
35
35
  } from "./chunk-U266LV4M.js";
@@ -1,6 +1,6 @@
1
1
  import { Config, Database, EasyCMS, NavGroup, CollectionConfig, ID, RawDocument, Field, ResolvedConfig, ConfigIssue } from './index.js';
2
- export { dt as API_KEYS, du as API_KEY_GLOBAL_OPERATIONS, dv as API_KEY_OPERATIONS, dw as DEFAULT_MAX_VERSIONS, dx as DEFAULT_PASSWORD_EMAILS, dy as FIELD_TYPE_BASES, dz as FOLDER_LEVELS, dA as MediaFolders, dB as SSO_COOKIE, dC as Secrets, cL as TRIGRAM_LIKE_MIN, dD as codeOfStatus, dd as hasRows, df as isHasMany, dE as isJsonLogger, dg as isPolymorphic, dF as keyAllows, dG as logFormat, dm as mimeAllowedBy, dn as polymorphicValue, dp as relationTargets, dq as rowFields, dH as secretsOf, ds as uniqueWithinOf } from './config-BZ4fsHL4.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-CMTJ99sx.js';
2
+ export { dt as API_KEYS, du as API_KEY_GLOBAL_OPERATIONS, dv as API_KEY_OPERATIONS, dw as DEFAULT_MAX_VERSIONS, dx as DEFAULT_PASSWORD_EMAILS, dy as FIELD_TYPE_BASES, dz as FOLDER_LEVELS, dA as MediaFolders, dB as SSO_COOKIE, dC as Secrets, cL as TRIGRAM_LIKE_MIN, dD as codeOfStatus, dd as hasRows, df as isHasMany, dE as isJsonLogger, dg as isPolymorphic, dF as keyAllows, dG as logFormat, dm as mimeAllowedBy, dn as polymorphicValue, dp as relationTargets, dq as rowFields, dH as secretsOf, ds as uniqueWithinOf } from './config-3opRDa7L.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-Ce-WEeAh.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-KUEGUD2X.js";
61
+ } from "./chunk-OBVILNIV.js";
62
62
  import {
63
63
  conditionIssues
64
64
  } from "./chunk-U266LV4M.js";
@@ -1,4 +1,4 @@
1
- import { bG as Label, F as Field, I as ID, aD as CollectionView, u as AdminLocale, J as AdminSwitcher, cI as SsoProviderRef } from './config-BZ4fsHL4.js';
1
+ import { bG as Label, F as Field, I as ID, aD as CollectionView, u as AdminLocale, J as AdminSwitcher, cI as SsoProviderRef } from './config-3opRDa7L.js';
2
2
  import { FieldCondition } from './conditions.js';
3
3
 
4
4
  /** A Web Component from an admin module, with its `props` (plain JSON). */
package/dist/plugin.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { j as ADMIN_ICONS, q as AdminComponent, t as AdminIcon, ah as AuthUser, av as CliCommand, aw as CollectionAccess, az as CollectionConfig, C as Config, aE as ConfigError, aL as DashboardWidget, aV as EasyCMSError, aZ as Endpoint, a_ as EndpointRequest, a$ as ErrorCode, F as Field, b3 as FieldAccess, e as FieldError, b8 as FieldTypeBase, b9 as FieldTypeDefinition, ba as FieldTypeValidateContext, bm as ForbiddenError, bo as GlobalConfig, I as ID, bD as JobConfig, bG as Label, bT as NavGroup, bU as NotFoundError, bW as OnRequest, bX as OnRequestArgs, b_ as PLUGIN_API_VERSION, c3 as PayloadTooLargeError, c4 as Plugin, c5 as PluginInfo, c6 as PluginTypes, c9 as QueryError, ce as RequestContext, cP as TooManyRequestsError, cQ as TypedPlugin, cS as UnauthorizedError, cZ as ValidationError, W as Where, da as defineFieldType, db as definePlugin } from './config-BZ4fsHL4.js';
2
- export { A as ADMIN_API_VERSION, c as AdminElementProps, k as AdminPageRoute, S as SetFieldDetail, w as warnDeprecated } from './plugin-GcNICm6a.js';
1
+ export { j as ADMIN_ICONS, q as AdminComponent, t as AdminIcon, ah as AuthUser, av as CliCommand, aw as CollectionAccess, az as CollectionConfig, C as Config, aE as ConfigError, aL as DashboardWidget, aV as EasyCMSError, aZ as Endpoint, a_ as EndpointRequest, a$ as ErrorCode, F as Field, b3 as FieldAccess, e as FieldError, b8 as FieldTypeBase, b9 as FieldTypeDefinition, ba as FieldTypeValidateContext, bm as ForbiddenError, bo as GlobalConfig, I as ID, bD as JobConfig, bG as Label, bT as NavGroup, bU as NotFoundError, bW as OnRequest, bX as OnRequestArgs, b_ as PLUGIN_API_VERSION, c3 as PayloadTooLargeError, c4 as Plugin, c5 as PluginInfo, c6 as PluginTypes, c9 as QueryError, ce as RequestContext, cP as TooManyRequestsError, cQ as TypedPlugin, cS as UnauthorizedError, cZ as ValidationError, W as Where, da as defineFieldType, db as definePlugin } from './config-3opRDa7L.js';
2
+ export { A as ADMIN_API_VERSION, c as AdminElementProps, k as AdminPageRoute, S as SetFieldDetail, w as warnDeprecated } from './plugin-D7ra0pjj.js';
3
3
  import './conditions.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easy-cms/core",
3
- "version": "1.33.0",
3
+ "version": "1.34.0",
4
4
  "description": "Embedded, code-first headless CMS for Nuxt and Next.js",
5
5
  "license": "MIT",
6
6
  "type": "module",