@preprio/toolkit 0.5.0-rc.3 → 0.5.0-rc.5

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.
Files changed (39) hide show
  1. package/README.md +226 -151
  2. package/dist/astro/index.cjs +27 -7
  3. package/dist/astro/index.js +27 -7
  4. package/dist/{chunk-SXUDBGLZ.js → chunk-3X55JL52.js} +1 -1
  5. package/dist/{chunk-42Z2VW7G.js → chunk-74KY5EAM.js} +67 -9
  6. package/dist/{chunk-MDAV2FLM.js → chunk-CMUFTCG3.js} +1 -1
  7. package/dist/{chunk-PP3O7RB4.js → chunk-SBLZANL5.js} +1 -1
  8. package/dist/{chunk-6WY3MWCX.js → chunk-TG6N3C22.js} +1 -1
  9. package/dist/index.cjs +68 -10
  10. package/dist/index.d.cts +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.js +5 -5
  13. package/dist/{live-preview-EADA3ZL4.js → live-preview-H4643QYF.js} +2 -2
  14. package/dist/nextjs/components.cjs +1 -1
  15. package/dist/nextjs/components.js +2 -2
  16. package/dist/nextjs/index.cjs +27 -7
  17. package/dist/nextjs/index.d.cts +2 -0
  18. package/dist/nextjs/index.d.ts +2 -0
  19. package/dist/nextjs/index.js +27 -7
  20. package/dist/nextjs/live-action.js +3 -3
  21. package/dist/nextjs/live.cjs +73 -12
  22. package/dist/nextjs/live.d.cts +3 -1
  23. package/dist/nextjs/live.d.ts +3 -1
  24. package/dist/nextjs/live.js +5 -2
  25. package/dist/nuxt/index.cjs +1 -1
  26. package/dist/nuxt/index.js +1 -1
  27. package/dist/nuxt/{live-preview-PTEC3GPC.js → live-preview-O2ZTJNW4.js} +67 -9
  28. package/dist/nuxt/live.cjs +69 -11
  29. package/dist/nuxt/live.js +1 -1
  30. package/dist/react/components.cjs +1 -1
  31. package/dist/react/components.js +1 -1
  32. package/dist/sveltekit/index.cjs +1 -1
  33. package/dist/sveltekit/index.js +1 -1
  34. package/dist/sveltekit/live-preview-O2ZTJNW4.js +1520 -0
  35. package/dist/sveltekit/live.cjs +1731 -0
  36. package/dist/sveltekit/live.d.cts +59 -0
  37. package/dist/sveltekit/live.d.ts +59 -0
  38. package/dist/sveltekit/live.js +97 -0
  39. package/package.json +6 -1
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var VERSION = "0.5.0-rc.3";
2
+ var VERSION = "0.5.0-rc.5";
3
3
 
4
4
  // src/core/features.ts
5
5
  function isEnabled(config) {
@@ -381,6 +381,20 @@ var UPPERCASE_BOUNDARY = /(.)(?=[A-Z])/g;
381
381
  function graphqlFieldName(apiId) {
382
382
  return apiId.replace(UPPERCASE_BOUNDARY, "$1_").toLowerCase();
383
383
  }
384
+ var TEXT_BODY_FIELDS = [
385
+ { name: "body", plain: false },
386
+ { name: "html", plain: false },
387
+ { name: "text", plain: true }
388
+ ];
389
+ var TAG_PATTERN = /<[^>]+>/g;
390
+ function plainTextFromHtml(html) {
391
+ return html.replace(TAG_PATTERN, "");
392
+ }
393
+ function isTextEntry(record) {
394
+ const typename = record.__typename;
395
+ if (typeof typename === "string") return typename === "Text";
396
+ return "html" in record || "text" in record && "format" in record;
397
+ }
384
398
 
385
399
  // src/core/live-preview/index-snapshot.ts
386
400
  var debug = createScopedLogger("live-preview");
@@ -518,7 +532,6 @@ function listKeysOf(entry) {
518
532
  }
519
533
  return keys;
520
534
  }
521
- var TAG_PATTERN = /<[^>]+>/g;
522
535
  function buildText(entry, template) {
523
536
  const body = typeof entry.body === "string" ? entry.body : "";
524
537
  const full = {
@@ -526,7 +539,7 @@ function buildText(entry, template) {
526
539
  _id: entry._id,
527
540
  body,
528
541
  html: body,
529
- text: body.replace(TAG_PATTERN, ""),
542
+ text: plainTextFromHtml(body),
530
543
  format: entry.format ?? null
531
544
  };
532
545
  if (!template) return full;
@@ -1129,11 +1142,13 @@ function applyPatch(root, index, patch, doc, result) {
1129
1142
  const segments = patch.field.split(".");
1130
1143
  if (segments.some((s) => !s || FORBIDDEN_SEGMENTS2.has(s))) return root;
1131
1144
  const targets = [];
1145
+ const plain = /* @__PURE__ */ new Set();
1132
1146
  for (const ownerPath of ownerPaths) {
1133
1147
  if (doc) {
1134
1148
  const resolved = resolveTargets(root, doc, ownerPath, segments);
1135
1149
  root = resolved.root;
1136
1150
  targets.push(...resolved.targets);
1151
+ resolved.plain.forEach((target) => plain.add(target));
1137
1152
  } else {
1138
1153
  targets.push([...ownerPath, ...segments.map(toPathSegment)]);
1139
1154
  }
@@ -1147,7 +1162,8 @@ function applyPatch(root, index, patch, doc, result) {
1147
1162
  }
1148
1163
  if (patch.type === "field") {
1149
1164
  for (const target of targets) {
1150
- let value = keepEditLink(readAtPath(root, target), patch.value);
1165
+ const pushed = plain.has(target) && typeof patch.value === "string" ? plainTextFromHtml(patch.value) : patch.value;
1166
+ let value = keepEditLink(readAtPath(root, target), pushed);
1151
1167
  if (patch.edit && typeof value === "string" && !vercelStegaSplit2(value).encoded) {
1152
1168
  value = editLinksFor(result, patch.edit.item)?.encode(
1153
1169
  value,
@@ -1211,9 +1227,10 @@ function resolveTargets(root, doc, ownerPath, segments) {
1211
1227
  owner = owner[step];
1212
1228
  }
1213
1229
  const selections = selectionsAt(root, doc, ownerPath);
1214
- if (!selections) return { root, targets: [] };
1230
+ if (!selections) return { root, targets: [], plain: /* @__PURE__ */ new Set() };
1215
1231
  let current = root;
1216
1232
  const out = [];
1233
+ const plain = /* @__PURE__ */ new Set();
1217
1234
  const walk = (node, sel, i, path) => {
1218
1235
  if (i === segments.length) {
1219
1236
  out.push(path);
@@ -1234,12 +1251,15 @@ function resolveTargets(root, doc, ownerPath, segments) {
1234
1251
  if (node === null || typeof node !== "object") return;
1235
1252
  const record = node;
1236
1253
  const wanted = graphqlFieldName(segment);
1254
+ const textBody = i === segments.length - 1 && segment === "body" && isTextEntry(record) ? TEXT_BODY_FIELDS : null;
1237
1255
  let matched = false;
1238
1256
  for (const field of collectFields(sel, typenameOf(node), doc).values()) {
1239
- if (field.name !== segment && field.name !== wanted) continue;
1257
+ const alias = textBody?.find((f) => f.name === field.name);
1258
+ if (field.name !== segment && field.name !== wanted && !alias) continue;
1240
1259
  if (!Object.prototype.hasOwnProperty.call(record, field.key)) continue;
1241
1260
  matched = true;
1242
1261
  const fieldPath = [...path, field.key];
1262
+ if (alias?.plain) plain.add(fieldPath);
1243
1263
  let value = record[field.key];
1244
1264
  const next = segments[i + 1];
1245
1265
  if (value === null && field.selections.length && next !== void 0 && next !== "items" && !INDEX_SEGMENT.test(next)) {
@@ -1262,7 +1282,7 @@ function resolveTargets(root, doc, ownerPath, segments) {
1262
1282
  if (!matched && segment === "items") walk(node, sel, i + 1, path);
1263
1283
  };
1264
1284
  walk(owner, selections, 0, ownerPath);
1265
- return { root: current, targets: out };
1285
+ return { root: current, targets: out, plain };
1266
1286
  }
1267
1287
  var NON_ALPHANUMERIC = /[^a-z0-9]/gi;
1268
1288
  var typeKey = (name) => name.replace(NON_ALPHANUMERIC, "").toLowerCase();
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  VERSION,
3
3
  resolveFeatures
4
- } from "./chunk-MDAV2FLM.js";
4
+ } from "./chunk-CMUFTCG3.js";
5
5
 
6
6
  // src/core/server.ts
7
7
  var PreprError = class extends Error {
@@ -19,6 +19,20 @@ function fieldKeyIn(record, apiId) {
19
19
  const name = graphqlFieldName(apiId);
20
20
  return Object.prototype.hasOwnProperty.call(record, name) ? name : void 0;
21
21
  }
22
+ var TEXT_BODY_FIELDS = [
23
+ { name: "body", plain: false },
24
+ { name: "html", plain: false },
25
+ { name: "text", plain: true }
26
+ ];
27
+ var TAG_PATTERN = /<[^>]+>/g;
28
+ function plainTextFromHtml(html) {
29
+ return html.replace(TAG_PATTERN, "");
30
+ }
31
+ function isTextEntry(record) {
32
+ const typename = record.__typename;
33
+ if (typeof typename === "string") return typename === "Text";
34
+ return "html" in record || "text" in record && "format" in record;
35
+ }
22
36
 
23
37
  // src/core/live-preview/index-snapshot.ts
24
38
  var debug = createScopedLogger("live-preview");
@@ -118,13 +132,51 @@ function patchSnapshot(snapshot, index, itemId, field, value) {
118
132
  if (!paths?.length) return snapshot;
119
133
  let root = snapshot;
120
134
  let changed = false;
135
+ const markChanged = () => {
136
+ changed = true;
137
+ };
121
138
  for (const path of paths) {
122
- root = patchAtPath(root, path, field, value, () => {
123
- changed = true;
124
- });
139
+ for (const [target, targetValue] of expandTextBody(
140
+ root,
141
+ path,
142
+ field,
143
+ value
144
+ )) {
145
+ root = patchAtPath(root, path, target, targetValue, markChanged);
146
+ }
125
147
  }
126
148
  return changed ? root : snapshot;
127
149
  }
150
+ function expandTextBody(root, path, field, value) {
151
+ const segments = field.split(".");
152
+ if (segments[segments.length - 1] !== "body" || typeof value !== "string") {
153
+ return [[field, value]];
154
+ }
155
+ let node = root;
156
+ for (const step of path) {
157
+ node = node[step];
158
+ }
159
+ for (const segment of segments.slice(0, -1)) {
160
+ if (node === null || typeof node !== "object") return [[field, value]];
161
+ const record2 = node;
162
+ node = INDEX_SEGMENT.test(segment) ? record2[Number(segment)] : record2[fieldKeyIn(record2, segment) ?? segment];
163
+ }
164
+ if (node === null || typeof node !== "object" || Array.isArray(node)) {
165
+ return [[field, value]];
166
+ }
167
+ const record = node;
168
+ if (!isTextEntry(record)) return [[field, value]];
169
+ const prefix = segments.slice(0, -1);
170
+ const writes = [];
171
+ for (const { name, plain } of TEXT_BODY_FIELDS) {
172
+ if (!(name in record)) continue;
173
+ writes.push([
174
+ [...prefix, name].join("."),
175
+ plain ? plainTextFromHtml(value) : value
176
+ ]);
177
+ }
178
+ return writes.length ? writes : [[field, value]];
179
+ }
128
180
  function patchAtPath(root, path, field, value, markChanged) {
129
181
  const segments = field.split(".");
130
182
  if (segments.some((s) => FORBIDDEN_SEGMENTS.has(s))) return root;
@@ -189,7 +241,6 @@ function listKeysOf(entry) {
189
241
  }
190
242
  return keys;
191
243
  }
192
- var TAG_PATTERN = /<[^>]+>/g;
193
244
  function buildText(entry, template) {
194
245
  const body = typeof entry.body === "string" ? entry.body : "";
195
246
  const full = {
@@ -197,7 +248,7 @@ function buildText(entry, template) {
197
248
  _id: entry._id,
198
249
  body,
199
250
  html: body,
200
- text: body.replace(TAG_PATTERN, ""),
251
+ text: plainTextFromHtml(body),
201
252
  format: entry.format ?? null
202
253
  };
203
254
  if (!template) return full;
@@ -811,11 +862,13 @@ function applyPatch(root, index, patch, doc, result) {
811
862
  const segments = patch.field.split(".");
812
863
  if (segments.some((s) => !s || FORBIDDEN_SEGMENTS2.has(s))) return root;
813
864
  const targets = [];
865
+ const plain = /* @__PURE__ */ new Set();
814
866
  for (const ownerPath of ownerPaths) {
815
867
  if (doc) {
816
868
  const resolved = resolveTargets(root, doc, ownerPath, segments);
817
869
  root = resolved.root;
818
870
  targets.push(...resolved.targets);
871
+ resolved.plain.forEach((target) => plain.add(target));
819
872
  } else {
820
873
  targets.push([...ownerPath, ...segments.map(toPathSegment)]);
821
874
  }
@@ -829,7 +882,8 @@ function applyPatch(root, index, patch, doc, result) {
829
882
  }
830
883
  if (patch.type === "field") {
831
884
  for (const target of targets) {
832
- let value = keepEditLink(readAtPath(root, target), patch.value);
885
+ const pushed = plain.has(target) && typeof patch.value === "string" ? plainTextFromHtml(patch.value) : patch.value;
886
+ let value = keepEditLink(readAtPath(root, target), pushed);
833
887
  if (patch.edit && typeof value === "string" && !vercelStegaSplit2(value).encoded) {
834
888
  value = editLinksFor(result, patch.edit.item)?.encode(
835
889
  value,
@@ -893,9 +947,10 @@ function resolveTargets(root, doc, ownerPath, segments) {
893
947
  owner = owner[step];
894
948
  }
895
949
  const selections = selectionsAt(root, doc, ownerPath);
896
- if (!selections) return { root, targets: [] };
950
+ if (!selections) return { root, targets: [], plain: /* @__PURE__ */ new Set() };
897
951
  let current = root;
898
952
  const out = [];
953
+ const plain = /* @__PURE__ */ new Set();
899
954
  const walk = (node, sel, i, path) => {
900
955
  if (i === segments.length) {
901
956
  out.push(path);
@@ -916,12 +971,15 @@ function resolveTargets(root, doc, ownerPath, segments) {
916
971
  if (node === null || typeof node !== "object") return;
917
972
  const record = node;
918
973
  const wanted = graphqlFieldName(segment);
974
+ const textBody = i === segments.length - 1 && segment === "body" && isTextEntry(record) ? TEXT_BODY_FIELDS : null;
919
975
  let matched = false;
920
976
  for (const field of collectFields(sel, typenameOf(node), doc).values()) {
921
- if (field.name !== segment && field.name !== wanted) continue;
977
+ const alias = textBody?.find((f) => f.name === field.name);
978
+ if (field.name !== segment && field.name !== wanted && !alias) continue;
922
979
  if (!Object.prototype.hasOwnProperty.call(record, field.key)) continue;
923
980
  matched = true;
924
981
  const fieldPath = [...path, field.key];
982
+ if (alias?.plain) plain.add(fieldPath);
925
983
  let value = record[field.key];
926
984
  const next = segments[i + 1];
927
985
  if (value === null && field.selections.length && next !== void 0 && next !== "items" && !INDEX_SEGMENT2.test(next)) {
@@ -944,7 +1002,7 @@ function resolveTargets(root, doc, ownerPath, segments) {
944
1002
  if (!matched && segment === "items") walk(node, sel, i + 1, path);
945
1003
  };
946
1004
  walk(owner, selections, 0, ownerPath);
947
- return { root: current, targets: out };
1005
+ return { root: current, targets: out, plain };
948
1006
  }
949
1007
  var NON_ALPHANUMERIC = /[^a-z0-9]/gi;
950
1008
  var typeKey = (name) => name.replace(NON_ALPHANUMERIC, "").toLowerCase();
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var VERSION = "0.5.0-rc.3";
2
+ var VERSION = "0.5.0-rc.5";
3
3
 
4
4
  // src/core/features.ts
5
5
  function isEnabled(config) {
@@ -2,7 +2,7 @@ import {
2
2
  ALL_FEATURES_ENABLED,
3
3
  VERSION,
4
4
  resolveFeatures
5
- } from "./chunk-MDAV2FLM.js";
5
+ } from "./chunk-CMUFTCG3.js";
6
6
  import {
7
7
  createIframeBridge,
8
8
  isLocale,
@@ -8,7 +8,7 @@ import {
8
8
  parseListEntries,
9
9
  patchSnapshot,
10
10
  syncListSnapshot
11
- } from "./chunk-42Z2VW7G.js";
11
+ } from "./chunk-74KY5EAM.js";
12
12
  import {
13
13
  createScopedLogger,
14
14
  getTrustedParentOrigin,
package/dist/index.cjs CHANGED
@@ -49,7 +49,7 @@ __export(src_exports, {
49
49
  module.exports = __toCommonJS(src_exports);
50
50
 
51
51
  // src/version.ts
52
- var VERSION = "0.5.0-rc.3";
52
+ var VERSION = "0.5.0-rc.5";
53
53
 
54
54
  // src/core/features.ts
55
55
  function isEnabled(config) {
@@ -3572,6 +3572,20 @@ function fieldKeyIn(record, apiId) {
3572
3572
  const name = graphqlFieldName(apiId);
3573
3573
  return Object.prototype.hasOwnProperty.call(record, name) ? name : void 0;
3574
3574
  }
3575
+ var TEXT_BODY_FIELDS = [
3576
+ { name: "body", plain: false },
3577
+ { name: "html", plain: false },
3578
+ { name: "text", plain: true }
3579
+ ];
3580
+ var TAG_PATTERN = /<[^>]+>/g;
3581
+ function plainTextFromHtml(html) {
3582
+ return html.replace(TAG_PATTERN, "");
3583
+ }
3584
+ function isTextEntry(record) {
3585
+ const typename = record.__typename;
3586
+ if (typeof typename === "string") return typename === "Text";
3587
+ return "html" in record || "text" in record && "format" in record;
3588
+ }
3575
3589
 
3576
3590
  // src/core/live-preview/index-snapshot.ts
3577
3591
  var debug10 = createScopedLogger("live-preview");
@@ -3671,13 +3685,51 @@ function patchSnapshot(snapshot, index, itemId, field, value) {
3671
3685
  if (!paths?.length) return snapshot;
3672
3686
  let root = snapshot;
3673
3687
  let changed = false;
3688
+ const markChanged = () => {
3689
+ changed = true;
3690
+ };
3674
3691
  for (const path of paths) {
3675
- root = patchAtPath(root, path, field, value, () => {
3676
- changed = true;
3677
- });
3692
+ for (const [target, targetValue] of expandTextBody(
3693
+ root,
3694
+ path,
3695
+ field,
3696
+ value
3697
+ )) {
3698
+ root = patchAtPath(root, path, target, targetValue, markChanged);
3699
+ }
3678
3700
  }
3679
3701
  return changed ? root : snapshot;
3680
3702
  }
3703
+ function expandTextBody(root, path, field, value) {
3704
+ const segments = field.split(".");
3705
+ if (segments[segments.length - 1] !== "body" || typeof value !== "string") {
3706
+ return [[field, value]];
3707
+ }
3708
+ let node = root;
3709
+ for (const step of path) {
3710
+ node = node[step];
3711
+ }
3712
+ for (const segment of segments.slice(0, -1)) {
3713
+ if (node === null || typeof node !== "object") return [[field, value]];
3714
+ const record2 = node;
3715
+ node = INDEX_SEGMENT2.test(segment) ? record2[Number(segment)] : record2[fieldKeyIn(record2, segment) ?? segment];
3716
+ }
3717
+ if (node === null || typeof node !== "object" || Array.isArray(node)) {
3718
+ return [[field, value]];
3719
+ }
3720
+ const record = node;
3721
+ if (!isTextEntry(record)) return [[field, value]];
3722
+ const prefix = segments.slice(0, -1);
3723
+ const writes = [];
3724
+ for (const { name, plain } of TEXT_BODY_FIELDS) {
3725
+ if (!(name in record)) continue;
3726
+ writes.push([
3727
+ [...prefix, name].join("."),
3728
+ plain ? plainTextFromHtml(value) : value
3729
+ ]);
3730
+ }
3731
+ return writes.length ? writes : [[field, value]];
3732
+ }
3681
3733
  function patchAtPath(root, path, field, value, markChanged) {
3682
3734
  const segments = field.split(".");
3683
3735
  if (segments.some((s2) => FORBIDDEN_SEGMENTS.has(s2))) return root;
@@ -3742,7 +3794,6 @@ function listKeysOf(entry) {
3742
3794
  }
3743
3795
  return keys;
3744
3796
  }
3745
- var TAG_PATTERN = /<[^>]+>/g;
3746
3797
  function buildText(entry, template) {
3747
3798
  const body = typeof entry.body === "string" ? entry.body : "";
3748
3799
  const full = {
@@ -3750,7 +3801,7 @@ function buildText(entry, template) {
3750
3801
  _id: entry._id,
3751
3802
  body,
3752
3803
  html: body,
3753
- text: body.replace(TAG_PATTERN, ""),
3804
+ text: plainTextFromHtml(body),
3754
3805
  format: entry.format ?? null
3755
3806
  };
3756
3807
  if (!template) return full;
@@ -4364,11 +4415,13 @@ function applyPatch(root, index, patch, doc, result) {
4364
4415
  const segments = patch.field.split(".");
4365
4416
  if (segments.some((s2) => !s2 || FORBIDDEN_SEGMENTS2.has(s2))) return root;
4366
4417
  const targets = [];
4418
+ const plain = /* @__PURE__ */ new Set();
4367
4419
  for (const ownerPath of ownerPaths) {
4368
4420
  if (doc) {
4369
4421
  const resolved = resolveTargets(root, doc, ownerPath, segments);
4370
4422
  root = resolved.root;
4371
4423
  targets.push(...resolved.targets);
4424
+ resolved.plain.forEach((target) => plain.add(target));
4372
4425
  } else {
4373
4426
  targets.push([...ownerPath, ...segments.map(toPathSegment)]);
4374
4427
  }
@@ -4382,7 +4435,8 @@ function applyPatch(root, index, patch, doc, result) {
4382
4435
  }
4383
4436
  if (patch.type === "field") {
4384
4437
  for (const target of targets) {
4385
- let value = keepEditLink(readAtPath(root, target), patch.value);
4438
+ const pushed = plain.has(target) && typeof patch.value === "string" ? plainTextFromHtml(patch.value) : patch.value;
4439
+ let value = keepEditLink(readAtPath(root, target), pushed);
4386
4440
  if (patch.edit && typeof value === "string" && !(0, import_stega6.vercelStegaSplit)(value).encoded) {
4387
4441
  value = editLinksFor(result, patch.edit.item)?.encode(
4388
4442
  value,
@@ -4446,9 +4500,10 @@ function resolveTargets(root, doc, ownerPath, segments) {
4446
4500
  owner = owner[step];
4447
4501
  }
4448
4502
  const selections = selectionsAt(root, doc, ownerPath);
4449
- if (!selections) return { root, targets: [] };
4503
+ if (!selections) return { root, targets: [], plain: /* @__PURE__ */ new Set() };
4450
4504
  let current = root;
4451
4505
  const out = [];
4506
+ const plain = /* @__PURE__ */ new Set();
4452
4507
  const walk = (node, sel, i2, path) => {
4453
4508
  if (i2 === segments.length) {
4454
4509
  out.push(path);
@@ -4469,12 +4524,15 @@ function resolveTargets(root, doc, ownerPath, segments) {
4469
4524
  if (node === null || typeof node !== "object") return;
4470
4525
  const record = node;
4471
4526
  const wanted = graphqlFieldName(segment);
4527
+ const textBody = i2 === segments.length - 1 && segment === "body" && isTextEntry(record) ? TEXT_BODY_FIELDS : null;
4472
4528
  let matched = false;
4473
4529
  for (const field of collectFields(sel, typenameOf(node), doc).values()) {
4474
- if (field.name !== segment && field.name !== wanted) continue;
4530
+ const alias = textBody?.find((f3) => f3.name === field.name);
4531
+ if (field.name !== segment && field.name !== wanted && !alias) continue;
4475
4532
  if (!Object.prototype.hasOwnProperty.call(record, field.key)) continue;
4476
4533
  matched = true;
4477
4534
  const fieldPath = [...path, field.key];
4535
+ if (alias?.plain) plain.add(fieldPath);
4478
4536
  let value = record[field.key];
4479
4537
  const next = segments[i2 + 1];
4480
4538
  if (value === null && field.selections.length && next !== void 0 && next !== "items" && !INDEX_SEGMENT3.test(next)) {
@@ -4497,7 +4555,7 @@ function resolveTargets(root, doc, ownerPath, segments) {
4497
4555
  if (!matched && segment === "items") walk(node, sel, i2 + 1, path);
4498
4556
  };
4499
4557
  walk(owner, selections, 0, ownerPath);
4500
- return { root: current, targets: out };
4558
+ return { root: current, targets: out, plain };
4501
4559
  }
4502
4560
  var NON_ALPHANUMERIC = /[^a-z0-9]/gi;
4503
4561
  var typeKey = (name) => name.replace(NON_ALPHANUMERIC, "").toLowerCase();
package/dist/index.d.cts CHANGED
@@ -5,7 +5,7 @@ export { g as PreprEnvironment, h as PreprEventType, i as PreprFeatureConfig, j
5
5
  * Package version; must match package.json. Lives in its own leaf module so
6
6
  * core can import it without cycling through the barrel.
7
7
  */
8
- declare const VERSION = "0.5.0-rc.3";
8
+ declare const VERSION = "0.5.0-rc.5";
9
9
 
10
10
  /**
11
11
  * Resolve a `PreprFeatures` bag to plain booleans, defaulting every omitted key
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ export { g as PreprEnvironment, h as PreprEventType, i as PreprFeatureConfig, j
5
5
  * Package version; must match package.json. Lives in its own leaf module so
6
6
  * core can import it without cycling through the barrel.
7
7
  */
8
- declare const VERSION = "0.5.0-rc.3";
8
+ declare const VERSION = "0.5.0-rc.5";
9
9
 
10
10
  /**
11
11
  * Resolve a `PreprFeatures` bag to plain booleans, defaulting every omitted key
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  setTrackingParam,
18
18
  stegaClean,
19
19
  trackEvent
20
- } from "./chunk-PP3O7RB4.js";
20
+ } from "./chunk-SBLZANL5.js";
21
21
  import {
22
22
  PreprError,
23
23
  extractAccessToken,
@@ -28,20 +28,20 @@ import {
28
28
  getPreprUUIDFromHeaders,
29
29
  getToolbarPropsFromHeaders,
30
30
  validatePreprToken
31
- } from "./chunk-SXUDBGLZ.js";
31
+ } from "./chunk-3X55JL52.js";
32
32
  import {
33
33
  VERSION,
34
34
  resolveFeatures
35
- } from "./chunk-MDAV2FLM.js";
35
+ } from "./chunk-CMUFTCG3.js";
36
36
  import {
37
37
  createLiveBridge,
38
38
  createLiveStore
39
- } from "./chunk-6WY3MWCX.js";
39
+ } from "./chunk-TG6N3C22.js";
40
40
  import "./chunk-URXSDJOU.js";
41
41
  import {
42
42
  normalizeQuery,
43
43
  parsePatchLog
44
- } from "./chunk-42Z2VW7G.js";
44
+ } from "./chunk-74KY5EAM.js";
45
45
  import {
46
46
  createScopedLogger
47
47
  } from "./chunk-S3VT4UWM.js";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  createLiveBridge,
3
3
  createLiveStore
4
- } from "./chunk-6WY3MWCX.js";
4
+ } from "./chunk-TG6N3C22.js";
5
5
  import "./chunk-URXSDJOU.js";
6
6
  import {
7
7
  applyPatchLog,
8
8
  normalizeQuery,
9
9
  parsePatchLog
10
- } from "./chunk-42Z2VW7G.js";
10
+ } from "./chunk-74KY5EAM.js";
11
11
  import "./chunk-S3VT4UWM.js";
12
12
  export {
13
13
  applyPatchLog,
@@ -3517,7 +3517,7 @@ function createPreprPreview(opts = {}) {
3517
3517
  var import_react = require("react");
3518
3518
 
3519
3519
  // src/version.ts
3520
- var VERSION = "0.5.0-rc.3";
3520
+ var VERSION = "0.5.0-rc.5";
3521
3521
 
3522
3522
  // src/core/pixel.ts
3523
3523
  var PIXEL_SCRIPT_URL = "https://cdn.tracking.prepr.io/js/prepr.min.js";
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  createPreprPreview,
4
4
  loadTrackingPixel
5
- } from "../chunk-PP3O7RB4.js";
6
- import "../chunk-MDAV2FLM.js";
5
+ } from "../chunk-SBLZANL5.js";
6
+ import "../chunk-CMUFTCG3.js";
7
7
  import "../chunk-URXSDJOU.js";
8
8
  import "../chunk-S3VT4UWM.js";
9
9
 
@@ -49,7 +49,7 @@ module.exports = __toCommonJS(nextjs_exports);
49
49
  var import_server = require("next/server");
50
50
 
51
51
  // src/version.ts
52
- var VERSION = "0.5.0-rc.3";
52
+ var VERSION = "0.5.0-rc.5";
53
53
 
54
54
  // src/core/constants.ts
55
55
  var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
@@ -324,6 +324,20 @@ var UPPERCASE_BOUNDARY = /(.)(?=[A-Z])/g;
324
324
  function graphqlFieldName(apiId) {
325
325
  return apiId.replace(UPPERCASE_BOUNDARY, "$1_").toLowerCase();
326
326
  }
327
+ var TEXT_BODY_FIELDS = [
328
+ { name: "body", plain: false },
329
+ { name: "html", plain: false },
330
+ { name: "text", plain: true }
331
+ ];
332
+ var TAG_PATTERN = /<[^>]+>/g;
333
+ function plainTextFromHtml(html) {
334
+ return html.replace(TAG_PATTERN, "");
335
+ }
336
+ function isTextEntry(record) {
337
+ const typename = record.__typename;
338
+ if (typeof typename === "string") return typename === "Text";
339
+ return "html" in record || "text" in record && "format" in record;
340
+ }
327
341
 
328
342
  // src/core/live-preview/index-snapshot.ts
329
343
  var debug = createScopedLogger("live-preview");
@@ -461,7 +475,6 @@ function listKeysOf(entry) {
461
475
  }
462
476
  return keys;
463
477
  }
464
- var TAG_PATTERN = /<[^>]+>/g;
465
478
  function buildText(entry, template) {
466
479
  const body = typeof entry.body === "string" ? entry.body : "";
467
480
  const full = {
@@ -469,7 +482,7 @@ function buildText(entry, template) {
469
482
  _id: entry._id,
470
483
  body,
471
484
  html: body,
472
- text: body.replace(TAG_PATTERN, ""),
485
+ text: plainTextFromHtml(body),
473
486
  format: entry.format ?? null
474
487
  };
475
488
  if (!template) return full;
@@ -929,11 +942,13 @@ function applyPatch(root, index, patch, doc, result) {
929
942
  const segments = patch.field.split(".");
930
943
  if (segments.some((s) => !s || FORBIDDEN_SEGMENTS2.has(s))) return root;
931
944
  const targets = [];
945
+ const plain = /* @__PURE__ */ new Set();
932
946
  for (const ownerPath of ownerPaths) {
933
947
  if (doc) {
934
948
  const resolved = resolveTargets(root, doc, ownerPath, segments);
935
949
  root = resolved.root;
936
950
  targets.push(...resolved.targets);
951
+ resolved.plain.forEach((target) => plain.add(target));
937
952
  } else {
938
953
  targets.push([...ownerPath, ...segments.map(toPathSegment)]);
939
954
  }
@@ -947,7 +962,8 @@ function applyPatch(root, index, patch, doc, result) {
947
962
  }
948
963
  if (patch.type === "field") {
949
964
  for (const target of targets) {
950
- let value = keepEditLink(readAtPath(root, target), patch.value);
965
+ const pushed = plain.has(target) && typeof patch.value === "string" ? plainTextFromHtml(patch.value) : patch.value;
966
+ let value = keepEditLink(readAtPath(root, target), pushed);
951
967
  if (patch.edit && typeof value === "string" && !(0, import_stega2.vercelStegaSplit)(value).encoded) {
952
968
  value = editLinksFor(result, patch.edit.item)?.encode(
953
969
  value,
@@ -1011,9 +1027,10 @@ function resolveTargets(root, doc, ownerPath, segments) {
1011
1027
  owner = owner[step];
1012
1028
  }
1013
1029
  const selections = selectionsAt(root, doc, ownerPath);
1014
- if (!selections) return { root, targets: [] };
1030
+ if (!selections) return { root, targets: [], plain: /* @__PURE__ */ new Set() };
1015
1031
  let current = root;
1016
1032
  const out = [];
1033
+ const plain = /* @__PURE__ */ new Set();
1017
1034
  const walk = (node, sel, i, path) => {
1018
1035
  if (i === segments.length) {
1019
1036
  out.push(path);
@@ -1034,12 +1051,15 @@ function resolveTargets(root, doc, ownerPath, segments) {
1034
1051
  if (node === null || typeof node !== "object") return;
1035
1052
  const record = node;
1036
1053
  const wanted = graphqlFieldName(segment);
1054
+ const textBody = i === segments.length - 1 && segment === "body" && isTextEntry(record) ? TEXT_BODY_FIELDS : null;
1037
1055
  let matched = false;
1038
1056
  for (const field of collectFields(sel, typenameOf(node), doc).values()) {
1039
- if (field.name !== segment && field.name !== wanted) continue;
1057
+ const alias = textBody?.find((f) => f.name === field.name);
1058
+ if (field.name !== segment && field.name !== wanted && !alias) continue;
1040
1059
  if (!Object.prototype.hasOwnProperty.call(record, field.key)) continue;
1041
1060
  matched = true;
1042
1061
  const fieldPath = [...path, field.key];
1062
+ if (alias?.plain) plain.add(fieldPath);
1043
1063
  let value = record[field.key];
1044
1064
  const next = segments[i + 1];
1045
1065
  if (value === null && field.selections.length && next !== void 0 && next !== "items" && !INDEX_SEGMENT.test(next)) {
@@ -1062,7 +1082,7 @@ function resolveTargets(root, doc, ownerPath, segments) {
1062
1082
  if (!matched && segment === "items") walk(node, sel, i + 1, path);
1063
1083
  };
1064
1084
  walk(owner, selections, 0, ownerPath);
1065
- return { root: current, targets: out };
1085
+ return { root: current, targets: out, plain };
1066
1086
  }
1067
1087
  var NON_ALPHANUMERIC = /[^a-z0-9]/gi;
1068
1088
  var typeKey = (name) => name.replace(NON_ALPHANUMERIC, "").toLowerCase();
@@ -311,6 +311,8 @@ interface LivePreviewConfig {
311
311
  interface PreprRefreshProps {
312
312
  /** Pass your preview flag; never `true` on a production deployment. */
313
313
  enabled?: boolean;
314
+ /** Exact editor origins, replacing the `*.prepr.io` default. */
315
+ allowedEditorOrigins?: string[];
314
316
  /** Your preview token uses GraphQL strict mode; see the toolbar option. */
315
317
  strictMode?: boolean;
316
318
  }