@preprio/toolkit 0.5.0-rc.5 → 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.
- package/README.md +125 -26
- package/dist/astro/index.cjs +126 -30
- package/dist/astro/index.js +130 -30
- package/dist/{chunk-TG6N3C22.js → chunk-IPMB32AZ.js} +1 -1
- package/dist/{chunk-74KY5EAM.js → chunk-KD3GK6TO.js} +2 -0
- package/dist/{chunk-3X55JL52.js → chunk-KZIRM54F.js} +1 -1
- package/dist/{chunk-SBLZANL5.js → chunk-L3SDL6MP.js} +11 -3
- package/dist/{chunk-CMUFTCG3.js → chunk-WHZNCYUS.js} +1 -1
- package/dist/codegen/index.cjs +79 -0
- package/dist/codegen/index.d.cts +46 -0
- package/dist/codegen/index.d.ts +46 -0
- package/dist/codegen/index.js +62 -0
- package/dist/index.cjs +133 -28
- package/dist/index.d.cts +14 -2
- package/dist/index.d.ts +14 -2
- package/dist/index.js +108 -6
- package/dist/{live-preview-H4643QYF.js → live-preview-DLXGXRE5.js} +2 -2
- package/dist/nextjs/components.cjs +11 -3
- package/dist/nextjs/components.js +2 -2
- package/dist/nextjs/index.cjs +124 -28
- package/dist/nextjs/index.js +128 -28
- package/dist/nextjs/live-action.js +3 -3
- package/dist/nextjs/live.js +1 -1
- package/dist/nuxt/chunk-BWPGO25E.js +340 -0
- package/dist/nuxt/index.cjs +1 -1
- package/dist/nuxt/index.js +1 -1
- package/dist/nuxt/{live-preview-O2ZTJNW4.js → live-preview-2RCU35W5.js} +6 -337
- package/dist/nuxt/live.cjs +1007 -911
- package/dist/nuxt/live.js +109 -5
- package/dist/react/components.cjs +11 -3
- package/dist/react/components.js +11 -3
- package/dist/sveltekit/chunk-BWPGO25E.js +340 -0
- package/dist/sveltekit/index.cjs +1 -1
- package/dist/sveltekit/index.js +1 -1
- package/dist/sveltekit/{live-preview-O2ZTJNW4.js → live-preview-2RCU35W5.js} +6 -337
- package/dist/sveltekit/live.cjs +1008 -909
- package/dist/sveltekit/live.js +118 -11
- package/package.json +11 -1
package/dist/astro/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/version.ts
|
|
2
|
-
var VERSION = "0.5.0-rc.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
430
|
+
walk2(record[key]);
|
|
431
431
|
path.pop();
|
|
432
432
|
}
|
|
433
433
|
}
|
|
434
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
904
|
+
walk2(fragment.selections, asMatched);
|
|
905
905
|
}
|
|
906
906
|
}
|
|
907
907
|
};
|
|
908
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
935
|
+
walk2(fragment.selections);
|
|
936
936
|
}
|
|
937
937
|
}
|
|
938
938
|
};
|
|
939
|
-
|
|
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
|
|
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
|
-
|
|
1244
|
+
walk2(node[position], sel, i + 1, [...path, position]);
|
|
1245
1245
|
}
|
|
1246
1246
|
} else if (segment === "items") {
|
|
1247
|
-
|
|
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
|
-
|
|
1280
|
+
walk2(value, field.selections, i + 1, fieldPath);
|
|
1281
1281
|
}
|
|
1282
|
-
if (!matched && segment === "items")
|
|
1282
|
+
if (!matched && segment === "items") walk2(node, sel, i + 1, path);
|
|
1283
1283
|
};
|
|
1284
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
1422
|
+
walk2(value);
|
|
1423
1423
|
}
|
|
1424
1424
|
};
|
|
1425
|
-
|
|
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
|
|
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))
|
|
1482
|
+
for (const value of Object.values(node)) walk2(value);
|
|
1483
1483
|
};
|
|
1484
|
-
|
|
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
|
|
1551
|
-
const
|
|
1552
|
-
|
|
1553
|
-
|
|
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
|
});
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
ALL_FEATURES_ENABLED,
|
|
3
3
|
VERSION,
|
|
4
4
|
resolveFeatures
|
|
5
|
-
} from "./chunk-
|
|
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 {
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/codegen/index.ts
|
|
21
|
+
var codegen_exports = {};
|
|
22
|
+
__export(codegen_exports, {
|
|
23
|
+
addPreprIds: () => addPreprIds,
|
|
24
|
+
preprIds: () => preprIds
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(codegen_exports);
|
|
27
|
+
var import_graphql = require("graphql");
|
|
28
|
+
function field(name) {
|
|
29
|
+
return { kind: import_graphql.Kind.FIELD, name: { kind: import_graphql.Kind.NAME, value: name } };
|
|
30
|
+
}
|
|
31
|
+
function hasResponseKey(set, key) {
|
|
32
|
+
return set.selections.some(
|
|
33
|
+
(s) => s.kind === import_graphql.Kind.FIELD && (s.alias ?? s.name).value === key
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
function addPreprIds(document, schema) {
|
|
37
|
+
const roots = new Set(
|
|
38
|
+
[
|
|
39
|
+
schema.getQueryType(),
|
|
40
|
+
schema.getMutationType(),
|
|
41
|
+
schema.getSubscriptionType()
|
|
42
|
+
].filter(Boolean)
|
|
43
|
+
);
|
|
44
|
+
const typeInfo = new import_graphql.TypeInfo(schema);
|
|
45
|
+
return (0, import_graphql.visit)(
|
|
46
|
+
document,
|
|
47
|
+
(0, import_graphql.visitWithTypeInfo)(typeInfo, {
|
|
48
|
+
SelectionSet(node) {
|
|
49
|
+
const type = typeInfo.getParentType();
|
|
50
|
+
if (!type || !(0, import_graphql.isCompositeType)(type) || roots.has(type)) return;
|
|
51
|
+
const added = [];
|
|
52
|
+
if (((0, import_graphql.isObjectType)(type) || (0, import_graphql.isInterfaceType)(type)) && "_id" in type.getFields() && !hasResponseKey(node, "_id")) {
|
|
53
|
+
added.push(field("_id"));
|
|
54
|
+
}
|
|
55
|
+
if (!hasResponseKey(node, "__typename")) {
|
|
56
|
+
added.push(field("__typename"));
|
|
57
|
+
}
|
|
58
|
+
if (!added.length) return;
|
|
59
|
+
return { ...node, selections: [...added, ...node.selections] };
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
var preprIds = {
|
|
65
|
+
transform({
|
|
66
|
+
documents,
|
|
67
|
+
schema
|
|
68
|
+
}) {
|
|
69
|
+
const built = (0, import_graphql.buildASTSchema)(schema, { assumeValidSDL: true });
|
|
70
|
+
return documents.map(
|
|
71
|
+
(file) => file.document ? { ...file, document: addPreprIds(file.document, built) } : file
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
76
|
+
0 && (module.exports = {
|
|
77
|
+
addPreprIds,
|
|
78
|
+
preprIds
|
|
79
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { DocumentNode, GraphQLSchema } from 'graphql';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The slice of a GraphQL Codegen `DocumentFile` this transform touches,
|
|
5
|
+
* written out so the package needs no dependency on `@graphql-codegen/*`.
|
|
6
|
+
*/
|
|
7
|
+
interface CodegenDocumentFile {
|
|
8
|
+
document?: DocumentNode;
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Select `_id` and `__typename` on every level of a query that has them, so
|
|
13
|
+
* live preview and click-to-edit can find each item without you selecting
|
|
14
|
+
* them by hand.
|
|
15
|
+
*
|
|
16
|
+
* The schema decides where they go: `_id` only on types that have one
|
|
17
|
+
* (models and components, not collections like `Pages` or unions), and
|
|
18
|
+
* `__typename` on every object, interface and union below the root.
|
|
19
|
+
* Fields already selected are left as they are.
|
|
20
|
+
*/
|
|
21
|
+
declare function addPreprIds(document: DocumentNode, schema: GraphQLSchema): DocumentNode;
|
|
22
|
+
/**
|
|
23
|
+
* GraphQL Codegen document transform that runs `addPreprIds` on every
|
|
24
|
+
* document, so the generated documents and types include `_id` and
|
|
25
|
+
* `__typename` wherever the schema has them:
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* // codegen.ts
|
|
29
|
+
* import { preprIds } from '@preprio/toolkit/codegen';
|
|
30
|
+
*
|
|
31
|
+
* generates: {
|
|
32
|
+
* 'src/gql/': {
|
|
33
|
+
* preset: 'client',
|
|
34
|
+
* documentTransforms: [preprIds],
|
|
35
|
+
* },
|
|
36
|
+
* },
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
declare const preprIds: {
|
|
40
|
+
transform({ documents, schema, }: {
|
|
41
|
+
documents: CodegenDocumentFile[];
|
|
42
|
+
schema: DocumentNode;
|
|
43
|
+
}): CodegenDocumentFile[];
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export { type CodegenDocumentFile, addPreprIds, preprIds };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { DocumentNode, GraphQLSchema } from 'graphql';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The slice of a GraphQL Codegen `DocumentFile` this transform touches,
|
|
5
|
+
* written out so the package needs no dependency on `@graphql-codegen/*`.
|
|
6
|
+
*/
|
|
7
|
+
interface CodegenDocumentFile {
|
|
8
|
+
document?: DocumentNode;
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Select `_id` and `__typename` on every level of a query that has them, so
|
|
13
|
+
* live preview and click-to-edit can find each item without you selecting
|
|
14
|
+
* them by hand.
|
|
15
|
+
*
|
|
16
|
+
* The schema decides where they go: `_id` only on types that have one
|
|
17
|
+
* (models and components, not collections like `Pages` or unions), and
|
|
18
|
+
* `__typename` on every object, interface and union below the root.
|
|
19
|
+
* Fields already selected are left as they are.
|
|
20
|
+
*/
|
|
21
|
+
declare function addPreprIds(document: DocumentNode, schema: GraphQLSchema): DocumentNode;
|
|
22
|
+
/**
|
|
23
|
+
* GraphQL Codegen document transform that runs `addPreprIds` on every
|
|
24
|
+
* document, so the generated documents and types include `_id` and
|
|
25
|
+
* `__typename` wherever the schema has them:
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* // codegen.ts
|
|
29
|
+
* import { preprIds } from '@preprio/toolkit/codegen';
|
|
30
|
+
*
|
|
31
|
+
* generates: {
|
|
32
|
+
* 'src/gql/': {
|
|
33
|
+
* preset: 'client',
|
|
34
|
+
* documentTransforms: [preprIds],
|
|
35
|
+
* },
|
|
36
|
+
* },
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
declare const preprIds: {
|
|
40
|
+
transform({ documents, schema, }: {
|
|
41
|
+
documents: CodegenDocumentFile[];
|
|
42
|
+
schema: DocumentNode;
|
|
43
|
+
}): CodegenDocumentFile[];
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export { type CodegenDocumentFile, addPreprIds, preprIds };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// src/codegen/index.ts
|
|
2
|
+
import {
|
|
3
|
+
buildASTSchema,
|
|
4
|
+
isCompositeType,
|
|
5
|
+
isInterfaceType,
|
|
6
|
+
isObjectType,
|
|
7
|
+
Kind,
|
|
8
|
+
TypeInfo,
|
|
9
|
+
visit,
|
|
10
|
+
visitWithTypeInfo
|
|
11
|
+
} from "graphql";
|
|
12
|
+
function field(name) {
|
|
13
|
+
return { kind: Kind.FIELD, name: { kind: Kind.NAME, value: name } };
|
|
14
|
+
}
|
|
15
|
+
function hasResponseKey(set, key) {
|
|
16
|
+
return set.selections.some(
|
|
17
|
+
(s) => s.kind === Kind.FIELD && (s.alias ?? s.name).value === key
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
function addPreprIds(document, schema) {
|
|
21
|
+
const roots = new Set(
|
|
22
|
+
[
|
|
23
|
+
schema.getQueryType(),
|
|
24
|
+
schema.getMutationType(),
|
|
25
|
+
schema.getSubscriptionType()
|
|
26
|
+
].filter(Boolean)
|
|
27
|
+
);
|
|
28
|
+
const typeInfo = new TypeInfo(schema);
|
|
29
|
+
return visit(
|
|
30
|
+
document,
|
|
31
|
+
visitWithTypeInfo(typeInfo, {
|
|
32
|
+
SelectionSet(node) {
|
|
33
|
+
const type = typeInfo.getParentType();
|
|
34
|
+
if (!type || !isCompositeType(type) || roots.has(type)) return;
|
|
35
|
+
const added = [];
|
|
36
|
+
if ((isObjectType(type) || isInterfaceType(type)) && "_id" in type.getFields() && !hasResponseKey(node, "_id")) {
|
|
37
|
+
added.push(field("_id"));
|
|
38
|
+
}
|
|
39
|
+
if (!hasResponseKey(node, "__typename")) {
|
|
40
|
+
added.push(field("__typename"));
|
|
41
|
+
}
|
|
42
|
+
if (!added.length) return;
|
|
43
|
+
return { ...node, selections: [...added, ...node.selections] };
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
var preprIds = {
|
|
49
|
+
transform({
|
|
50
|
+
documents,
|
|
51
|
+
schema
|
|
52
|
+
}) {
|
|
53
|
+
const built = buildASTSchema(schema, { assumeValidSDL: true });
|
|
54
|
+
return documents.map(
|
|
55
|
+
(file) => file.document ? { ...file, document: addPreprIds(file.document, built) } : file
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
export {
|
|
60
|
+
addPreprIds,
|
|
61
|
+
preprIds
|
|
62
|
+
};
|