@thebes/cadmus 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- import { $ as ValidationSeverity, A as CollectionConfig, B as RichTextFieldConfig, C as ArrayFieldConfig, D as CmsConfig, Dt as StringBlockRenderer, E as CheckboxFieldConfig, Et as PortableBlockLike, F as JsonFieldConfig, G as flattenFields, H as TextFieldConfig, I as JsonValue, J as CustomValidatorResult, K as nestDoc, L as NumberFieldConfig, M as DateFieldConfig, N as FieldConfig, O as CollectionAccess, Ot as createBlockRegistry, P as GroupFieldConfig, Q as ValidationFieldContext, R as RelationshipDepth, S as AccessFn, T as CadmeaPlugin, Tt as BlockRegistry, U as UploadFieldConfig, V as SelectFieldConfig, W as flattenDoc, X as ValidateDocumentOptions, Y as Rule, Z as ValidationBuilder, _ as collectionSearchTableSQL, a as BuildStudioStructureOptions, at as LocalApi, b as extractSearchText, c as StudioStructureItem, ct as createLocalApi, d as CollectionMeta, et as assertValid, f as getCollectionsMeta, g as collectionSearchTableName, h as cmsConfigToSchema, i as deliverWebhookMessage, it as CmsRegistry, j as CollectionHooks, k as CollectionAdminConfig, kt as renderBlocksToString, l as buildStudioStructure, lt as createVersionedLocalApi, m as defineCollection, n as WebhookMessage, nt as rule, o as DEFAULT_STUDIO_GROUP, ot as VersionedLocalApi, p as defineCmsConfig, q as CustomValidator, r as createWebhookHook, rt as validateDocument, s as StudioStructureGroup, st as can, t as WebhookConfig, tt as defineField, u as generateSchemaSource, ut as getRegisteredApi, v as collectionToTable, w as BaseFieldConfig, x as relationshipJoinTables, y as collectionVersionsTable, z as RelationshipFieldConfig } from "../index-BRZrCTsN.cjs";
2
- export { AccessFn, ArrayFieldConfig, BaseFieldConfig, BlockRegistry, BuildStudioStructureOptions, CadmeaPlugin, CheckboxFieldConfig, CmsConfig, CmsRegistry, CollectionAccess, CollectionAdminConfig, CollectionConfig, CollectionHooks, CollectionMeta, CustomValidator, CustomValidatorResult, DEFAULT_STUDIO_GROUP, DateFieldConfig, FieldConfig, GroupFieldConfig, JsonFieldConfig, JsonValue, LocalApi, NumberFieldConfig, PortableBlockLike, RelationshipDepth, RelationshipFieldConfig, RichTextFieldConfig, Rule, SelectFieldConfig, StringBlockRenderer, StudioStructureGroup, StudioStructureItem, TextFieldConfig, UploadFieldConfig, ValidateDocumentOptions, ValidationBuilder, ValidationFieldContext, ValidationSeverity, VersionedLocalApi, WebhookConfig, WebhookMessage, assertValid, buildStudioStructure, can, cmsConfigToSchema, collectionSearchTableName, collectionSearchTableSQL, collectionToTable, collectionVersionsTable, createBlockRegistry, createLocalApi, createVersionedLocalApi, createWebhookHook, defineCmsConfig, defineCollection, defineField, deliverWebhookMessage, extractSearchText, flattenDoc, flattenFields, generateSchemaSource, getCollectionsMeta, getRegisteredApi, nestDoc, relationshipJoinTables, renderBlocksToString, rule, validateDocument };
1
+ import { $ as RelationshipDepth, A as cmsConfigToSchema, At as PatchOp, B as CadmeaPlugin, C as RunMigrationOptions, Ct as createLocalApi, D as getCollectionsMeta, Dt as FieldChange, E as CollectionMeta, Et as DiffOptions, F as extractSearchText, G as CollectionConfig, H as CmsConfig, I as relationshipJoinTables, J as FieldConfig, Jt as BlockRegistry, K as CollectionHooks, L as AccessFn, M as collectionSearchTableSQL, Mt as computePatch, N as collectionToTable, Nt as diffDocuments, O as defineCmsConfig, Ot as FieldChangeKind, P as collectionVersionsTable, Q as NumberFieldConfig, Qt as renderBlocksToString, R as ArrayFieldConfig, S as MigrationResult, St as can, T as runMigration, Tt as getRegisteredApi, U as CollectionAccess, V as CheckboxFieldConfig, W as CollectionAdminConfig, X as JsonFieldConfig, Xt as StringBlockRenderer, Y as GroupFieldConfig, Yt as PortableBlockLike, Z as JsonValue, Zt as createBlockRegistry, _ as StudioStructureItem, _t as rule, a as EDIT_ATTR, at as flattenDoc, b as Migration, bt as LocalApi, c as VisualEditingMessage, ct as CustomValidator, d as editAttr, dt as ValidateDocumentOptions, et as RelationshipFieldConfig, f as encodeEditRef, ft as ValidationBuilder, g as StudioStructureGroup, gt as defineField, h as DEFAULT_STUDIO_GROUP, ht as assertValid, i as deliverWebhookMessage, it as UploadFieldConfig, j as collectionSearchTableName, jt as applyPatch, k as defineCollection, kt as Patch, l as VisualEditingOptions, lt as CustomValidatorResult, m as BuildStudioStructureOptions, mt as ValidationSeverity, n as WebhookMessage, nt as SelectFieldConfig, o as EditRef, ot as flattenFields, p as mountVisualEditing, pt as ValidationFieldContext, q as DateFieldConfig, r as createWebhookHook, rt as TextFieldConfig, s as VISUAL_EDIT_MESSAGE, st as nestDoc, t as WebhookConfig, tt as RichTextFieldConfig, u as decodeEditRef, ut as Rule, v as buildStudioStructure, vt as validateDocument, w as defineMigration, wt as createVersionedLocalApi, x as MigrationChange, xt as VersionedLocalApi, y as generateSchemaSource, yt as CmsRegistry, z as BaseFieldConfig } from "../index-sB3YOadC.cjs";
2
+ export { AccessFn, ArrayFieldConfig, BaseFieldConfig, BlockRegistry, BuildStudioStructureOptions, CadmeaPlugin, CheckboxFieldConfig, CmsConfig, CmsRegistry, CollectionAccess, CollectionAdminConfig, CollectionConfig, CollectionHooks, CollectionMeta, CustomValidator, CustomValidatorResult, DEFAULT_STUDIO_GROUP, DateFieldConfig, DiffOptions, EDIT_ATTR, EditRef, FieldChange, FieldChangeKind, FieldConfig, GroupFieldConfig, JsonFieldConfig, JsonValue, LocalApi, Migration, MigrationChange, MigrationResult, NumberFieldConfig, Patch, PatchOp, PortableBlockLike, RelationshipDepth, RelationshipFieldConfig, RichTextFieldConfig, Rule, RunMigrationOptions, SelectFieldConfig, StringBlockRenderer, StudioStructureGroup, StudioStructureItem, TextFieldConfig, UploadFieldConfig, VISUAL_EDIT_MESSAGE, ValidateDocumentOptions, ValidationBuilder, ValidationFieldContext, ValidationSeverity, VersionedLocalApi, VisualEditingMessage, VisualEditingOptions, WebhookConfig, WebhookMessage, applyPatch, assertValid, buildStudioStructure, can, cmsConfigToSchema, collectionSearchTableName, collectionSearchTableSQL, collectionToTable, collectionVersionsTable, computePatch, createBlockRegistry, createLocalApi, createVersionedLocalApi, createWebhookHook, decodeEditRef, defineCmsConfig, defineCollection, defineField, defineMigration, deliverWebhookMessage, diffDocuments, editAttr, encodeEditRef, extractSearchText, flattenDoc, flattenFields, generateSchemaSource, getCollectionsMeta, getRegisteredApi, mountVisualEditing, nestDoc, relationshipJoinTables, renderBlocksToString, rule, runMigration, validateDocument };
@@ -1,2 +1,2 @@
1
- import { $ as ValidationSeverity, A as CollectionConfig, B as RichTextFieldConfig, C as ArrayFieldConfig, D as CmsConfig, Dt as StringBlockRenderer, E as CheckboxFieldConfig, Et as PortableBlockLike, F as JsonFieldConfig, G as flattenFields, H as TextFieldConfig, I as JsonValue, J as CustomValidatorResult, K as nestDoc, L as NumberFieldConfig, M as DateFieldConfig, N as FieldConfig, O as CollectionAccess, Ot as createBlockRegistry, P as GroupFieldConfig, Q as ValidationFieldContext, R as RelationshipDepth, S as AccessFn, T as CadmeaPlugin, Tt as BlockRegistry, U as UploadFieldConfig, V as SelectFieldConfig, W as flattenDoc, X as ValidateDocumentOptions, Y as Rule, Z as ValidationBuilder, _ as collectionSearchTableSQL, a as BuildStudioStructureOptions, at as LocalApi, b as extractSearchText, c as StudioStructureItem, ct as createLocalApi, d as CollectionMeta, et as assertValid, f as getCollectionsMeta, g as collectionSearchTableName, h as cmsConfigToSchema, i as deliverWebhookMessage, it as CmsRegistry, j as CollectionHooks, k as CollectionAdminConfig, kt as renderBlocksToString, l as buildStudioStructure, lt as createVersionedLocalApi, m as defineCollection, n as WebhookMessage, nt as rule, o as DEFAULT_STUDIO_GROUP, ot as VersionedLocalApi, p as defineCmsConfig, q as CustomValidator, r as createWebhookHook, rt as validateDocument, s as StudioStructureGroup, st as can, t as WebhookConfig, tt as defineField, u as generateSchemaSource, ut as getRegisteredApi, v as collectionToTable, w as BaseFieldConfig, x as relationshipJoinTables, y as collectionVersionsTable, z as RelationshipFieldConfig } from "../index-BRZrCTsN.js";
2
- export { AccessFn, ArrayFieldConfig, BaseFieldConfig, BlockRegistry, BuildStudioStructureOptions, CadmeaPlugin, CheckboxFieldConfig, CmsConfig, CmsRegistry, CollectionAccess, CollectionAdminConfig, CollectionConfig, CollectionHooks, CollectionMeta, CustomValidator, CustomValidatorResult, DEFAULT_STUDIO_GROUP, DateFieldConfig, FieldConfig, GroupFieldConfig, JsonFieldConfig, JsonValue, LocalApi, NumberFieldConfig, PortableBlockLike, RelationshipDepth, RelationshipFieldConfig, RichTextFieldConfig, Rule, SelectFieldConfig, StringBlockRenderer, StudioStructureGroup, StudioStructureItem, TextFieldConfig, UploadFieldConfig, ValidateDocumentOptions, ValidationBuilder, ValidationFieldContext, ValidationSeverity, VersionedLocalApi, WebhookConfig, WebhookMessage, assertValid, buildStudioStructure, can, cmsConfigToSchema, collectionSearchTableName, collectionSearchTableSQL, collectionToTable, collectionVersionsTable, createBlockRegistry, createLocalApi, createVersionedLocalApi, createWebhookHook, defineCmsConfig, defineCollection, defineField, deliverWebhookMessage, extractSearchText, flattenDoc, flattenFields, generateSchemaSource, getCollectionsMeta, getRegisteredApi, nestDoc, relationshipJoinTables, renderBlocksToString, rule, validateDocument };
1
+ import { $ as RelationshipDepth, A as cmsConfigToSchema, At as PatchOp, B as CadmeaPlugin, C as RunMigrationOptions, Ct as createLocalApi, D as getCollectionsMeta, Dt as FieldChange, E as CollectionMeta, Et as DiffOptions, F as extractSearchText, G as CollectionConfig, H as CmsConfig, I as relationshipJoinTables, J as FieldConfig, Jt as BlockRegistry, K as CollectionHooks, L as AccessFn, M as collectionSearchTableSQL, Mt as computePatch, N as collectionToTable, Nt as diffDocuments, O as defineCmsConfig, Ot as FieldChangeKind, P as collectionVersionsTable, Q as NumberFieldConfig, Qt as renderBlocksToString, R as ArrayFieldConfig, S as MigrationResult, St as can, T as runMigration, Tt as getRegisteredApi, U as CollectionAccess, V as CheckboxFieldConfig, W as CollectionAdminConfig, X as JsonFieldConfig, Xt as StringBlockRenderer, Y as GroupFieldConfig, Yt as PortableBlockLike, Z as JsonValue, Zt as createBlockRegistry, _ as StudioStructureItem, _t as rule, a as EDIT_ATTR, at as flattenDoc, b as Migration, bt as LocalApi, c as VisualEditingMessage, ct as CustomValidator, d as editAttr, dt as ValidateDocumentOptions, et as RelationshipFieldConfig, f as encodeEditRef, ft as ValidationBuilder, g as StudioStructureGroup, gt as defineField, h as DEFAULT_STUDIO_GROUP, ht as assertValid, i as deliverWebhookMessage, it as UploadFieldConfig, j as collectionSearchTableName, jt as applyPatch, k as defineCollection, kt as Patch, l as VisualEditingOptions, lt as CustomValidatorResult, m as BuildStudioStructureOptions, mt as ValidationSeverity, n as WebhookMessage, nt as SelectFieldConfig, o as EditRef, ot as flattenFields, p as mountVisualEditing, pt as ValidationFieldContext, q as DateFieldConfig, r as createWebhookHook, rt as TextFieldConfig, s as VISUAL_EDIT_MESSAGE, st as nestDoc, t as WebhookConfig, tt as RichTextFieldConfig, u as decodeEditRef, ut as Rule, v as buildStudioStructure, vt as validateDocument, w as defineMigration, wt as createVersionedLocalApi, x as MigrationChange, xt as VersionedLocalApi, y as generateSchemaSource, yt as CmsRegistry, z as BaseFieldConfig } from "../index-sB3YOadC.js";
2
+ export { AccessFn, ArrayFieldConfig, BaseFieldConfig, BlockRegistry, BuildStudioStructureOptions, CadmeaPlugin, CheckboxFieldConfig, CmsConfig, CmsRegistry, CollectionAccess, CollectionAdminConfig, CollectionConfig, CollectionHooks, CollectionMeta, CustomValidator, CustomValidatorResult, DEFAULT_STUDIO_GROUP, DateFieldConfig, DiffOptions, EDIT_ATTR, EditRef, FieldChange, FieldChangeKind, FieldConfig, GroupFieldConfig, JsonFieldConfig, JsonValue, LocalApi, Migration, MigrationChange, MigrationResult, NumberFieldConfig, Patch, PatchOp, PortableBlockLike, RelationshipDepth, RelationshipFieldConfig, RichTextFieldConfig, Rule, RunMigrationOptions, SelectFieldConfig, StringBlockRenderer, StudioStructureGroup, StudioStructureItem, TextFieldConfig, UploadFieldConfig, VISUAL_EDIT_MESSAGE, ValidateDocumentOptions, ValidationBuilder, ValidationFieldContext, ValidationSeverity, VersionedLocalApi, VisualEditingMessage, VisualEditingOptions, WebhookConfig, WebhookMessage, applyPatch, assertValid, buildStudioStructure, can, cmsConfigToSchema, collectionSearchTableName, collectionSearchTableSQL, collectionToTable, collectionVersionsTable, computePatch, createBlockRegistry, createLocalApi, createVersionedLocalApi, createWebhookHook, decodeEditRef, defineCmsConfig, defineCollection, defineField, defineMigration, deliverWebhookMessage, diffDocuments, editAttr, encodeEditRef, extractSearchText, flattenDoc, flattenFields, generateSchemaSource, getCollectionsMeta, getRegisteredApi, mountVisualEditing, nestDoc, relationshipJoinTables, renderBlocksToString, rule, runMigration, validateDocument };
package/dist/cms/index.js CHANGED
@@ -306,6 +306,83 @@ function defineCmsConfig(config) {
306
306
  return resolved;
307
307
  }
308
308
  //#endregion
309
+ //#region src/cms/patch.ts
310
+ function deepEqual(a, b) {
311
+ if (a === b) return true;
312
+ if (a === null || b === null) return false;
313
+ if (typeof a !== typeof b) return false;
314
+ if (Array.isArray(a) || Array.isArray(b)) {
315
+ if (!Array.isArray(a) || !Array.isArray(b)) return false;
316
+ if (a.length !== b.length) return false;
317
+ return a.every((item, i) => deepEqual(item, b[i]));
318
+ }
319
+ if (typeof a === "object" && typeof b === "object") {
320
+ const ak = Object.keys(a);
321
+ const bk = Object.keys(b);
322
+ if (ak.length !== bk.length) return false;
323
+ return ak.every((key) => Object.hasOwn(b, key) && deepEqual(a[key], b[key]));
324
+ }
325
+ return false;
326
+ }
327
+ /**
328
+ * Field-level diff between two document snapshots — the per-field
329
+ * added/removed/changed list a version-history UI renders. Values are
330
+ * compared structurally (deep-equal), so a field only shows as `changed`
331
+ * when its content actually differs.
332
+ */
333
+ function diffDocuments(before, after, options = {}) {
334
+ const ignore = new Set(options.ignore ?? []);
335
+ const keys = options.fields ? options.fields : [...new Set([...Object.keys(before), ...Object.keys(after)])];
336
+ const changes = [];
337
+ for (const path of keys) {
338
+ if (ignore.has(path)) continue;
339
+ const inBefore = Object.hasOwn(before, path);
340
+ const inAfter = Object.hasOwn(after, path);
341
+ if (inBefore && !inAfter) changes.push({
342
+ path,
343
+ kind: "removed",
344
+ before: before[path]
345
+ });
346
+ else if (!inBefore && inAfter) changes.push({
347
+ path,
348
+ kind: "added",
349
+ after: after[path]
350
+ });
351
+ else if (inBefore && inAfter && !deepEqual(before[path], after[path])) changes.push({
352
+ path,
353
+ kind: "changed",
354
+ before: before[path],
355
+ after: after[path]
356
+ });
357
+ }
358
+ return changes;
359
+ }
360
+ /**
361
+ * The {@link Patch} that transforms `before` into `after`: `set` for each
362
+ * added/changed field, `unset` for each removed field. `applyPatch(before,
363
+ * computePatch(before, after))` deep-equals `after`.
364
+ */
365
+ function computePatch(before, after) {
366
+ return diffDocuments(before, after).map((change) => change.kind === "removed" ? {
367
+ op: "unset",
368
+ path: change.path
369
+ } : {
370
+ op: "set",
371
+ path: change.path,
372
+ value: change.after
373
+ });
374
+ }
375
+ /**
376
+ * Apply a {@link Patch} to a document, returning a new document (the input is
377
+ * never mutated). Unknown ops are ignored defensively.
378
+ */
379
+ function applyPatch(doc, patch) {
380
+ const next = { ...doc };
381
+ for (const op of patch) if (op.op === "set") next[op.path] = op.value;
382
+ else if (op.op === "unset") delete next[op.path];
383
+ return next;
384
+ }
385
+ //#endregion
309
386
  //#region src/cms/validation.ts
310
387
  const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
311
388
  const SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
@@ -894,6 +971,21 @@ function createVersionedLocalApi(db, table, versionsTable, config, registry) {
894
971
  const [row] = await db.update(table).set({ publishedVersionId: null }).where(eq(idColumn, id)).returning();
895
972
  if (!row) notFound(config, id);
896
973
  return row;
974
+ },
975
+ async diffVersions(context, fromVersionId, toVersionId) {
976
+ await checkAccess(config, "read", context);
977
+ const rows = await db.select().from(versionsTable).where(inArray(versionsIdColumn, [fromVersionId, toVersionId]));
978
+ const byId = new Map(rows.map((r) => [r.id, r.versionData]));
979
+ const before = byId.get(fromVersionId);
980
+ const after = byId.get(toVersionId);
981
+ if (!before) notFoundVersion(config, fromVersionId);
982
+ if (!after) notFoundVersion(config, toVersionId);
983
+ return diffDocuments(before, after, { ignore: [
984
+ "id",
985
+ "createdAt",
986
+ "status",
987
+ "publishedVersionId"
988
+ ] });
897
989
  }
898
990
  };
899
991
  }
@@ -907,6 +999,50 @@ function getCollectionsMeta(config) {
907
999
  }));
908
1000
  }
909
1001
  //#endregion
1002
+ //#region src/cms/migrate.ts
1003
+ /** Identity helper — gives a migration definition its type + a greppable call site. */
1004
+ function defineMigration(migration) {
1005
+ return migration;
1006
+ }
1007
+ function patchToUpdate(patch) {
1008
+ const values = {};
1009
+ for (const op of patch) values[op.path] = op.op === "set" ? op.value : null;
1010
+ return values;
1011
+ }
1012
+ /**
1013
+ * Run a migration over every document in a collection. Reads all documents
1014
+ * through `api.find`, applies `migration.document`, and (unless `dryRun`)
1015
+ * writes the resulting patch through `api.update`. Returns a report of what
1016
+ * changed — run it `dryRun` first, then apply.
1017
+ */
1018
+ async function runMigration(migration, options) {
1019
+ const { api, context, dryRun = false } = options;
1020
+ const rows = await api.find(context);
1021
+ const changes = [];
1022
+ const errors = [];
1023
+ let changed = 0;
1024
+ for (const before of rows) try {
1025
+ const patch = computePatch(before, await migration.document(before) ?? before);
1026
+ if (patch.length === 0) continue;
1027
+ changes.push({
1028
+ id: before.id,
1029
+ patch
1030
+ });
1031
+ changed++;
1032
+ if (!dryRun) await api.update(context, before.id, patchToUpdate(patch));
1033
+ } catch (err) {
1034
+ errors.push(`document ${before.id}: ${String(err)}`);
1035
+ }
1036
+ return {
1037
+ migration: migration.name,
1038
+ dryRun,
1039
+ scanned: rows.length,
1040
+ changed,
1041
+ changes,
1042
+ errors
1043
+ };
1044
+ }
1045
+ //#endregion
910
1046
  //#region src/cms/schema-gen.ts
911
1047
  function toSnakeCase(value) {
912
1048
  return value.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
@@ -1105,6 +1241,90 @@ function buildStudioStructure(config, options = {}) {
1105
1241
  }));
1106
1242
  }
1107
1243
  //#endregion
1244
+ //#region src/cms/visual-editing.ts
1245
+ /** The data attribute editable regions are tagged with. */
1246
+ const EDIT_ATTR = "data-cadmus-edit";
1247
+ /** `postMessage` payload type for a click-to-edit selection. */
1248
+ const VISUAL_EDIT_MESSAGE = "cadmus:visual-edit";
1249
+ function encodeEditRef(ref) {
1250
+ return `${ref.collection}:${ref.id}:${ref.field}`;
1251
+ }
1252
+ /** Parse an {@link EditRef} string, or null if malformed. */
1253
+ function decodeEditRef(value) {
1254
+ const parts = value.split(":");
1255
+ if (parts.length !== 3) return null;
1256
+ const [collection, idRaw, field] = parts;
1257
+ const id = Number.parseInt(idRaw, 10);
1258
+ if (!collection || !field || !Number.isFinite(id)) return null;
1259
+ return {
1260
+ collection,
1261
+ id,
1262
+ field
1263
+ };
1264
+ }
1265
+ /**
1266
+ * Attribute object to spread onto a rendered element so the overlay can map
1267
+ * it back to its source field, e.g. `<h1 {...editAttr({collection:'pages',
1268
+ * id, field:'title'})}>`.
1269
+ */
1270
+ function editAttr(ref) {
1271
+ return { [EDIT_ATTR]: encodeEditRef(ref) };
1272
+ }
1273
+ /**
1274
+ * Mount the click-to-edit overlay. Browser-only — call from a preview page's
1275
+ * client script. Highlights `[data-cadmus-edit]` elements on hover and, on
1276
+ * click, calls `onSelect` and posts a {@link VisualEditingMessage} to the
1277
+ * parent window. Returns a cleanup function that removes the listeners.
1278
+ */
1279
+ function mountVisualEditing(options = {}) {
1280
+ const { onSelect, targetOrigin = "*", highlightColor = "#56c6be" } = options;
1281
+ const closest = (target) => {
1282
+ if (!(target instanceof Element)) return null;
1283
+ const el = target.closest(`[${EDIT_ATTR}]`);
1284
+ return el instanceof HTMLElement ? el : null;
1285
+ };
1286
+ let previous = null;
1287
+ const clearHighlight = () => {
1288
+ if (previous) {
1289
+ previous.el.style.outline = previous.outline;
1290
+ previous = null;
1291
+ }
1292
+ };
1293
+ const onOver = (event) => {
1294
+ const el = closest(event.target);
1295
+ if (!el || el === previous?.el) return;
1296
+ clearHighlight();
1297
+ previous = {
1298
+ el,
1299
+ outline: el.style.outline
1300
+ };
1301
+ el.style.outline = `2px solid ${highlightColor}`;
1302
+ el.style.outlineOffset = "2px";
1303
+ el.style.cursor = "pointer";
1304
+ };
1305
+ const onClick = (event) => {
1306
+ const el = closest(event.target);
1307
+ if (!el) return;
1308
+ const ref = decodeEditRef(el.getAttribute("data-cadmus-edit") ?? "");
1309
+ if (!ref) return;
1310
+ event.preventDefault();
1311
+ event.stopPropagation();
1312
+ onSelect?.(ref, el);
1313
+ const message = {
1314
+ type: VISUAL_EDIT_MESSAGE,
1315
+ ref
1316
+ };
1317
+ window.parent?.postMessage(message, targetOrigin);
1318
+ };
1319
+ document.addEventListener("mouseover", onOver, true);
1320
+ document.addEventListener("click", onClick, true);
1321
+ return () => {
1322
+ clearHighlight();
1323
+ document.removeEventListener("mouseover", onOver, true);
1324
+ document.removeEventListener("click", onClick, true);
1325
+ };
1326
+ }
1327
+ //#endregion
1108
1328
  //#region src/cms/webhooks.ts
1109
1329
  /**
1110
1330
  * Builds an `afterChange` hook that enqueues a `WebhookMessage` for every
@@ -1184,6 +1404,6 @@ async function deliverWebhookMessage(message) {
1184
1404
  if (!response.ok) throw new CadmusQueueError(`Webhook delivery to "${message.url}" returned status ${response.status}`);
1185
1405
  }
1186
1406
  //#endregion
1187
- export { DEFAULT_STUDIO_GROUP, Rule, assertValid, buildStudioStructure, can, cmsConfigToSchema, collectionSearchTableName, collectionSearchTableSQL, collectionToTable, collectionVersionsTable, createBlockRegistry, createLocalApi, createVersionedLocalApi, createWebhookHook, defineCmsConfig, defineCollection, defineField, deliverWebhookMessage, extractSearchText, flattenDoc, flattenFields, generateSchemaSource, getCollectionsMeta, getRegisteredApi, nestDoc, relationshipJoinTables, renderBlocksToString, rule, validateDocument };
1407
+ export { DEFAULT_STUDIO_GROUP, EDIT_ATTR, Rule, VISUAL_EDIT_MESSAGE, applyPatch, assertValid, buildStudioStructure, can, cmsConfigToSchema, collectionSearchTableName, collectionSearchTableSQL, collectionToTable, collectionVersionsTable, computePatch, createBlockRegistry, createLocalApi, createVersionedLocalApi, createWebhookHook, decodeEditRef, defineCmsConfig, defineCollection, defineField, defineMigration, deliverWebhookMessage, diffDocuments, editAttr, encodeEditRef, extractSearchText, flattenDoc, flattenFields, generateSchemaSource, getCollectionsMeta, getRegisteredApi, mountVisualEditing, nestDoc, relationshipJoinTables, renderBlocksToString, rule, runMigration, validateDocument };
1188
1408
 
1189
1409
  //# sourceMappingURL=index.js.map