@preprio/toolkit 0.5.0-rc.4 → 0.5.0-rc.6

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 (45) hide show
  1. package/README.md +337 -165
  2. package/dist/astro/index.cjs +126 -30
  3. package/dist/astro/index.js +130 -30
  4. package/dist/{chunk-TG6N3C22.js → chunk-IPMB32AZ.js} +1 -1
  5. package/dist/{chunk-74KY5EAM.js → chunk-KD3GK6TO.js} +2 -0
  6. package/dist/{chunk-AHBN6FQP.js → chunk-KZIRM54F.js} +1 -1
  7. package/dist/{chunk-PDNCNTDB.js → chunk-L3SDL6MP.js} +11 -3
  8. package/dist/{chunk-46ISDRHT.js → chunk-WHZNCYUS.js} +1 -1
  9. package/dist/codegen/index.cjs +79 -0
  10. package/dist/codegen/index.d.cts +46 -0
  11. package/dist/codegen/index.d.ts +46 -0
  12. package/dist/codegen/index.js +62 -0
  13. package/dist/index.cjs +133 -28
  14. package/dist/index.d.cts +14 -2
  15. package/dist/index.d.ts +14 -2
  16. package/dist/index.js +108 -6
  17. package/dist/{live-preview-H4643QYF.js → live-preview-DLXGXRE5.js} +2 -2
  18. package/dist/nextjs/components.cjs +11 -3
  19. package/dist/nextjs/components.js +2 -2
  20. package/dist/nextjs/index.cjs +124 -28
  21. package/dist/nextjs/index.d.cts +2 -0
  22. package/dist/nextjs/index.d.ts +2 -0
  23. package/dist/nextjs/index.js +128 -28
  24. package/dist/nextjs/live-action.js +3 -3
  25. package/dist/nextjs/live.cjs +4 -1
  26. package/dist/nextjs/live.d.cts +3 -1
  27. package/dist/nextjs/live.d.ts +3 -1
  28. package/dist/nextjs/live.js +5 -2
  29. package/dist/nuxt/chunk-BWPGO25E.js +340 -0
  30. package/dist/nuxt/index.cjs +1 -1
  31. package/dist/nuxt/index.js +1 -1
  32. package/dist/nuxt/{live-preview-O2ZTJNW4.js → live-preview-2RCU35W5.js} +6 -337
  33. package/dist/nuxt/live.cjs +1007 -911
  34. package/dist/nuxt/live.js +109 -5
  35. package/dist/react/components.cjs +11 -3
  36. package/dist/react/components.js +11 -3
  37. package/dist/sveltekit/chunk-BWPGO25E.js +340 -0
  38. package/dist/sveltekit/index.cjs +1 -1
  39. package/dist/sveltekit/index.js +1 -1
  40. package/dist/sveltekit/live-preview-2RCU35W5.js +1189 -0
  41. package/dist/sveltekit/live.cjs +1830 -0
  42. package/dist/sveltekit/live.d.cts +59 -0
  43. package/dist/sveltekit/live.d.ts +59 -0
  44. package/dist/sveltekit/live.js +204 -0
  45. package/package.json +16 -1
@@ -31,7 +31,7 @@ __export(astro_exports, {
31
31
  module.exports = __toCommonJS(astro_exports);
32
32
 
33
33
  // src/version.ts
34
- var VERSION = "0.5.0-rc.4";
34
+ var VERSION = "0.5.0-rc.6";
35
35
 
36
36
  // src/core/features.ts
37
37
  function isEnabled(config) {
@@ -430,14 +430,14 @@ function indexSnapshot(data) {
430
430
  const index = /* @__PURE__ */ new Map();
431
431
  const visited = /* @__PURE__ */ new WeakSet();
432
432
  const path = [];
433
- function walk(node) {
433
+ function walk2(node) {
434
434
  if (node === null || typeof node !== "object") return;
435
435
  if (visited.has(node)) return;
436
436
  visited.add(node);
437
437
  if (Array.isArray(node)) {
438
438
  for (let i = 0; i < node.length; i++) {
439
439
  path.push(i);
440
- walk(node[i]);
440
+ walk2(node[i]);
441
441
  path.pop();
442
442
  }
443
443
  return;
@@ -455,11 +455,11 @@ function indexSnapshot(data) {
455
455
  for (const key in record) {
456
456
  if (!Object.prototype.hasOwnProperty.call(record, key)) continue;
457
457
  path.push(key);
458
- walk(record[key]);
458
+ walk2(record[key]);
459
459
  path.pop();
460
460
  }
461
461
  }
462
- walk(data);
462
+ walk2(data);
463
463
  return index;
464
464
  }
465
465
 
@@ -916,12 +916,12 @@ function resolveFields(selections, typename, doc, options) {
916
916
  }
917
917
  };
918
918
  const applies = (on, list) => conditionMatches(on, typename) || typename !== void 0 && typeConditions(list, doc).includes(typename);
919
- const walk = (list, matched) => {
919
+ const walk2 = (list, matched) => {
920
920
  for (const s of list) {
921
921
  if (s.kind === "field") {
922
922
  add(matched ? exact : loose, s);
923
923
  } else if (s.kind === "inline") {
924
- walk(s.selections, matched && applies(s.on, s.selections));
924
+ walk2(s.selections, matched && applies(s.on, s.selections));
925
925
  } else {
926
926
  const fragment = doc.fragments.get(s.name);
927
927
  if (!fragment) continue;
@@ -929,11 +929,11 @@ function resolveFields(selections, typename, doc, options) {
929
929
  if (walkedMatched.has(fragment)) continue;
930
930
  if (!asMatched && walkedLoose.has(fragment)) continue;
931
931
  (asMatched ? walkedMatched : walkedLoose).add(fragment);
932
- walk(fragment.selections, asMatched);
932
+ walk2(fragment.selections, asMatched);
933
933
  }
934
934
  }
935
935
  };
936
- walk(selections, true);
936
+ walk2(selections, true);
937
937
  if (!options.strict) {
938
938
  for (const [key, field] of loose) {
939
939
  if (!exact.has(key)) exact.set(key, field);
@@ -950,21 +950,21 @@ function typeConditions(selections, doc) {
950
950
  if (hit) return hit;
951
951
  const names = /* @__PURE__ */ new Set();
952
952
  const seen = /* @__PURE__ */ new Set();
953
- const walk = (list) => {
953
+ const walk2 = (list) => {
954
954
  for (const s of list) {
955
955
  if (s.kind === "inline") {
956
956
  if (s.on) names.add(s.on);
957
- walk(s.selections);
957
+ walk2(s.selections);
958
958
  } else if (s.kind === "spread") {
959
959
  const fragment = doc.fragments.get(s.name);
960
960
  if (!fragment || seen.has(fragment)) continue;
961
961
  seen.add(fragment);
962
962
  names.add(fragment.on);
963
- walk(fragment.selections);
963
+ walk2(fragment.selections);
964
964
  }
965
965
  }
966
966
  };
967
- walk(selections);
967
+ walk2(selections);
968
968
  const conditions = [...names];
969
969
  conditionsCache.set(selections, conditions);
970
970
  return conditions;
@@ -1259,7 +1259,7 @@ function resolveTargets(root, doc, ownerPath, segments) {
1259
1259
  let current = root;
1260
1260
  const out = [];
1261
1261
  const plain = /* @__PURE__ */ new Set();
1262
- const walk = (node, sel, i, path) => {
1262
+ const walk2 = (node, sel, i, path) => {
1263
1263
  if (i === segments.length) {
1264
1264
  out.push(path);
1265
1265
  return;
@@ -1269,10 +1269,10 @@ function resolveTargets(root, doc, ownerPath, segments) {
1269
1269
  if (INDEX_SEGMENT.test(segment)) {
1270
1270
  const position = Number(segment);
1271
1271
  if (position < node.length) {
1272
- walk(node[position], sel, i + 1, [...path, position]);
1272
+ walk2(node[position], sel, i + 1, [...path, position]);
1273
1273
  }
1274
1274
  } else if (segment === "items") {
1275
- walk(node, sel, i + 1, path);
1275
+ walk2(node, sel, i + 1, path);
1276
1276
  }
1277
1277
  return;
1278
1278
  }
@@ -1305,11 +1305,11 @@ function resolveTargets(root, doc, ownerPath, segments) {
1305
1305
  current = writeAtPath(current, fieldPath, value);
1306
1306
  }
1307
1307
  }
1308
- walk(value, field.selections, i + 1, fieldPath);
1308
+ walk2(value, field.selections, i + 1, fieldPath);
1309
1309
  }
1310
- if (!matched && segment === "items") walk(node, sel, i + 1, path);
1310
+ if (!matched && segment === "items") walk2(node, sel, i + 1, path);
1311
1311
  };
1312
- walk(owner, selections, 0, ownerPath);
1312
+ walk2(owner, selections, 0, ownerPath);
1313
1313
  return { root: current, targets: out, plain };
1314
1314
  }
1315
1315
  var NON_ALPHANUMERIC = /[^a-z0-9]/gi;
@@ -1432,11 +1432,11 @@ function listKeysIn(result) {
1432
1432
  if (!byType) {
1433
1433
  byType = /* @__PURE__ */ new Map();
1434
1434
  const seen = /* @__PURE__ */ new WeakSet();
1435
- const walk = (node) => {
1435
+ const walk2 = (node) => {
1436
1436
  if (node === null || typeof node !== "object" || seen.has(node)) return;
1437
1437
  seen.add(node);
1438
1438
  if (Array.isArray(node)) {
1439
- node.forEach(walk);
1439
+ node.forEach(walk2);
1440
1440
  return;
1441
1441
  }
1442
1442
  const record = node;
@@ -1447,10 +1447,10 @@ function listKeysIn(result) {
1447
1447
  if (!keys) byType.set(type, keys = /* @__PURE__ */ new Set());
1448
1448
  keys.add(key);
1449
1449
  }
1450
- walk(value);
1450
+ walk2(value);
1451
1451
  }
1452
1452
  };
1453
- walk(result);
1453
+ walk2(result);
1454
1454
  listKeysCache.set(result, byType);
1455
1455
  }
1456
1456
  return byType.get(typename) ?? NO_KEYS;
@@ -1492,7 +1492,7 @@ function findEditLink(root) {
1492
1492
  if (linkCache.has(root)) return linkCache.get(root) ?? null;
1493
1493
  let found = null;
1494
1494
  const seen = /* @__PURE__ */ new WeakSet();
1495
- const walk = (node) => {
1495
+ const walk2 = (node) => {
1496
1496
  if (found) return;
1497
1497
  if (typeof node === "string") {
1498
1498
  if (!(0, import_stega2.vercelStegaSplit)(node).encoded) return;
@@ -1507,9 +1507,9 @@ function findEditLink(root) {
1507
1507
  }
1508
1508
  if (node === null || typeof node !== "object" || seen.has(node)) return;
1509
1509
  seen.add(node);
1510
- for (const value of Object.values(node)) walk(value);
1510
+ for (const value of Object.values(node)) walk2(value);
1511
1511
  };
1512
- walk(root);
1512
+ walk2(root);
1513
1513
  linkCache.set(root, found);
1514
1514
  return found;
1515
1515
  }
@@ -1535,6 +1535,101 @@ async function readLiveLogFromRequest(request) {
1535
1535
  }
1536
1536
  }
1537
1537
 
1538
+ // src/core/live-preview/edit-links.ts
1539
+ var import_stega3 = require("@vercel/stega");
1540
+ var ENTRY_PARAM = "entry";
1541
+ var TOP_LEVEL_ENTRY = /^[A-Za-z0-9_]+\.\d+$/;
1542
+ function entryIdOf(element) {
1543
+ if (!isRecord(element)) return void 0;
1544
+ if (typeof element._id === "string") return element._id;
1545
+ if (element.__typename !== "Assets" || !Array.isArray(element.items)) {
1546
+ return void 0;
1547
+ }
1548
+ const first = element.items[0];
1549
+ return isRecord(first) && typeof first._id === "string" ? first._id : void 0;
1550
+ }
1551
+ function isRecord(value) {
1552
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1553
+ }
1554
+ function annotate(value, ctx) {
1555
+ if (!ctx.entryId) return value;
1556
+ const { cleaned, encoded } = (0, import_stega3.vercelStegaSplit)(value);
1557
+ if (!encoded) return value;
1558
+ let payload;
1559
+ try {
1560
+ payload = (0, import_stega3.vercelStegaDecode)(encoded);
1561
+ } catch {
1562
+ return value;
1563
+ }
1564
+ if (typeof payload?.href !== "string") return value;
1565
+ let url;
1566
+ try {
1567
+ url = new URL(payload.href);
1568
+ } catch {
1569
+ return value;
1570
+ }
1571
+ if (url.searchParams.has(ENTRY_PARAM)) return value;
1572
+ url.searchParams.set(ENTRY_PARAM, ctx.entryId);
1573
+ const itemId = decodeURIComponent(url.pathname.split("/").pop() ?? "");
1574
+ if (!url.searchParams.has("field") && ctx.entryField && TOP_LEVEL_ENTRY.test(ctx.entryField) && itemId === ctx.entryOwnerId) {
1575
+ url.searchParams.set("field", ctx.entryField);
1576
+ }
1577
+ return (0, import_stega3.vercelStegaCombine)(
1578
+ cleaned,
1579
+ { ...payload, href: url.toString() },
1580
+ false
1581
+ );
1582
+ }
1583
+ function walk(value, selections, ctx) {
1584
+ if (typeof value === "string") return annotate(value, ctx);
1585
+ if (Array.isArray(value)) {
1586
+ let changed2 = false;
1587
+ const next2 = value.map((element, index) => {
1588
+ const path = [...ctx.path, String(index)];
1589
+ const entryId = ctx.inAssets ? void 0 : entryIdOf(element);
1590
+ const entry = entryId ? {
1591
+ entryId,
1592
+ entryField: ctx.ownerId ? path.join(".") : void 0,
1593
+ entryOwnerId: ctx.ownerId,
1594
+ inAssets: isRecord(element) && element._id === void 0
1595
+ } : {};
1596
+ const out = walk(element, selections, { ...ctx, ...entry, path });
1597
+ if (out !== element) changed2 = true;
1598
+ return out;
1599
+ });
1600
+ return changed2 ? next2 : value;
1601
+ }
1602
+ if (!isRecord(value)) return value;
1603
+ const id = typeof value._id === "string" ? value._id : void 0;
1604
+ const typename = typeof value.__typename === "string" ? value.__typename : void 0;
1605
+ const fields = ctx.doc && selections ? collectFields(selections, typename, ctx.doc) : null;
1606
+ let changed = false;
1607
+ const next = {};
1608
+ for (const [key, child] of Object.entries(value)) {
1609
+ const field = fields?.get(key);
1610
+ const name = field?.name ?? key;
1611
+ const out = walk(child, field?.selections ?? null, {
1612
+ ...ctx,
1613
+ ownerId: id ?? ctx.ownerId,
1614
+ path: id ? [name] : [...ctx.path, name]
1615
+ });
1616
+ if (out !== child) changed = true;
1617
+ next[key] = out;
1618
+ }
1619
+ return changed ? next : value;
1620
+ }
1621
+ function annotateEditLinks(result, query, operationName) {
1622
+ let doc = null;
1623
+ if (query !== void 0) {
1624
+ try {
1625
+ doc = readQueryDocument(query, operationName);
1626
+ } catch {
1627
+ doc = null;
1628
+ }
1629
+ }
1630
+ return walk(result, doc?.operation ?? null, { doc, path: [] });
1631
+ }
1632
+
1538
1633
  // src/astro/index.ts
1539
1634
  var LIVE_LOG = /* @__PURE__ */ Symbol.for("@preprio/toolkit/astro-live-log");
1540
1635
  async function onPreprRequest(context, next, options) {
@@ -1575,10 +1670,11 @@ async function getToolbarProps(headers, token, features) {
1575
1670
  return getToolbarPropsFromHeaders(headers, token, features);
1576
1671
  }
1577
1672
  function normalizeQuery2(query, result, options = {}) {
1578
- if (!options.enabled || !options.locals) return result;
1579
- const log = options.locals[LIVE_LOG];
1580
- if (!log?.length) return result;
1581
- return normalizeQuery(query, result, {
1673
+ if (!options.enabled) return result;
1674
+ const annotated = annotateEditLinks(result, query, options.operationName);
1675
+ const log = options.locals?.[LIVE_LOG];
1676
+ if (!log?.length) return annotated;
1677
+ return normalizeQuery(query, annotated, {
1582
1678
  log,
1583
1679
  operationName: options.operationName
1584
1680
  });
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var VERSION = "0.5.0-rc.4";
2
+ var VERSION = "0.5.0-rc.6";
3
3
 
4
4
  // src/core/features.ts
5
5
  function isEnabled(config) {
@@ -402,14 +402,14 @@ function indexSnapshot(data) {
402
402
  const index = /* @__PURE__ */ new Map();
403
403
  const visited = /* @__PURE__ */ new WeakSet();
404
404
  const path = [];
405
- function walk(node) {
405
+ function walk2(node) {
406
406
  if (node === null || typeof node !== "object") return;
407
407
  if (visited.has(node)) return;
408
408
  visited.add(node);
409
409
  if (Array.isArray(node)) {
410
410
  for (let i = 0; i < node.length; i++) {
411
411
  path.push(i);
412
- walk(node[i]);
412
+ walk2(node[i]);
413
413
  path.pop();
414
414
  }
415
415
  return;
@@ -427,11 +427,11 @@ function indexSnapshot(data) {
427
427
  for (const key in record) {
428
428
  if (!Object.prototype.hasOwnProperty.call(record, key)) continue;
429
429
  path.push(key);
430
- walk(record[key]);
430
+ walk2(record[key]);
431
431
  path.pop();
432
432
  }
433
433
  }
434
- walk(data);
434
+ walk2(data);
435
435
  return index;
436
436
  }
437
437
 
@@ -888,12 +888,12 @@ function resolveFields(selections, typename, doc, options) {
888
888
  }
889
889
  };
890
890
  const applies = (on, list) => conditionMatches(on, typename) || typename !== void 0 && typeConditions(list, doc).includes(typename);
891
- const walk = (list, matched) => {
891
+ const walk2 = (list, matched) => {
892
892
  for (const s of list) {
893
893
  if (s.kind === "field") {
894
894
  add(matched ? exact : loose, s);
895
895
  } else if (s.kind === "inline") {
896
- walk(s.selections, matched && applies(s.on, s.selections));
896
+ walk2(s.selections, matched && applies(s.on, s.selections));
897
897
  } else {
898
898
  const fragment = doc.fragments.get(s.name);
899
899
  if (!fragment) continue;
@@ -901,11 +901,11 @@ function resolveFields(selections, typename, doc, options) {
901
901
  if (walkedMatched.has(fragment)) continue;
902
902
  if (!asMatched && walkedLoose.has(fragment)) continue;
903
903
  (asMatched ? walkedMatched : walkedLoose).add(fragment);
904
- walk(fragment.selections, asMatched);
904
+ walk2(fragment.selections, asMatched);
905
905
  }
906
906
  }
907
907
  };
908
- walk(selections, true);
908
+ walk2(selections, true);
909
909
  if (!options.strict) {
910
910
  for (const [key, field] of loose) {
911
911
  if (!exact.has(key)) exact.set(key, field);
@@ -922,21 +922,21 @@ function typeConditions(selections, doc) {
922
922
  if (hit) return hit;
923
923
  const names = /* @__PURE__ */ new Set();
924
924
  const seen = /* @__PURE__ */ new Set();
925
- const walk = (list) => {
925
+ const walk2 = (list) => {
926
926
  for (const s of list) {
927
927
  if (s.kind === "inline") {
928
928
  if (s.on) names.add(s.on);
929
- walk(s.selections);
929
+ walk2(s.selections);
930
930
  } else if (s.kind === "spread") {
931
931
  const fragment = doc.fragments.get(s.name);
932
932
  if (!fragment || seen.has(fragment)) continue;
933
933
  seen.add(fragment);
934
934
  names.add(fragment.on);
935
- walk(fragment.selections);
935
+ walk2(fragment.selections);
936
936
  }
937
937
  }
938
938
  };
939
- walk(selections);
939
+ walk2(selections);
940
940
  const conditions = [...names];
941
941
  conditionsCache.set(selections, conditions);
942
942
  return conditions;
@@ -1231,7 +1231,7 @@ function resolveTargets(root, doc, ownerPath, segments) {
1231
1231
  let current = root;
1232
1232
  const out = [];
1233
1233
  const plain = /* @__PURE__ */ new Set();
1234
- const walk = (node, sel, i, path) => {
1234
+ const walk2 = (node, sel, i, path) => {
1235
1235
  if (i === segments.length) {
1236
1236
  out.push(path);
1237
1237
  return;
@@ -1241,10 +1241,10 @@ function resolveTargets(root, doc, ownerPath, segments) {
1241
1241
  if (INDEX_SEGMENT.test(segment)) {
1242
1242
  const position = Number(segment);
1243
1243
  if (position < node.length) {
1244
- walk(node[position], sel, i + 1, [...path, position]);
1244
+ walk2(node[position], sel, i + 1, [...path, position]);
1245
1245
  }
1246
1246
  } else if (segment === "items") {
1247
- walk(node, sel, i + 1, path);
1247
+ walk2(node, sel, i + 1, path);
1248
1248
  }
1249
1249
  return;
1250
1250
  }
@@ -1277,11 +1277,11 @@ function resolveTargets(root, doc, ownerPath, segments) {
1277
1277
  current = writeAtPath(current, fieldPath, value);
1278
1278
  }
1279
1279
  }
1280
- walk(value, field.selections, i + 1, fieldPath);
1280
+ walk2(value, field.selections, i + 1, fieldPath);
1281
1281
  }
1282
- if (!matched && segment === "items") walk(node, sel, i + 1, path);
1282
+ if (!matched && segment === "items") walk2(node, sel, i + 1, path);
1283
1283
  };
1284
- walk(owner, selections, 0, ownerPath);
1284
+ walk2(owner, selections, 0, ownerPath);
1285
1285
  return { root: current, targets: out, plain };
1286
1286
  }
1287
1287
  var NON_ALPHANUMERIC = /[^a-z0-9]/gi;
@@ -1404,11 +1404,11 @@ function listKeysIn(result) {
1404
1404
  if (!byType) {
1405
1405
  byType = /* @__PURE__ */ new Map();
1406
1406
  const seen = /* @__PURE__ */ new WeakSet();
1407
- const walk = (node) => {
1407
+ const walk2 = (node) => {
1408
1408
  if (node === null || typeof node !== "object" || seen.has(node)) return;
1409
1409
  seen.add(node);
1410
1410
  if (Array.isArray(node)) {
1411
- node.forEach(walk);
1411
+ node.forEach(walk2);
1412
1412
  return;
1413
1413
  }
1414
1414
  const record = node;
@@ -1419,10 +1419,10 @@ function listKeysIn(result) {
1419
1419
  if (!keys) byType.set(type, keys = /* @__PURE__ */ new Set());
1420
1420
  keys.add(key);
1421
1421
  }
1422
- walk(value);
1422
+ walk2(value);
1423
1423
  }
1424
1424
  };
1425
- walk(result);
1425
+ walk2(result);
1426
1426
  listKeysCache.set(result, byType);
1427
1427
  }
1428
1428
  return byType.get(typename) ?? NO_KEYS;
@@ -1464,7 +1464,7 @@ function findEditLink(root) {
1464
1464
  if (linkCache.has(root)) return linkCache.get(root) ?? null;
1465
1465
  let found = null;
1466
1466
  const seen = /* @__PURE__ */ new WeakSet();
1467
- const walk = (node) => {
1467
+ const walk2 = (node) => {
1468
1468
  if (found) return;
1469
1469
  if (typeof node === "string") {
1470
1470
  if (!vercelStegaSplit2(node).encoded) return;
@@ -1479,9 +1479,9 @@ function findEditLink(root) {
1479
1479
  }
1480
1480
  if (node === null || typeof node !== "object" || seen.has(node)) return;
1481
1481
  seen.add(node);
1482
- for (const value of Object.values(node)) walk(value);
1482
+ for (const value of Object.values(node)) walk2(value);
1483
1483
  };
1484
- walk(root);
1484
+ walk2(root);
1485
1485
  linkCache.set(root, found);
1486
1486
  return found;
1487
1487
  }
@@ -1507,6 +1507,105 @@ async function readLiveLogFromRequest(request) {
1507
1507
  }
1508
1508
  }
1509
1509
 
1510
+ // src/core/live-preview/edit-links.ts
1511
+ import {
1512
+ vercelStegaCombine as vercelStegaCombine2,
1513
+ vercelStegaDecode as vercelStegaDecode2,
1514
+ vercelStegaSplit as vercelStegaSplit3
1515
+ } from "@vercel/stega";
1516
+ var ENTRY_PARAM = "entry";
1517
+ var TOP_LEVEL_ENTRY = /^[A-Za-z0-9_]+\.\d+$/;
1518
+ function entryIdOf(element) {
1519
+ if (!isRecord(element)) return void 0;
1520
+ if (typeof element._id === "string") return element._id;
1521
+ if (element.__typename !== "Assets" || !Array.isArray(element.items)) {
1522
+ return void 0;
1523
+ }
1524
+ const first = element.items[0];
1525
+ return isRecord(first) && typeof first._id === "string" ? first._id : void 0;
1526
+ }
1527
+ function isRecord(value) {
1528
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1529
+ }
1530
+ function annotate(value, ctx) {
1531
+ if (!ctx.entryId) return value;
1532
+ const { cleaned, encoded } = vercelStegaSplit3(value);
1533
+ if (!encoded) return value;
1534
+ let payload;
1535
+ try {
1536
+ payload = vercelStegaDecode2(encoded);
1537
+ } catch {
1538
+ return value;
1539
+ }
1540
+ if (typeof payload?.href !== "string") return value;
1541
+ let url;
1542
+ try {
1543
+ url = new URL(payload.href);
1544
+ } catch {
1545
+ return value;
1546
+ }
1547
+ if (url.searchParams.has(ENTRY_PARAM)) return value;
1548
+ url.searchParams.set(ENTRY_PARAM, ctx.entryId);
1549
+ const itemId = decodeURIComponent(url.pathname.split("/").pop() ?? "");
1550
+ if (!url.searchParams.has("field") && ctx.entryField && TOP_LEVEL_ENTRY.test(ctx.entryField) && itemId === ctx.entryOwnerId) {
1551
+ url.searchParams.set("field", ctx.entryField);
1552
+ }
1553
+ return vercelStegaCombine2(
1554
+ cleaned,
1555
+ { ...payload, href: url.toString() },
1556
+ false
1557
+ );
1558
+ }
1559
+ function walk(value, selections, ctx) {
1560
+ if (typeof value === "string") return annotate(value, ctx);
1561
+ if (Array.isArray(value)) {
1562
+ let changed2 = false;
1563
+ const next2 = value.map((element, index) => {
1564
+ const path = [...ctx.path, String(index)];
1565
+ const entryId = ctx.inAssets ? void 0 : entryIdOf(element);
1566
+ const entry = entryId ? {
1567
+ entryId,
1568
+ entryField: ctx.ownerId ? path.join(".") : void 0,
1569
+ entryOwnerId: ctx.ownerId,
1570
+ inAssets: isRecord(element) && element._id === void 0
1571
+ } : {};
1572
+ const out = walk(element, selections, { ...ctx, ...entry, path });
1573
+ if (out !== element) changed2 = true;
1574
+ return out;
1575
+ });
1576
+ return changed2 ? next2 : value;
1577
+ }
1578
+ if (!isRecord(value)) return value;
1579
+ const id = typeof value._id === "string" ? value._id : void 0;
1580
+ const typename = typeof value.__typename === "string" ? value.__typename : void 0;
1581
+ const fields = ctx.doc && selections ? collectFields(selections, typename, ctx.doc) : null;
1582
+ let changed = false;
1583
+ const next = {};
1584
+ for (const [key, child] of Object.entries(value)) {
1585
+ const field = fields?.get(key);
1586
+ const name = field?.name ?? key;
1587
+ const out = walk(child, field?.selections ?? null, {
1588
+ ...ctx,
1589
+ ownerId: id ?? ctx.ownerId,
1590
+ path: id ? [name] : [...ctx.path, name]
1591
+ });
1592
+ if (out !== child) changed = true;
1593
+ next[key] = out;
1594
+ }
1595
+ return changed ? next : value;
1596
+ }
1597
+ function annotateEditLinks(result, query, operationName) {
1598
+ let doc = null;
1599
+ if (query !== void 0) {
1600
+ try {
1601
+ doc = readQueryDocument(query, operationName);
1602
+ } catch {
1603
+ doc = null;
1604
+ }
1605
+ }
1606
+ return walk(result, doc?.operation ?? null, { doc, path: [] });
1607
+ }
1608
+
1510
1609
  // src/astro/index.ts
1511
1610
  var LIVE_LOG = /* @__PURE__ */ Symbol.for("@preprio/toolkit/astro-live-log");
1512
1611
  async function onPreprRequest(context, next, options) {
@@ -1547,10 +1646,11 @@ async function getToolbarProps(headers, token, features) {
1547
1646
  return getToolbarPropsFromHeaders(headers, token, features);
1548
1647
  }
1549
1648
  function normalizeQuery2(query, result, options = {}) {
1550
- if (!options.enabled || !options.locals) return result;
1551
- const log = options.locals[LIVE_LOG];
1552
- if (!log?.length) return result;
1553
- return normalizeQuery(query, result, {
1649
+ if (!options.enabled) return result;
1650
+ const annotated = annotateEditLinks(result, query, options.operationName);
1651
+ const log = options.locals?.[LIVE_LOG];
1652
+ if (!log?.length) return annotated;
1653
+ return normalizeQuery(query, annotated, {
1554
1654
  log,
1555
1655
  operationName: options.operationName
1556
1656
  });
@@ -8,7 +8,7 @@ import {
8
8
  parseListEntries,
9
9
  patchSnapshot,
10
10
  syncListSnapshot
11
- } from "./chunk-74KY5EAM.js";
11
+ } from "./chunk-KD3GK6TO.js";
12
12
  import {
13
13
  createScopedLogger,
14
14
  getTrustedParentOrigin,
@@ -1210,6 +1210,8 @@ export {
1210
1210
  indexSnapshot,
1211
1211
  patchSnapshot,
1212
1212
  syncListSnapshot,
1213
+ readQueryDocument,
1214
+ collectFields,
1213
1215
  isLiveFieldChange,
1214
1216
  parseListEntries,
1215
1217
  parseEditTarget,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  VERSION,
3
3
  resolveFeatures
4
- } from "./chunk-46ISDRHT.js";
4
+ } from "./chunk-WHZNCYUS.js";
5
5
 
6
6
  // src/core/server.ts
7
7
  var PreprError = class extends Error {
@@ -2,7 +2,7 @@ import {
2
2
  ALL_FEATURES_ENABLED,
3
3
  VERSION,
4
4
  resolveFeatures
5
- } from "./chunk-46ISDRHT.js";
5
+ } from "./chunk-WHZNCYUS.js";
6
6
  import {
7
7
  createIframeBridge,
8
8
  isLocale,
@@ -480,6 +480,7 @@ function findFieldElement(lookup) {
480
480
 
481
481
  // src/core/stega/dom.ts
482
482
  var IGNORED_ANCESTORS = "script, style, noscript";
483
+ var AUTO_ENTRY_ATTR = "data-prepr-entry-auto";
483
484
  function isIgnoredTextNode(node) {
484
485
  if (node.parentElement?.closest(IGNORED_ANCESTORS)) return true;
485
486
  return !node.textContent?.trim();
@@ -513,7 +514,9 @@ function parseEditHref(href) {
513
514
  return {
514
515
  id: url.pathname.split("/").pop() || void 0,
515
516
  field: url.searchParams.get("field") || void 0,
516
- locale: url.searchParams.get("locale") || void 0
517
+ locale: url.searchParams.get("locale") || void 0,
518
+ // Added by the toolkit's `annotateEditLinks`, not by Prepr.
519
+ entry: url.searchParams.get("entry") || void 0
517
520
  };
518
521
  } catch {
519
522
  return {};
@@ -530,11 +533,16 @@ function tagEncodedElement(element, decoded) {
530
533
  element.setAttribute("data-prepr-encoded", "");
531
534
  element.setAttribute("data-prepr-href", decoded.href);
532
535
  element.setAttribute("data-prepr-origin", decoded.origin);
533
- const { id, field, locale } = parseEditHref(decoded.href);
536
+ const { id, field, locale, entry } = parseEditHref(decoded.href);
534
537
  setOrRemove(element, "data-prepr-id", id);
535
538
  const fieldHint = element.getAttribute("data-prepr-edit-target")?.trim() || void 0;
536
539
  setOrRemove(element, "data-prepr-field", field ?? fieldHint);
537
540
  setOrRemove(element, "data-prepr-locale", locale);
541
+ const siteEntry = element.hasAttribute("data-prepr-entry-id") && !element.hasAttribute(AUTO_ENTRY_ATTR);
542
+ if (!siteEntry) {
543
+ setOrRemove(element, "data-prepr-entry-id", entry);
544
+ setOrRemove(element, AUTO_ENTRY_ATTR, entry && "true");
545
+ }
538
546
  }
539
547
  function readEditPayload(element) {
540
548
  return {
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var VERSION = "0.5.0-rc.4";
2
+ var VERSION = "0.5.0-rc.6";
3
3
 
4
4
  // src/core/features.ts
5
5
  function isEnabled(config) {