@pro-laico/payload-dev-tools 0.0.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.
Files changed (91) hide show
  1. package/LICENSE.md +22 -0
  2. package/README.md +9 -0
  3. package/dist/components/DevToolbar.d.ts +27 -0
  4. package/dist/components/DevToolbar.d.ts.map +1 -0
  5. package/dist/components/DevToolbar.js +32 -0
  6. package/dist/components/DevToolbar.js.map +1 -0
  7. package/dist/components/DevToolbarClient.d.ts +16 -0
  8. package/dist/components/DevToolbarClient.d.ts.map +1 -0
  9. package/dist/components/DevToolbarClient.js +983 -0
  10. package/dist/components/DevToolbarClient.js.map +1 -0
  11. package/dist/components/resolveDevChrome.d.ts +33 -0
  12. package/dist/components/resolveDevChrome.d.ts.map +1 -0
  13. package/dist/components/resolveDevChrome.js +42 -0
  14. package/dist/components/resolveDevChrome.js.map +1 -0
  15. package/dist/components/resolveDevChrome.spec.d.ts +2 -0
  16. package/dist/components/resolveDevChrome.spec.d.ts.map +1 -0
  17. package/dist/components/resolveDevChrome.spec.js +98 -0
  18. package/dist/components/resolveDevChrome.spec.js.map +1 -0
  19. package/dist/components/styles.d.ts +5 -0
  20. package/dist/components/styles.d.ts.map +1 -0
  21. package/dist/components/styles.js +110 -0
  22. package/dist/components/styles.js.map +1 -0
  23. package/dist/cookies.d.ts +12 -0
  24. package/dist/cookies.d.ts.map +1 -0
  25. package/dist/cookies.js +12 -0
  26. package/dist/cookies.js.map +1 -0
  27. package/dist/endpoints/activateIconSet.d.ts +10 -0
  28. package/dist/endpoints/activateIconSet.d.ts.map +1 -0
  29. package/dist/endpoints/activateIconSet.js +55 -0
  30. package/dist/endpoints/activateIconSet.js.map +1 -0
  31. package/dist/endpoints/dev.d.ts +12 -0
  32. package/dist/endpoints/dev.d.ts.map +1 -0
  33. package/dist/endpoints/dev.js +31 -0
  34. package/dist/endpoints/dev.js.map +1 -0
  35. package/dist/endpoints/stage.d.ts +14 -0
  36. package/dist/endpoints/stage.d.ts.map +1 -0
  37. package/dist/endpoints/stage.js +42 -0
  38. package/dist/endpoints/stage.js.map +1 -0
  39. package/dist/harness.d.ts +40 -0
  40. package/dist/harness.d.ts.map +1 -0
  41. package/dist/harness.js +30 -0
  42. package/dist/harness.js.map +1 -0
  43. package/dist/index.d.ts +7 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +9 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/lib/getPayloadClient.d.ts +15 -0
  48. package/dist/lib/getPayloadClient.d.ts.map +1 -0
  49. package/dist/lib/getPayloadClient.js +29 -0
  50. package/dist/lib/getPayloadClient.js.map +1 -0
  51. package/dist/lib/snapshot.d.ts +89 -0
  52. package/dist/lib/snapshot.d.ts.map +1 -0
  53. package/dist/lib/snapshot.js +183 -0
  54. package/dist/lib/snapshot.js.map +1 -0
  55. package/dist/next/client.d.ts +27 -0
  56. package/dist/next/client.d.ts.map +1 -0
  57. package/dist/next/client.js +275 -0
  58. package/dist/next/client.js.map +1 -0
  59. package/dist/next/createDevPage.d.ts +37 -0
  60. package/dist/next/createDevPage.d.ts.map +1 -0
  61. package/dist/next/createDevPage.js +287 -0
  62. package/dist/next/createDevPage.js.map +1 -0
  63. package/dist/next/pageStyles.d.ts +5 -0
  64. package/dist/next/pageStyles.d.ts.map +1 -0
  65. package/dist/next/pageStyles.js +83 -0
  66. package/dist/next/pageStyles.js.map +1 -0
  67. package/dist/next/specimen.d.ts +24 -0
  68. package/dist/next/specimen.d.ts.map +1 -0
  69. package/dist/next/specimen.js +48 -0
  70. package/dist/next/specimen.js.map +1 -0
  71. package/dist/next/views.d.ts +31 -0
  72. package/dist/next/views.d.ts.map +1 -0
  73. package/dist/next/views.js +431 -0
  74. package/dist/next/views.js.map +1 -0
  75. package/dist/next.d.ts +5 -0
  76. package/dist/next.d.ts.map +1 -0
  77. package/dist/next.js +6 -0
  78. package/dist/next.js.map +1 -0
  79. package/dist/options.d.ts +17 -0
  80. package/dist/options.d.ts.map +1 -0
  81. package/dist/options.js +3 -0
  82. package/dist/options.js.map +1 -0
  83. package/dist/plugin.d.ts +20 -0
  84. package/dist/plugin.d.ts.map +1 -0
  85. package/dist/plugin.js +51 -0
  86. package/dist/plugin.js.map +1 -0
  87. package/dist/toolbar.d.ts +8 -0
  88. package/dist/toolbar.d.ts.map +1 -0
  89. package/dist/toolbar.js +8 -0
  90. package/dist/toolbar.js.map +1 -0
  91. package/package.json +77 -0
@@ -0,0 +1,983 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import Link from "next/link";
4
+ import { usePathname, useRouter } from "next/navigation";
5
+ import { useCallback, useEffect, useRef, useState } from "react";
6
+ import { CHROME_COOKIES, STAGE_COOKIE } from "../cookies.js";
7
+ const STORE_KEY = 'pdt-settings';
8
+ const HIDE_KEY = 'pdt-hidden';
9
+ const DEFAULTS = {
10
+ corner: 'bottom-right',
11
+ size: 'md'
12
+ };
13
+ const CORNER_CLASS = {
14
+ 'bottom-right': 'br',
15
+ 'bottom-left': 'bl',
16
+ 'top-right': 'tr',
17
+ 'top-left': 'tl'
18
+ };
19
+ const CORNERS = [
20
+ {
21
+ value: 'top-left',
22
+ arrow: '↖'
23
+ },
24
+ {
25
+ value: 'top-right',
26
+ arrow: '↗'
27
+ },
28
+ {
29
+ value: 'bottom-left',
30
+ arrow: '↙'
31
+ },
32
+ {
33
+ value: 'bottom-right',
34
+ arrow: '↘'
35
+ }
36
+ ];
37
+ const SIZES = [
38
+ 'sm',
39
+ 'md',
40
+ 'lg'
41
+ ];
42
+ const VIEW_TITLE = {
43
+ info: 'Info',
44
+ seed: 'Seed',
45
+ pages: 'Pages',
46
+ tests: 'Tests',
47
+ settings: 'Settings'
48
+ };
49
+ const readSettings = ()=>{
50
+ try {
51
+ const parsed = JSON.parse(localStorage.getItem(STORE_KEY) ?? '{}');
52
+ return parsed && typeof parsed === 'object' ? {
53
+ ...DEFAULTS,
54
+ ...parsed
55
+ } : DEFAULTS;
56
+ } catch {
57
+ return DEFAULTS;
58
+ }
59
+ };
60
+ /** A selection cookie (`testKey:versionId`), read client-side — the server reads the same cookie
61
+ * (test pages for the stage cookie, `resolveDevChrome` for the chrome slots), so the toolbar
62
+ * chips and the rendered result always agree. */ const readSelectionCookie = (name)=>{
63
+ const raw = document.cookie.split('; ').find((c)=>c.startsWith(`${name}=`))?.split('=')[1];
64
+ if (!raw) return null;
65
+ try {
66
+ const decoded = decodeURIComponent(raw);
67
+ const sep = decoded.indexOf(':');
68
+ return sep > 0 ? {
69
+ testKey: decoded.slice(0, sep),
70
+ versionId: decoded.slice(sep + 1)
71
+ } : null;
72
+ } catch {
73
+ return null;
74
+ }
75
+ };
76
+ /**
77
+ * The toolbar panel — THE controller for the dev experience. Navigation happens through it (the
78
+ * dev pages render content only, no nav of their own), the panel stays open across route changes
79
+ * (it lives in the layout, and rows are client-side `<Link>`s), and the Tests view both opens a
80
+ * test's page and toggles which version that page shows.
81
+ */ export function DevToolbarClient({ tests, links }) {
82
+ const router = useRouter();
83
+ const pathname = usePathname();
84
+ const [mounted, setMounted] = useState(false);
85
+ const [hidden, setHidden] = useState(false);
86
+ const [open, setOpen] = useState(false);
87
+ const [view, setView] = useState('main');
88
+ const [settings, setSettings] = useState(DEFAULTS);
89
+ const [selection, setSelection] = useState(null);
90
+ const [chrome, setChrome] = useState({
91
+ header: null,
92
+ footer: null
93
+ });
94
+ const [snapshot, setSnapshot] = useState(null);
95
+ const [snapshotError, setSnapshotError] = useState(false);
96
+ const [seeding, setSeeding] = useState(false);
97
+ const [confirming, setConfirming] = useState(false);
98
+ const [seedError, setSeedError] = useState(null);
99
+ const rootRef = useRef(null);
100
+ useEffect(()=>{
101
+ setHidden(sessionStorage.getItem(HIDE_KEY) === '1');
102
+ setSettings(readSettings());
103
+ setSelection(readSelectionCookie(STAGE_COOKIE));
104
+ setChrome({
105
+ header: readSelectionCookie(CHROME_COOKIES.header),
106
+ footer: readSelectionCookie(CHROME_COOKIES.footer)
107
+ });
108
+ setMounted(true);
109
+ }, []);
110
+ const fetchSnapshot = useCallback(async ()=>{
111
+ try {
112
+ const res = await fetch('/api/dev', {
113
+ headers: {
114
+ accept: 'application/json'
115
+ },
116
+ credentials: 'include'
117
+ });
118
+ if (!res.ok) throw new Error(String(res.status));
119
+ setSnapshot(await res.json());
120
+ setSnapshotError(false);
121
+ } catch {
122
+ setSnapshotError(true);
123
+ }
124
+ }, []);
125
+ // Lazy: the snapshot loads on first open, not on page load.
126
+ useEffect(()=>{
127
+ if (open && !snapshot && !snapshotError) void fetchSnapshot();
128
+ }, [
129
+ open,
130
+ snapshot,
131
+ snapshotError,
132
+ fetchSnapshot
133
+ ]);
134
+ const base = snapshot?.devRoute ?? '/dev';
135
+ /** Select a version: write the cookie, then show it — refresh if we're already on the test's
136
+ * page, navigate there if not. The panel stays open either way. */ const selectVersion = useCallback((testKey, versionId)=>{
137
+ // biome-ignore lint/suspicious/noDocumentCookie: dev-only synchronous cookie write; Cookie Store API is async and not universal
138
+ document.cookie = `${STAGE_COOKIE}=${encodeURIComponent(`${testKey}:${versionId}`)}; path=/; samesite=lax`;
139
+ setSelection({
140
+ testKey,
141
+ versionId
142
+ });
143
+ const testPath = `${base}/tests/${testKey}`;
144
+ if (pathname === testPath) router.refresh();
145
+ else router.push(testPath);
146
+ }, [
147
+ base,
148
+ pathname,
149
+ router
150
+ ]);
151
+ /** Set/clear a chrome override (header/footer swap): the cookie applies SITE-WIDE in dev —
152
+ * `resolveDevChrome` in the host layout swaps the variant in wherever you browse. */ const selectChrome = useCallback((slot, sel)=>{
153
+ // biome-ignore lint/suspicious/noDocumentCookie: dev-only synchronous cookie write; Cookie Store API is async and not universal
154
+ document.cookie = sel ? `${CHROME_COOKIES[slot]}=${encodeURIComponent(`${sel.testKey}:${sel.versionId}`)}; path=/; samesite=lax` : `${CHROME_COOKIES[slot]}=; path=/; max-age=0; samesite=lax`;
155
+ setChrome((prev)=>({
156
+ ...prev,
157
+ [slot]: sel
158
+ }));
159
+ router.refresh();
160
+ }, [
161
+ router
162
+ ]);
163
+ const update = useCallback((patch)=>{
164
+ setSettings((prev)=>{
165
+ const next = {
166
+ ...prev,
167
+ ...patch
168
+ };
169
+ try {
170
+ localStorage.setItem(STORE_KEY, JSON.stringify(next));
171
+ } catch {}
172
+ return next;
173
+ });
174
+ }, []);
175
+ const runSeed = async ()=>{
176
+ setSeeding(true);
177
+ setSeedError(null);
178
+ try {
179
+ const res = await fetch('/api/seed', {
180
+ method: 'POST',
181
+ credentials: 'include'
182
+ });
183
+ if (res.ok) {
184
+ setConfirming(false);
185
+ setSeeding(false);
186
+ await fetchSnapshot();
187
+ router.refresh();
188
+ return;
189
+ }
190
+ const body = await res.json().catch(()=>null);
191
+ setSeedError(body?.error ? body : {
192
+ error: `Seed failed (HTTP ${res.status}).`
193
+ });
194
+ } catch {
195
+ setSeedError({
196
+ error: 'Seed request failed — is the dev server running?'
197
+ });
198
+ }
199
+ setSeeding(false);
200
+ setConfirming(false);
201
+ };
202
+ useEffect(()=>{
203
+ if (!open) return;
204
+ const onDown = (e)=>{
205
+ if (rootRef.current && e.target instanceof Node && !rootRef.current.contains(e.target)) setOpen(false);
206
+ };
207
+ document.addEventListener('mousedown', onDown);
208
+ return ()=>document.removeEventListener('mousedown', onDown);
209
+ }, [
210
+ open
211
+ ]);
212
+ useEffect(()=>{
213
+ const onKey = (e)=>{
214
+ if (e.key !== 'Escape' || !open) return;
215
+ if (view === 'main') setOpen(false);
216
+ else setView('main');
217
+ };
218
+ document.addEventListener('keydown', onKey);
219
+ return ()=>document.removeEventListener('keydown', onKey);
220
+ }, [
221
+ open,
222
+ view
223
+ ]);
224
+ if (!mounted || hidden) return null;
225
+ const corner = CORNER_CLASS[settings.corner];
226
+ const seed = snapshot?.seed;
227
+ const pageLinks = [
228
+ {
229
+ href: base,
230
+ title: 'Overview'
231
+ },
232
+ ...snapshot?.icons ? [
233
+ {
234
+ href: `${base}/icons`,
235
+ title: 'Icons'
236
+ }
237
+ ] : [],
238
+ ...snapshot?.fonts ? [
239
+ {
240
+ href: `${base}/fonts`,
241
+ title: 'Fonts'
242
+ }
243
+ ] : [],
244
+ ...snapshot?.images ? [
245
+ {
246
+ href: `${base}/images`,
247
+ title: 'Images'
248
+ }
249
+ ] : [],
250
+ ...snapshot?.mux ? [
251
+ {
252
+ href: `${base}/mux`,
253
+ title: 'Mux'
254
+ }
255
+ ] : [],
256
+ ...links,
257
+ {
258
+ href: snapshot?.adminRoute ?? '/admin',
259
+ title: 'Payload admin'
260
+ },
261
+ {
262
+ href: 'https://payload-plugins.prolaico.com/docs',
263
+ title: 'Plugin docs ↗'
264
+ }
265
+ ];
266
+ return /*#__PURE__*/ _jsxs("div", {
267
+ ref: rootRef,
268
+ className: `pdt-root pdt-corner-${corner}`,
269
+ children: [
270
+ open ? /*#__PURE__*/ _jsxs("div", {
271
+ className: `pdt-panel pdt-panel-${corner}`,
272
+ children: [
273
+ /*#__PURE__*/ _jsxs("div", {
274
+ className: "pdt-head",
275
+ children: [
276
+ view !== 'main' ? /*#__PURE__*/ _jsx("button", {
277
+ type: "button",
278
+ className: "pdt-back",
279
+ "aria-label": "Back",
280
+ onClick: ()=>setView('main'),
281
+ children: "‹"
282
+ }) : null,
283
+ /*#__PURE__*/ _jsx("span", {
284
+ className: "pdt-head-title",
285
+ children: view === 'main' ? 'Dev tools' : VIEW_TITLE[view]
286
+ }),
287
+ /*#__PURE__*/ _jsx("span", {
288
+ className: "pdt-head-badge",
289
+ children: "dev only"
290
+ })
291
+ ]
292
+ }),
293
+ /*#__PURE__*/ _jsxs("div", {
294
+ className: "pdt-body",
295
+ children: [
296
+ view === 'main' ? /*#__PURE__*/ _jsxs("ul", {
297
+ className: "pdt-menu",
298
+ children: [
299
+ /*#__PURE__*/ _jsx(MenuRow, {
300
+ label: "Info",
301
+ hint: snapshot ? snapshot.env.nodeEnv : undefined,
302
+ onClick: ()=>setView('info')
303
+ }),
304
+ snapshot?.plugins.seed !== false ? /*#__PURE__*/ _jsx(MenuRow, {
305
+ label: "Seed",
306
+ hint: seed ? seed.seeded ? `${seed.totalDocs} docs` : 'empty' : undefined,
307
+ onClick: ()=>setView('seed')
308
+ }) : null,
309
+ /*#__PURE__*/ _jsx(MenuRow, {
310
+ label: "Pages",
311
+ hint: pathname.startsWith(base) ? pathname : undefined,
312
+ onClick: ()=>setView('pages')
313
+ }),
314
+ tests.length ? /*#__PURE__*/ _jsx(MenuRow, {
315
+ label: "Tests",
316
+ hint: `${tests.length}`,
317
+ onClick: ()=>setView('tests')
318
+ }) : null,
319
+ /*#__PURE__*/ _jsx(MenuRow, {
320
+ label: "Settings",
321
+ onClick: ()=>setView('settings')
322
+ })
323
+ ]
324
+ }) : null,
325
+ view === 'info' ? /*#__PURE__*/ _jsxs("div", {
326
+ children: [
327
+ snapshotError ? /*#__PURE__*/ _jsx(SnapshotMissing, {
328
+ retry: fetchSnapshot
329
+ }) : null,
330
+ snapshot ? /*#__PURE__*/ _jsxs(_Fragment, {
331
+ children: [
332
+ /*#__PURE__*/ _jsxs("div", {
333
+ className: "pdt-card",
334
+ children: [
335
+ /*#__PURE__*/ _jsxs("div", {
336
+ className: "pdt-card-head",
337
+ children: [
338
+ /*#__PURE__*/ _jsx("span", {
339
+ className: "pdt-card-title",
340
+ children: "Environment"
341
+ }),
342
+ /*#__PURE__*/ _jsx("button", {
343
+ type: "button",
344
+ className: "pdt-kind",
345
+ onClick: fetchSnapshot,
346
+ children: "refresh"
347
+ })
348
+ ]
349
+ }),
350
+ /*#__PURE__*/ _jsxs("p", {
351
+ className: "pdt-small",
352
+ style: {
353
+ margin: 0
354
+ },
355
+ children: [
356
+ /*#__PURE__*/ _jsx("span", {
357
+ className: "pdt-code",
358
+ children: snapshot.env.nodeEnv
359
+ }),
360
+ " · node ",
361
+ snapshot.env.nodeVersion
362
+ ]
363
+ }),
364
+ /*#__PURE__*/ _jsx("div", {
365
+ style: {
366
+ marginTop: 8,
367
+ display: 'flex',
368
+ flexWrap: 'wrap',
369
+ gap: '3px 12px'
370
+ },
371
+ className: "pdt-small",
372
+ children: Object.entries(snapshot.plugins).map(([name, on])=>/*#__PURE__*/ _jsxs("span", {
373
+ children: [
374
+ /*#__PURE__*/ _jsx("span", {
375
+ className: `pdt-dot ${on ? 'pdt-dot-on' : 'pdt-dot-off'}`
376
+ }),
377
+ name
378
+ ]
379
+ }, name))
380
+ })
381
+ ]
382
+ }),
383
+ /*#__PURE__*/ _jsxs("div", {
384
+ className: "pdt-card",
385
+ children: [
386
+ /*#__PURE__*/ _jsx("div", {
387
+ className: "pdt-card-head",
388
+ children: /*#__PURE__*/ _jsx("span", {
389
+ className: "pdt-card-title",
390
+ children: "Collections"
391
+ })
392
+ }),
393
+ /*#__PURE__*/ _jsx("table", {
394
+ className: "pdt-table",
395
+ children: /*#__PURE__*/ _jsx("tbody", {
396
+ children: snapshot.collections.map((c)=>/*#__PURE__*/ _jsxs("tr", {
397
+ children: [
398
+ /*#__PURE__*/ _jsx("td", {
399
+ children: c.slug
400
+ }),
401
+ /*#__PURE__*/ _jsx("td", {
402
+ children: c.count ?? '?'
403
+ })
404
+ ]
405
+ }, c.slug))
406
+ })
407
+ })
408
+ ]
409
+ }),
410
+ snapshot.icons ? /*#__PURE__*/ _jsxs("div", {
411
+ className: "pdt-card",
412
+ children: [
413
+ /*#__PURE__*/ _jsxs("div", {
414
+ className: "pdt-card-head",
415
+ children: [
416
+ /*#__PURE__*/ _jsx("span", {
417
+ className: "pdt-card-title",
418
+ children: "Icons"
419
+ }),
420
+ /*#__PURE__*/ _jsx("span", {
421
+ className: "pdt-kind",
422
+ children: snapshot.icons.iconCount ?? '?'
423
+ })
424
+ ]
425
+ }),
426
+ /*#__PURE__*/ _jsxs("p", {
427
+ className: "pdt-small",
428
+ style: {
429
+ margin: 0
430
+ },
431
+ children: [
432
+ "Active set: ",
433
+ snapshot.icons.activeSet ?? /*#__PURE__*/ _jsx("span", {
434
+ className: "pdt-warn",
435
+ children: "none"
436
+ })
437
+ ]
438
+ }),
439
+ snapshot.icons.misses.length ? /*#__PURE__*/ _jsxs("p", {
440
+ className: "pdt-small pdt-warn",
441
+ style: {
442
+ margin: '6px 0 0'
443
+ },
444
+ children: [
445
+ "Misses:",
446
+ ' ',
447
+ snapshot.icons.misses.map((m)=>/*#__PURE__*/ _jsxs("span", {
448
+ className: "pdt-code",
449
+ style: {
450
+ marginRight: 5
451
+ },
452
+ children: [
453
+ m.name,
454
+ " ×",
455
+ m.count
456
+ ]
457
+ }, m.name))
458
+ ]
459
+ }) : null
460
+ ]
461
+ }) : null,
462
+ snapshot.fonts ? /*#__PURE__*/ _jsxs("div", {
463
+ className: "pdt-card",
464
+ children: [
465
+ /*#__PURE__*/ _jsxs("div", {
466
+ className: "pdt-card-head",
467
+ children: [
468
+ /*#__PURE__*/ _jsx("span", {
469
+ className: "pdt-card-title",
470
+ children: "Fonts"
471
+ }),
472
+ /*#__PURE__*/ _jsx("span", {
473
+ className: "pdt-kind",
474
+ children: snapshot.fonts.fontCount ?? '?'
475
+ })
476
+ ]
477
+ }),
478
+ /*#__PURE__*/ _jsx("table", {
479
+ className: "pdt-table",
480
+ children: /*#__PURE__*/ _jsx("tbody", {
481
+ children: snapshot.fonts.familyKeys.map((key)=>/*#__PURE__*/ _jsxs("tr", {
482
+ children: [
483
+ /*#__PURE__*/ _jsx("td", {
484
+ children: key
485
+ }),
486
+ /*#__PURE__*/ _jsx("td", {
487
+ children: snapshot.fonts?.slots[key] ?? 'unset'
488
+ })
489
+ ]
490
+ }, key))
491
+ })
492
+ })
493
+ ]
494
+ }) : null,
495
+ snapshot.mux ? /*#__PURE__*/ _jsxs("div", {
496
+ className: "pdt-card",
497
+ children: [
498
+ /*#__PURE__*/ _jsxs("div", {
499
+ className: "pdt-card-head",
500
+ children: [
501
+ /*#__PURE__*/ _jsx("span", {
502
+ className: "pdt-card-title",
503
+ children: "Mux"
504
+ }),
505
+ /*#__PURE__*/ _jsxs("span", {
506
+ className: "pdt-kind",
507
+ children: [
508
+ snapshot.mux.total ?? '?',
509
+ " / ",
510
+ snapshot.mux.ready ?? '?',
511
+ " ready"
512
+ ]
513
+ })
514
+ ]
515
+ }),
516
+ !snapshot.mux.credentialed ? /*#__PURE__*/ _jsx("p", {
517
+ className: "pdt-small pdt-warn",
518
+ style: {
519
+ margin: 0
520
+ },
521
+ children: "MUX_TOKEN_ID / MUX_TOKEN_SECRET not set"
522
+ }) : null
523
+ ]
524
+ }) : null
525
+ ]
526
+ }) : !snapshotError ? /*#__PURE__*/ _jsx("p", {
527
+ className: "pdt-note",
528
+ children: "Loading…"
529
+ }) : null
530
+ ]
531
+ }) : null,
532
+ view === 'seed' ? /*#__PURE__*/ _jsxs("div", {
533
+ children: [
534
+ snapshotError ? /*#__PURE__*/ _jsx(SnapshotMissing, {
535
+ retry: fetchSnapshot
536
+ }) : null,
537
+ snapshot && !seed ? /*#__PURE__*/ _jsxs("p", {
538
+ className: "pdt-note",
539
+ children: [
540
+ /*#__PURE__*/ _jsx("span", {
541
+ className: "pdt-code",
542
+ children: "@pro-laico/payload-seed"
543
+ }),
544
+ " isn't installed — add",
545
+ ' ',
546
+ /*#__PURE__*/ _jsx("span", {
547
+ className: "pdt-code",
548
+ children: "seedPlugin()"
549
+ }),
550
+ " to get one-click seeding here."
551
+ ]
552
+ }) : null,
553
+ seed ? /*#__PURE__*/ _jsxs("div", {
554
+ className: "pdt-card",
555
+ children: [
556
+ /*#__PURE__*/ _jsxs("div", {
557
+ className: "pdt-card-head",
558
+ children: [
559
+ /*#__PURE__*/ _jsx("span", {
560
+ className: "pdt-card-title",
561
+ children: seed.seeded ? `Seeded — ${seed.totalDocs} docs` : 'Not seeded'
562
+ }),
563
+ !seed.enabled ? /*#__PURE__*/ _jsx("span", {
564
+ className: "pdt-kind pdt-warn",
565
+ children: "locked"
566
+ }) : null
567
+ ]
568
+ }),
569
+ seed.definitions.length ? /*#__PURE__*/ _jsx("table", {
570
+ className: "pdt-table",
571
+ children: /*#__PURE__*/ _jsx("tbody", {
572
+ children: seed.definitions.map((d)=>/*#__PURE__*/ _jsxs("tr", {
573
+ children: [
574
+ /*#__PURE__*/ _jsxs("td", {
575
+ children: [
576
+ d.slug,
577
+ d.disabled ? /*#__PURE__*/ _jsx("span", {
578
+ className: "pdt-warn",
579
+ children: " · skipped"
580
+ }) : null
581
+ ]
582
+ }),
583
+ /*#__PURE__*/ _jsx("td", {
584
+ children: d.kind === 'global' ? 'global' : seed.counts[d.slug] ?? 0
585
+ })
586
+ ]
587
+ }, d.slug))
588
+ })
589
+ }) : /*#__PURE__*/ _jsx("p", {
590
+ className: "pdt-note",
591
+ style: {
592
+ margin: 0
593
+ },
594
+ children: "No seed definitions registered."
595
+ }),
596
+ /*#__PURE__*/ _jsxs("div", {
597
+ style: {
598
+ marginTop: 10,
599
+ display: 'flex',
600
+ gap: 6
601
+ },
602
+ children: [
603
+ /*#__PURE__*/ _jsx("button", {
604
+ type: "button",
605
+ className: `pdt-btn ${seed.seeded ? 'pdt-btn-danger' : 'pdt-btn-primary'}`,
606
+ disabled: seeding,
607
+ onClick: ()=>seed.seeded && !confirming ? setConfirming(true) : void runSeed(),
608
+ children: seeding ? 'Seeding…' : confirming ? 'Destructive — click again' : seed.seeded ? 'Reseed' : 'Seed the database'
609
+ }),
610
+ confirming ? /*#__PURE__*/ _jsx("button", {
611
+ type: "button",
612
+ className: "pdt-btn",
613
+ onClick: ()=>setConfirming(false),
614
+ children: "Cancel"
615
+ }) : null
616
+ ]
617
+ }),
618
+ !seed.enabled ? /*#__PURE__*/ _jsxs("p", {
619
+ className: "pdt-note",
620
+ children: [
621
+ "Set ",
622
+ /*#__PURE__*/ _jsx("span", {
623
+ className: "pdt-code",
624
+ children: "ENABLE_SEED=true"
625
+ }),
626
+ " in ",
627
+ /*#__PURE__*/ _jsx("span", {
628
+ className: "pdt-code",
629
+ children: ".env.local"
630
+ }),
631
+ " — the seed wipes seeded collections, so it's off by default."
632
+ ]
633
+ }) : null,
634
+ /*#__PURE__*/ _jsxs("p", {
635
+ className: "pdt-note",
636
+ style: {
637
+ marginBottom: 0
638
+ },
639
+ children: [
640
+ "Needs a logged-in",
641
+ ' ',
642
+ /*#__PURE__*/ _jsx("a", {
643
+ href: snapshot?.adminRoute ?? '/admin',
644
+ style: {
645
+ textDecoration: 'underline'
646
+ },
647
+ children: "admin"
648
+ }),
649
+ ' ',
650
+ "user · CLI: ",
651
+ /*#__PURE__*/ _jsx("span", {
652
+ className: "pdt-code",
653
+ children: "ENABLE_SEED=true pnpm seed"
654
+ })
655
+ ]
656
+ }),
657
+ seedError ? /*#__PURE__*/ _jsxs("div", {
658
+ className: "pdt-error",
659
+ children: [
660
+ seedError.error,
661
+ seedError.issues?.length ? /*#__PURE__*/ _jsx("ul", {
662
+ children: seedError.issues.map((issue)=>/*#__PURE__*/ _jsx("li", {
663
+ children: issue
664
+ }, issue))
665
+ }) : null
666
+ ]
667
+ }) : null
668
+ ]
669
+ }) : null
670
+ ]
671
+ }) : null,
672
+ view === 'pages' ? /*#__PURE__*/ _jsxs("div", {
673
+ children: [
674
+ /*#__PURE__*/ _jsx("ul", {
675
+ className: "pdt-menu",
676
+ children: pageLinks.map((link)=>link.href.startsWith('http') ? /*#__PURE__*/ _jsx("li", {
677
+ children: /*#__PURE__*/ _jsxs("a", {
678
+ className: "pdt-menu-row",
679
+ href: link.href,
680
+ target: "_blank",
681
+ rel: "noreferrer",
682
+ children: [
683
+ /*#__PURE__*/ _jsx("span", {
684
+ children: link.title
685
+ }),
686
+ /*#__PURE__*/ _jsx("span", {
687
+ className: "pdt-menu-hint",
688
+ children: link.href.replace(/^https?:\/\//, '')
689
+ })
690
+ ]
691
+ })
692
+ }, link.href) : /*#__PURE__*/ _jsx("li", {
693
+ children: /*#__PURE__*/ _jsxs(Link, {
694
+ className: `pdt-menu-row ${pathname === link.href ? 'pdt-current' : ''}`,
695
+ href: link.href,
696
+ children: [
697
+ /*#__PURE__*/ _jsx("span", {
698
+ children: link.title
699
+ }),
700
+ /*#__PURE__*/ _jsx("span", {
701
+ className: "pdt-menu-hint",
702
+ children: link.href
703
+ })
704
+ ]
705
+ })
706
+ }, link.href))
707
+ }),
708
+ !snapshot && !snapshotError ? /*#__PURE__*/ _jsx("p", {
709
+ className: "pdt-note",
710
+ children: "Loading plugin pages…"
711
+ }) : null,
712
+ snapshotError ? /*#__PURE__*/ _jsx(SnapshotMissing, {
713
+ retry: fetchSnapshot
714
+ }) : null
715
+ ]
716
+ }) : null,
717
+ view === 'tests' ? /*#__PURE__*/ _jsxs("div", {
718
+ children: [
719
+ tests.map((t)=>{
720
+ // header/footer kinds are chrome OVERRIDES: chips swap the variant into the real
721
+ // layout site-wide (via resolveDevChrome) instead of opening a test page.
722
+ if (t.kind === 'header' || t.kind === 'footer') {
723
+ const slot = t.kind;
724
+ const active = chrome[slot]?.testKey === t.key ? chrome[slot] : null;
725
+ return /*#__PURE__*/ _jsxs("div", {
726
+ className: "pdt-card",
727
+ children: [
728
+ /*#__PURE__*/ _jsxs("div", {
729
+ className: "pdt-card-head",
730
+ children: [
731
+ /*#__PURE__*/ _jsx("span", {
732
+ className: "pdt-card-title",
733
+ children: t.label
734
+ }),
735
+ /*#__PURE__*/ _jsx("span", {
736
+ className: "pdt-kind",
737
+ children: active ? /*#__PURE__*/ _jsx("span", {
738
+ className: "pdt-viewing",
739
+ children: "override on"
740
+ }) : `${t.kind} override`
741
+ })
742
+ ]
743
+ }),
744
+ /*#__PURE__*/ _jsxs("div", {
745
+ className: "pdt-chips",
746
+ children: [
747
+ /*#__PURE__*/ _jsx("button", {
748
+ type: "button",
749
+ className: `pdt-chip ${active ? '' : 'pdt-active'}`,
750
+ onClick: ()=>selectChrome(slot, null),
751
+ children: "Real"
752
+ }),
753
+ t.versions.map((v)=>/*#__PURE__*/ _jsx("button", {
754
+ type: "button",
755
+ className: `pdt-chip ${active?.versionId === v.id ? 'pdt-active' : ''}`,
756
+ onClick: ()=>selectChrome(slot, {
757
+ testKey: t.key,
758
+ versionId: v.id
759
+ }),
760
+ children: v.label
761
+ }, v.id))
762
+ ]
763
+ })
764
+ ]
765
+ }, t.key);
766
+ }
767
+ const testPath = `${base}/tests/${t.key}`;
768
+ const onPage = pathname === testPath;
769
+ // The page defaults to the first version when no cookie targets this test.
770
+ const selectedId = selection?.testKey === t.key ? selection.versionId : t.versions[0]?.id;
771
+ return /*#__PURE__*/ _jsxs("div", {
772
+ className: "pdt-card",
773
+ children: [
774
+ /*#__PURE__*/ _jsxs("div", {
775
+ className: "pdt-card-head",
776
+ children: [
777
+ /*#__PURE__*/ _jsxs(Link, {
778
+ href: testPath,
779
+ className: "pdt-card-title",
780
+ style: {
781
+ textDecoration: onPage ? 'none' : undefined
782
+ },
783
+ children: [
784
+ t.label,
785
+ " ",
786
+ onPage ? null : /*#__PURE__*/ _jsx("span", {
787
+ "aria-hidden": true,
788
+ children: "›"
789
+ })
790
+ ]
791
+ }),
792
+ /*#__PURE__*/ _jsx("span", {
793
+ className: "pdt-kind",
794
+ children: onPage ? /*#__PURE__*/ _jsx("span", {
795
+ className: "pdt-viewing",
796
+ children: "viewing"
797
+ }) : t.kind
798
+ })
799
+ ]
800
+ }),
801
+ /*#__PURE__*/ _jsx("div", {
802
+ className: "pdt-chips",
803
+ children: t.versions.map((v)=>/*#__PURE__*/ _jsx("button", {
804
+ type: "button",
805
+ className: `pdt-chip ${selectedId === v.id ? 'pdt-active' : ''}`,
806
+ onClick: ()=>selectVersion(t.key, v.id),
807
+ children: v.label
808
+ }, v.id))
809
+ })
810
+ ]
811
+ }, t.key);
812
+ }),
813
+ /*#__PURE__*/ _jsxs("p", {
814
+ className: "pdt-note",
815
+ children: [
816
+ "Page tests open as their own page; header/footer overrides swap into the live layout everywhere until you hit Real. Scriptable via ",
817
+ /*#__PURE__*/ _jsx("span", {
818
+ className: "pdt-code",
819
+ children: "/api/dev/stage?test=…&version=…"
820
+ })
821
+ ]
822
+ })
823
+ ]
824
+ }) : null,
825
+ view === 'settings' ? /*#__PURE__*/ _jsxs("div", {
826
+ children: [
827
+ /*#__PURE__*/ _jsxs("div", {
828
+ className: "pdt-settings-row",
829
+ children: [
830
+ /*#__PURE__*/ _jsx("span", {
831
+ className: "pdt-small pdt-muted",
832
+ children: "Corner"
833
+ }),
834
+ /*#__PURE__*/ _jsx("div", {
835
+ className: "pdt-corner-grid",
836
+ children: CORNERS.map((c)=>/*#__PURE__*/ _jsx("button", {
837
+ type: "button",
838
+ "aria-label": c.value,
839
+ className: `pdt-corner-btn ${settings.corner === c.value ? 'pdt-active' : ''}`,
840
+ onClick: ()=>update({
841
+ corner: c.value
842
+ }),
843
+ children: c.arrow
844
+ }, c.value))
845
+ })
846
+ ]
847
+ }),
848
+ /*#__PURE__*/ _jsxs("div", {
849
+ className: "pdt-settings-row",
850
+ children: [
851
+ /*#__PURE__*/ _jsx("span", {
852
+ className: "pdt-small pdt-muted",
853
+ children: "Size"
854
+ }),
855
+ /*#__PURE__*/ _jsx("div", {
856
+ className: "pdt-seg",
857
+ children: SIZES.map((s)=>/*#__PURE__*/ _jsx("button", {
858
+ type: "button",
859
+ className: settings.size === s ? 'pdt-active' : '',
860
+ onClick: ()=>update({
861
+ size: s
862
+ }),
863
+ children: s
864
+ }, s))
865
+ })
866
+ ]
867
+ }),
868
+ /*#__PURE__*/ _jsxs("div", {
869
+ style: {
870
+ padding: '6px 4px 2px'
871
+ },
872
+ children: [
873
+ /*#__PURE__*/ _jsx("button", {
874
+ type: "button",
875
+ className: "pdt-btn",
876
+ style: {
877
+ width: '100%',
878
+ justifyContent: 'center'
879
+ },
880
+ onClick: ()=>{
881
+ try {
882
+ sessionStorage.setItem(HIDE_KEY, '1');
883
+ } catch {}
884
+ setHidden(true);
885
+ setOpen(false);
886
+ },
887
+ children: "Hide for this session"
888
+ }),
889
+ /*#__PURE__*/ _jsx("p", {
890
+ className: "pdt-note",
891
+ style: {
892
+ textAlign: 'center'
893
+ },
894
+ children: "reopens in a new tab / session"
895
+ })
896
+ ]
897
+ })
898
+ ]
899
+ }) : null
900
+ ]
901
+ })
902
+ ]
903
+ }) : null,
904
+ /*#__PURE__*/ _jsx("button", {
905
+ type: "button",
906
+ "aria-label": "Dev tools",
907
+ title: "Dev tools",
908
+ className: `pdt-fab pdt-fab-${settings.size} ${open ? 'pdt-open' : ''}`,
909
+ onClick: ()=>{
910
+ setOpen((v)=>!v);
911
+ setView('main');
912
+ },
913
+ children: /*#__PURE__*/ _jsxs("svg", {
914
+ viewBox: "0 0 24 24",
915
+ fill: "none",
916
+ stroke: "currentColor",
917
+ strokeWidth: "2",
918
+ strokeLinecap: "round",
919
+ strokeLinejoin: "round",
920
+ "aria-hidden": true,
921
+ children: [
922
+ /*#__PURE__*/ _jsx("path", {
923
+ d: "m5 8 4 4-4 4"
924
+ }),
925
+ /*#__PURE__*/ _jsx("path", {
926
+ d: "M13 16h6"
927
+ })
928
+ ]
929
+ })
930
+ })
931
+ ]
932
+ });
933
+ }
934
+ const MenuRow = ({ label, hint, onClick })=>/*#__PURE__*/ _jsx("li", {
935
+ children: /*#__PURE__*/ _jsxs("button", {
936
+ type: "button",
937
+ className: "pdt-menu-row",
938
+ onClick: onClick,
939
+ children: [
940
+ /*#__PURE__*/ _jsx("span", {
941
+ children: label
942
+ }),
943
+ /*#__PURE__*/ _jsxs("span", {
944
+ className: "pdt-menu-hint",
945
+ children: [
946
+ hint ? /*#__PURE__*/ _jsx("span", {
947
+ children: hint
948
+ }) : null,
949
+ /*#__PURE__*/ _jsx("span", {
950
+ "aria-hidden": true,
951
+ children: "›"
952
+ })
953
+ ]
954
+ })
955
+ ]
956
+ })
957
+ });
958
+ const SnapshotMissing = ({ retry })=>/*#__PURE__*/ _jsxs("p", {
959
+ className: "pdt-note",
960
+ children: [
961
+ /*#__PURE__*/ _jsx("span", {
962
+ className: "pdt-warn",
963
+ children: "Couldn't reach /api/dev."
964
+ }),
965
+ " Is ",
966
+ /*#__PURE__*/ _jsx("span", {
967
+ className: "pdt-code",
968
+ children: "devToolsPlugin()"
969
+ }),
970
+ " in your Payload plugins list?",
971
+ ' ',
972
+ /*#__PURE__*/ _jsx("button", {
973
+ type: "button",
974
+ style: {
975
+ textDecoration: 'underline'
976
+ },
977
+ onClick: ()=>void retry(),
978
+ children: "Retry"
979
+ })
980
+ ]
981
+ });
982
+
983
+ //# sourceMappingURL=DevToolbarClient.js.map