@pro-laico/payload-dev-tools 0.0.0 → 0.2.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.
- package/dist/components/DevToolbar.d.ts.map +1 -1
- package/dist/components/DevToolbar.js +7 -3
- package/dist/components/DevToolbar.js.map +1 -1
- package/dist/components/DevToolbarClient.d.ts.map +1 -1
- package/dist/components/DevToolbarClient.js +91 -1
- package/dist/components/DevToolbarClient.js.map +1 -1
- package/dist/components/styles.d.ts +1 -1
- package/dist/components/styles.d.ts.map +1 -1
- package/dist/components/styles.js +13 -0
- package/dist/components/styles.js.map +1 -1
- package/dist/endpoints/activateIconSet.d.ts.map +1 -1
- package/dist/endpoints/activateIconSet.js +2 -0
- package/dist/endpoints/activateIconSet.js.map +1 -1
- package/dist/endpoints/draft.d.ts +12 -0
- package/dist/endpoints/draft.d.ts.map +1 -0
- package/dist/endpoints/draft.js +66 -0
- package/dist/endpoints/draft.js.map +1 -0
- package/dist/lib/snapshot.d.ts +15 -0
- package/dist/lib/snapshot.d.ts.map +1 -1
- package/dist/lib/snapshot.js +16 -1
- package/dist/lib/snapshot.js.map +1 -1
- package/dist/next/client.d.ts +5 -0
- package/dist/next/client.d.ts.map +1 -1
- package/dist/next/client.js +80 -0
- package/dist/next/client.js.map +1 -1
- package/dist/next/createDevPage.d.ts.map +1 -1
- package/dist/next/createDevPage.js +10 -1
- package/dist/next/createDevPage.js.map +1 -1
- package/dist/next/pageStyles.d.ts +1 -1
- package/dist/next/pageStyles.d.ts.map +1 -1
- package/dist/next/pageStyles.js +17 -0
- package/dist/next/pageStyles.js.map +1 -1
- package/dist/next/revalidatePanel.d.ts +81 -0
- package/dist/next/revalidatePanel.d.ts.map +1 -0
- package/dist/next/revalidatePanel.js +1094 -0
- package/dist/next/revalidatePanel.js.map +1 -0
- package/dist/next/views.d.ts +6 -0
- package/dist/next/views.d.ts.map +1 -1
- package/dist/next/views.js +16 -0
- package/dist/next/views.js.map +1 -1
- package/dist/plugin.d.ts +1 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +3 -0
- package/dist/plugin.js.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { devToolsEnabled } from "../options.js";
|
|
2
|
+
const TRUTHY = new Set([
|
|
3
|
+
'1',
|
|
4
|
+
'true',
|
|
5
|
+
'on'
|
|
6
|
+
]);
|
|
7
|
+
const FALSY = new Set([
|
|
8
|
+
'0',
|
|
9
|
+
'false',
|
|
10
|
+
'off'
|
|
11
|
+
]);
|
|
12
|
+
/**
|
|
13
|
+
* `GET /api/dev/draft` — Next.js draft mode as a dev-tools switch. Without params it reports
|
|
14
|
+
* `{ enabled }`; `?enable=1|0` (also `true/false`, `on/off`) flips it and reports the new state.
|
|
15
|
+
* `?to=/path` redirects (303, same-site only) instead of returning JSON, so a script or an AI
|
|
16
|
+
* agent can land on a page with drafts visible via one URL. The toolbar's Draft mode toggle
|
|
17
|
+
* calls this. Uses `draftMode()` from `next/headers` (imported lazily — the plugin entry stays
|
|
18
|
+
* loadable outside Next, e.g. under the Payload CLI), so the real `__prerender_bypass` cookie is
|
|
19
|
+
* set, exactly as a preview route would. Outside dev it 404s (see {@link devToolsEnabled}).
|
|
20
|
+
*/ export function createDraftEndpoint(enabled) {
|
|
21
|
+
return {
|
|
22
|
+
path: '/dev/draft',
|
|
23
|
+
method: 'get',
|
|
24
|
+
handler: async (req)=>{
|
|
25
|
+
if (!devToolsEnabled(enabled)) return Response.json({
|
|
26
|
+
error: 'Not found'
|
|
27
|
+
}, {
|
|
28
|
+
status: 404
|
|
29
|
+
});
|
|
30
|
+
let draft;
|
|
31
|
+
try {
|
|
32
|
+
const { draftMode } = await import("next/headers");
|
|
33
|
+
draft = await draftMode();
|
|
34
|
+
} catch {
|
|
35
|
+
return Response.json({
|
|
36
|
+
error: 'Draft mode needs a Next.js request context.'
|
|
37
|
+
}, {
|
|
38
|
+
status: 503
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const url = new URL(req.url ?? '/api/dev/draft', 'http://localhost');
|
|
42
|
+
const param = url.searchParams.get('enable')?.toLowerCase() ?? null;
|
|
43
|
+
if (param !== null && TRUTHY.has(param)) draft.enable();
|
|
44
|
+
else if (param !== null && FALSY.has(param)) draft.disable();
|
|
45
|
+
else if (param !== null) return Response.json({
|
|
46
|
+
error: `Unrecognized enable value "${param}" — use 1/0.`
|
|
47
|
+
}, {
|
|
48
|
+
status: 400
|
|
49
|
+
});
|
|
50
|
+
const rawTo = url.searchParams.get('to');
|
|
51
|
+
// Same-site paths only — no open redirect, even in dev.
|
|
52
|
+
if (rawTo) return new Response(null, {
|
|
53
|
+
status: 303,
|
|
54
|
+
headers: {
|
|
55
|
+
location: rawTo.startsWith('/') && !rawTo.startsWith('//') ? rawTo : '/'
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
const enabledNow = param === null ? draft.isEnabled : TRUTHY.has(param);
|
|
59
|
+
return Response.json({
|
|
60
|
+
enabled: enabledNow
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=draft.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/endpoints/draft.ts"],"sourcesContent":["import type { Endpoint } from 'payload'\nimport { devToolsEnabled } from '../options'\n\nconst TRUTHY = new Set(['1', 'true', 'on'])\nconst FALSY = new Set(['0', 'false', 'off'])\n\n/**\n * `GET /api/dev/draft` — Next.js draft mode as a dev-tools switch. Without params it reports\n * `{ enabled }`; `?enable=1|0` (also `true/false`, `on/off`) flips it and reports the new state.\n * `?to=/path` redirects (303, same-site only) instead of returning JSON, so a script or an AI\n * agent can land on a page with drafts visible via one URL. The toolbar's Draft mode toggle\n * calls this. Uses `draftMode()` from `next/headers` (imported lazily — the plugin entry stays\n * loadable outside Next, e.g. under the Payload CLI), so the real `__prerender_bypass` cookie is\n * set, exactly as a preview route would. Outside dev it 404s (see {@link devToolsEnabled}).\n */\nexport function createDraftEndpoint(enabled?: boolean): Endpoint {\n return {\n path: '/dev/draft',\n method: 'get',\n handler: async (req) => {\n if (!devToolsEnabled(enabled)) return Response.json({ error: 'Not found' }, { status: 404 })\n\n let draft: { isEnabled: boolean; enable: () => void; disable: () => void }\n try {\n const { draftMode } = await import('next/headers')\n draft = await draftMode()\n } catch {\n return Response.json({ error: 'Draft mode needs a Next.js request context.' }, { status: 503 })\n }\n\n const url = new URL(req.url ?? '/api/dev/draft', 'http://localhost')\n const param = url.searchParams.get('enable')?.toLowerCase() ?? null\n if (param !== null && TRUTHY.has(param)) draft.enable()\n else if (param !== null && FALSY.has(param)) draft.disable()\n else if (param !== null) return Response.json({ error: `Unrecognized enable value \"${param}\" — use 1/0.` }, { status: 400 })\n\n const rawTo = url.searchParams.get('to')\n // Same-site paths only — no open redirect, even in dev.\n if (rawTo)\n return new Response(null, { status: 303, headers: { location: rawTo.startsWith('/') && !rawTo.startsWith('//') ? rawTo : '/' } })\n\n const enabledNow = param === null ? draft.isEnabled : TRUTHY.has(param)\n return Response.json({ enabled: enabledNow })\n },\n }\n}\n"],"names":["devToolsEnabled","TRUTHY","Set","FALSY","createDraftEndpoint","enabled","path","method","handler","req","Response","json","error","status","draft","draftMode","url","URL","param","searchParams","get","toLowerCase","has","enable","disable","rawTo","headers","location","startsWith","enabledNow","isEnabled"],"mappings":"AACA,SAASA,eAAe,QAAQ,gBAAY;AAE5C,MAAMC,SAAS,IAAIC,IAAI;IAAC;IAAK;IAAQ;CAAK;AAC1C,MAAMC,QAAQ,IAAID,IAAI;IAAC;IAAK;IAAS;CAAM;AAE3C;;;;;;;;CAQC,GACD,OAAO,SAASE,oBAAoBC,OAAiB;IACnD,OAAO;QACLC,MAAM;QACNC,QAAQ;QACRC,SAAS,OAAOC;YACd,IAAI,CAACT,gBAAgBK,UAAU,OAAOK,SAASC,IAAI,CAAC;gBAAEC,OAAO;YAAY,GAAG;gBAAEC,QAAQ;YAAI;YAE1F,IAAIC;YACJ,IAAI;gBACF,MAAM,EAAEC,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC;gBACnCD,QAAQ,MAAMC;YAChB,EAAE,OAAM;gBACN,OAAOL,SAASC,IAAI,CAAC;oBAAEC,OAAO;gBAA8C,GAAG;oBAAEC,QAAQ;gBAAI;YAC/F;YAEA,MAAMG,MAAM,IAAIC,IAAIR,IAAIO,GAAG,IAAI,kBAAkB;YACjD,MAAME,QAAQF,IAAIG,YAAY,CAACC,GAAG,CAAC,WAAWC,iBAAiB;YAC/D,IAAIH,UAAU,QAAQjB,OAAOqB,GAAG,CAACJ,QAAQJ,MAAMS,MAAM;iBAChD,IAAIL,UAAU,QAAQf,MAAMmB,GAAG,CAACJ,QAAQJ,MAAMU,OAAO;iBACrD,IAAIN,UAAU,MAAM,OAAOR,SAASC,IAAI,CAAC;gBAAEC,OAAO,CAAC,2BAA2B,EAAEM,MAAM,YAAY,CAAC;YAAC,GAAG;gBAAEL,QAAQ;YAAI;YAE1H,MAAMY,QAAQT,IAAIG,YAAY,CAACC,GAAG,CAAC;YACnC,wDAAwD;YACxD,IAAIK,OACF,OAAO,IAAIf,SAAS,MAAM;gBAAEG,QAAQ;gBAAKa,SAAS;oBAAEC,UAAUF,MAAMG,UAAU,CAAC,QAAQ,CAACH,MAAMG,UAAU,CAAC,QAAQH,QAAQ;gBAAI;YAAE;YAEjI,MAAMI,aAAaX,UAAU,OAAOJ,MAAMgB,SAAS,GAAG7B,OAAOqB,GAAG,CAACJ;YACjE,OAAOR,SAASC,IAAI,CAAC;gBAAEN,SAASwB;YAAW;QAC7C;IACF;AACF"}
|
package/dist/lib/snapshot.d.ts
CHANGED
|
@@ -57,6 +57,19 @@ export type MuxSnapshot = {
|
|
|
57
57
|
total: number | null;
|
|
58
58
|
ready: number | null;
|
|
59
59
|
};
|
|
60
|
+
export type RevalidateSnapshot = {
|
|
61
|
+
/** Where the map endpoint lives (`/api/revalidate-map`), or null when disabled. */
|
|
62
|
+
endpointPath: string | null;
|
|
63
|
+
/** Tag namespace prefix ('' when unset). */
|
|
64
|
+
prefix: string;
|
|
65
|
+
/** Whether the plugin is recording reads/events in this process. */
|
|
66
|
+
observing: boolean;
|
|
67
|
+
/** Static reference-graph edge count ("can embed" relationships). */
|
|
68
|
+
edges: number;
|
|
69
|
+
/** Materialized cached reads / bust events observed so far. */
|
|
70
|
+
reads: number;
|
|
71
|
+
events: number;
|
|
72
|
+
};
|
|
60
73
|
/** Everything `GET /api/dev` reports: environment, per-plugin panels (null = plugin not
|
|
61
74
|
* installed), and doc counts for every collection. Built fresh on each request — dev only. */
|
|
62
75
|
export type DevSnapshot = {
|
|
@@ -74,12 +87,14 @@ export type DevSnapshot = {
|
|
|
74
87
|
icons: boolean;
|
|
75
88
|
fonts: boolean;
|
|
76
89
|
mux: boolean;
|
|
90
|
+
revalidate: boolean;
|
|
77
91
|
};
|
|
78
92
|
seed: SeedSnapshot | null;
|
|
79
93
|
images: ImagesSnapshot | null;
|
|
80
94
|
icons: IconsSnapshot | null;
|
|
81
95
|
fonts: FontsSnapshot | null;
|
|
82
96
|
mux: MuxSnapshot | null;
|
|
97
|
+
revalidate: RevalidateSnapshot | null;
|
|
83
98
|
collections: CollectionCount[];
|
|
84
99
|
globals: string[];
|
|
85
100
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/lib/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA8B,OAAO,EAAS,MAAM,SAAS,CAAA;AAEzE;wDACwD;AACxD,MAAM,MAAM,eAAe,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAA;AAEpE,MAAM,MAAM,YAAY,GAAG;IACzB,kFAAkF;IAClF,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,YAAY,GAAG,QAAQ,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACjF,iGAAiG;IACjG,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,qDAAqD;IACrD,MAAM,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,6EAA6E;IAC7E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB;sFACkF;IAClF,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,EAAE,CAAA;CAC1E,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,6FAA6F;IAC7F,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAA;IACpC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAA;AAE7G;+FAC+F;AAC/F,MAAM,MAAM,WAAW,GAAG;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,GAAG,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7C,UAAU,EAAE,MAAM,CAAA;IAClB,4FAA4F;IAC5F,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/lib/snapshot.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/snapshot.js
CHANGED
|
@@ -142,6 +142,18 @@ const muxSnapshot = async (payload, marker)=>{
|
|
|
142
142
|
})
|
|
143
143
|
};
|
|
144
144
|
};
|
|
145
|
+
const revalidateSnapshot = (marker)=>{
|
|
146
|
+
const inspect = globalThis[Symbol.for('pro-laico.payload-revalidate.inspect')];
|
|
147
|
+
const data = inspect?.();
|
|
148
|
+
return {
|
|
149
|
+
endpointPath: marker.endpointPath ?? null,
|
|
150
|
+
prefix: data?.prefix ?? '',
|
|
151
|
+
observing: data?.observing ?? false,
|
|
152
|
+
edges: data?.graph.edges.length ?? 0,
|
|
153
|
+
reads: data?.reads.length ?? 0,
|
|
154
|
+
events: data?.events.length ?? 0
|
|
155
|
+
};
|
|
156
|
+
};
|
|
145
157
|
/** Build the full dev snapshot from a booted Payload instance. Sibling @pro-laico plugins are
|
|
146
158
|
* discovered through their `config.custom` markers — no imports, so none of them are required. */ export async function buildDevSnapshot(payload) {
|
|
147
159
|
const custom = payload.config.custom ?? {};
|
|
@@ -150,6 +162,7 @@ const muxSnapshot = async (payload, marker)=>{
|
|
|
150
162
|
const iconsMarker = custom.payloadIcons;
|
|
151
163
|
const fontsMarker = custom.payloadFonts;
|
|
152
164
|
const muxMarker = custom.payloadMux;
|
|
165
|
+
const revalidateMarker = custom.payloadRevalidate;
|
|
153
166
|
const collections = [];
|
|
154
167
|
for (const c of payload.config.collections)collections.push({
|
|
155
168
|
slug: c.slug,
|
|
@@ -168,13 +181,15 @@ const muxSnapshot = async (payload, marker)=>{
|
|
|
168
181
|
images: !!imagesMarker,
|
|
169
182
|
icons: !!iconsMarker,
|
|
170
183
|
fonts: !!fontsMarker,
|
|
171
|
-
mux: !!muxMarker
|
|
184
|
+
mux: !!muxMarker,
|
|
185
|
+
revalidate: !!revalidateMarker
|
|
172
186
|
},
|
|
173
187
|
seed: seedMarker ? await seedSnapshot(payload, seedMarker) : null,
|
|
174
188
|
images: imagesMarker ? await imagesSnapshot(payload, imagesMarker) : null,
|
|
175
189
|
icons: iconsMarker ? await iconsSnapshot(payload, iconsMarker) : null,
|
|
176
190
|
fonts: fontsMarker ? await fontsSnapshot(payload, fontsMarker) : null,
|
|
177
191
|
mux: muxMarker ? await muxSnapshot(payload, muxMarker) : null,
|
|
192
|
+
revalidate: revalidateMarker ? revalidateSnapshot(revalidateMarker) : null,
|
|
178
193
|
collections,
|
|
179
194
|
globals: (payload.config.globals ?? []).map((g)=>g.slug)
|
|
180
195
|
};
|
package/dist/lib/snapshot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/snapshot.ts"],"sourcesContent":["import type { CollectionSlug, GlobalSlug, Payload, Where } from 'payload'\n\n/** One collection's row in the snapshot. `count` is null when counting failed (e.g. a slug the\n * adapter can't count) — distinct from an honest 0. */\nexport type CollectionCount = { slug: string; count: number | null }\n\nexport type SeedSnapshot = {\n /** Whether `ENABLE_SEED=true` is set — the kill switch every seed path checks. */\n enabled: boolean\n endpoint: string\n definitions: { slug: string; kind: 'collection' | 'global'; disabled?: string }[]\n /** Doc counts per collection-kind definition slug (globals always exist, so they're skipped). */\n counts: Record<string, number>\n totalDocs: number\n /** True once any seeded collection has documents. */\n seeded: boolean\n}\n\nexport type ImagesSnapshot = {\n sourceSlug: string\n variantSlug: string | null\n basePath: string\n sourceCount: number | null\n variantCount: number | null\n}\n\nexport type IconsSnapshot = {\n iconSlug: string\n iconSetSlug: string | null\n iconCount: number | null\n /** Title of the active (published) icon set, or null when none is active. */\n activeSet: string | null\n /** Runtime misses from the `iconRequest` diagnostic collection — names requested in code that\n * did not resolve through the active set. Empty when request tracking is off. */\n misses: { name: string; count: number; lastRequestedAt: string | null }[]\n}\n\nexport type FontsSnapshot = {\n fontSlug: string\n fontSetSlug: string | null\n fontOptimizedSlug: string | null\n familyKeys: string[]\n /** Active typeface title per family slot (from the `fontSet` global), or null when unset. */\n slots: Record<string, string | null>\n fontCount: number | null\n exportPath: string\n}\n\nexport type MuxSnapshot = { slug: string; credentialed: boolean; total: number | null; ready: number | null }\n\n/** Everything `GET /api/dev` reports: environment, per-plugin panels (null = plugin not\n * installed), and doc counts for every collection. Built fresh on each request — dev only. */\nexport type DevSnapshot = {\n generatedAt: string\n env: { nodeEnv: string; nodeVersion: string }\n adminRoute: string\n /** Where the host mounts the `createDevPage` catch-all (the plugin's `devRoute` option). */\n devRoute: string\n plugins: { seed: boolean; images: boolean; icons: boolean; fonts: boolean; mux: boolean }\n seed: SeedSnapshot | null\n images: ImagesSnapshot | null\n icons: IconsSnapshot | null\n fonts: FontsSnapshot | null\n mux: MuxSnapshot | null\n collections: CollectionCount[]\n globals: string[]\n}\n\nconst countDocs = async (payload: Payload, slug: string, where?: Where): Promise<number | null> => {\n try {\n return (await payload.count({ collection: slug as CollectionSlug, overrideAccess: true, ...(where ? { where } : {}) })).totalDocs\n } catch {\n return null\n }\n}\n\ntype SeedMarker = { options?: { definitions?: { slug: string; kind: 'collection' | 'global'; disabled?: string | boolean }[] } }\n\nconst seedSnapshot = async (payload: Payload, marker: SeedMarker): Promise<SeedSnapshot> => {\n const definitions = (marker.options?.definitions ?? []).map((d) => ({\n slug: d.slug,\n kind: d.kind,\n ...(d.disabled ? { disabled: typeof d.disabled === 'string' ? d.disabled : 'disabled' } : {}),\n }))\n const counts: Record<string, number> = {}\n for (const d of definitions) {\n if (d.kind !== 'collection') continue\n const n = await countDocs(payload, d.slug)\n if (n !== null) counts[d.slug] = n\n }\n const totalDocs = Object.values(counts).reduce((sum, n) => sum + n, 0)\n return { enabled: process.env.ENABLE_SEED === 'true', endpoint: '/api/seed', definitions, counts, totalDocs, seeded: totalDocs > 0 }\n}\n\ntype ImagesMarker = { sourceSlug?: string; variantSlug?: string | null; basePath?: string }\n\nconst imagesSnapshot = async (payload: Payload, marker: ImagesMarker): Promise<ImagesSnapshot> => {\n const sourceSlug = marker.sourceSlug ?? 'images'\n const variantSlug = marker.variantSlug ?? null\n return {\n sourceSlug,\n variantSlug,\n // The marker stores the endpoint-relative path ('/img'); report it as requested (/api/img).\n basePath: `/api${marker.basePath ?? '/img'}`,\n sourceCount: await countDocs(payload, sourceSlug),\n variantCount: variantSlug ? await countDocs(payload, variantSlug) : null,\n }\n}\n\ntype IconsMarker = { iconSlug?: string; iconSetSlug?: string | null; iconRequestSlug?: string | null }\n\nconst iconsSnapshot = async (payload: Payload, marker: IconsMarker): Promise<IconsSnapshot> => {\n const iconSlug = marker.iconSlug ?? 'icon'\n const iconSetSlug = marker.iconSetSlug ?? null\n\n let activeSet: string | null = null\n if (iconSetSlug) {\n try {\n const res = await payload.find({\n collection: iconSetSlug as CollectionSlug,\n where: { active: { equals: true } },\n limit: 1,\n depth: 0,\n overrideAccess: true,\n pagination: false,\n })\n const doc = res.docs[0] as { title?: string } | undefined\n activeSet = doc?.title ?? null\n } catch {}\n }\n\n let misses: IconsSnapshot['misses'] = []\n if (marker.iconRequestSlug) {\n try {\n const res = await payload.find({\n collection: marker.iconRequestSlug as CollectionSlug,\n sort: '-count',\n limit: 20,\n depth: 0,\n overrideAccess: true,\n pagination: false,\n })\n misses = (res.docs as { name?: string; count?: number; lastRequestedAt?: string }[]).flatMap((d) =>\n d.name ? [{ name: d.name, count: d.count ?? 1, lastRequestedAt: d.lastRequestedAt ?? null }] : [],\n )\n } catch {}\n }\n\n return { iconSlug, iconSetSlug, iconCount: await countDocs(payload, iconSlug), activeSet, misses }\n}\n\ntype FontsMarker = {\n fontSlug?: string\n fontSetSlug?: string | null\n fontOptimizedSlug?: string | null\n familyKeys?: string[]\n exportPath?: string\n}\n\nconst fontsSnapshot = async (payload: Payload, marker: FontsMarker): Promise<FontsSnapshot> => {\n const fontSlug = marker.fontSlug ?? 'font'\n const fontSetSlug = marker.fontSetSlug ?? null\n const familyKeys = marker.familyKeys ?? []\n\n const slots: Record<string, string | null> = {}\n for (const key of familyKeys) slots[key] = null\n if (fontSetSlug && familyKeys.length) {\n try {\n // Through `unknown`: in an app context `findGlobal` returns the app's generated global type.\n const set = (await payload.findGlobal({ slug: fontSetSlug as GlobalSlug, depth: 1, overrideAccess: true })) as unknown as Record<\n string,\n unknown\n >\n for (const key of familyKeys) {\n const value = set[key]\n slots[key] = value && typeof value === 'object' && 'title' in value ? ((value as { title?: string }).title ?? null) : null\n }\n } catch {}\n }\n\n return {\n fontSlug,\n fontSetSlug,\n fontOptimizedSlug: marker.fontOptimizedSlug ?? null,\n familyKeys,\n slots,\n fontCount: await countDocs(payload, fontSlug),\n exportPath: `/api${marker.exportPath ?? '/fonts/export'}`,\n }\n}\n\ntype MuxMarker = { options?: { extendCollection?: string } }\n\nconst muxSnapshot = async (payload: Payload, marker: MuxMarker): Promise<MuxSnapshot> => {\n const slug = marker.options?.extendCollection ?? 'mux-video'\n const collection = payload.config.collections.find((c) => c.slug === slug)\n return {\n slug,\n // The mux plugin marks its collection `custom.seedDisabled` when MUX_TOKEN_ID/SECRET are absent.\n credentialed: !collection?.custom?.seedDisabled,\n total: await countDocs(payload, slug),\n ready: await countDocs(payload, slug, { status: { equals: 'ready' } }),\n }\n}\n\n/** Build the full dev snapshot from a booted Payload instance. Sibling @pro-laico plugins are\n * discovered through their `config.custom` markers — no imports, so none of them are required. */\nexport async function buildDevSnapshot(payload: Payload): Promise<DevSnapshot> {\n const custom = (payload.config.custom ?? {}) as Record<string, Record<string, unknown> | undefined>\n const seedMarker = custom.payloadSeed\n const imagesMarker = custom.payloadImages\n const iconsMarker = custom.payloadIcons\n const fontsMarker = custom.payloadFonts\n const muxMarker = custom.payloadMux\n\n const collections: CollectionCount[] = []\n for (const c of payload.config.collections) collections.push({ slug: c.slug, count: await countDocs(payload, c.slug) })\n\n return {\n generatedAt: new Date().toISOString(),\n env: { nodeEnv: process.env.NODE_ENV ?? 'development', nodeVersion: process.version },\n adminRoute: payload.config.routes?.admin ?? '/admin',\n devRoute: (custom.payloadDevTools?.devRoute as string | undefined) ?? '/dev',\n plugins: { seed: !!seedMarker, images: !!imagesMarker, icons: !!iconsMarker, fonts: !!fontsMarker, mux: !!muxMarker },\n seed: seedMarker ? await seedSnapshot(payload, seedMarker) : null,\n images: imagesMarker ? await imagesSnapshot(payload, imagesMarker) : null,\n icons: iconsMarker ? await iconsSnapshot(payload, iconsMarker) : null,\n fonts: fontsMarker ? await fontsSnapshot(payload, fontsMarker) : null,\n mux: muxMarker ? await muxSnapshot(payload, muxMarker) : null,\n collections,\n globals: (payload.config.globals ?? []).map((g) => g.slug),\n }\n}\n"],"names":["countDocs","payload","slug","where","count","collection","overrideAccess","totalDocs","seedSnapshot","marker","definitions","options","map","d","kind","disabled","counts","n","Object","values","reduce","sum","enabled","process","env","ENABLE_SEED","endpoint","seeded","imagesSnapshot","sourceSlug","variantSlug","basePath","sourceCount","variantCount","iconsSnapshot","iconSlug","iconSetSlug","activeSet","res","find","active","equals","limit","depth","pagination","doc","docs","title","misses","iconRequestSlug","sort","flatMap","name","lastRequestedAt","iconCount","fontsSnapshot","fontSlug","fontSetSlug","familyKeys","slots","key","length","set","findGlobal","value","fontOptimizedSlug","fontCount","exportPath","muxSnapshot","extendCollection","config","collections","c","credentialed","custom","seedDisabled","total","ready","status","buildDevSnapshot","seedMarker","payloadSeed","imagesMarker","payloadImages","iconsMarker","payloadIcons","fontsMarker","payloadFonts","muxMarker","payloadMux","push","generatedAt","Date","toISOString","nodeEnv","NODE_ENV","nodeVersion","version","adminRoute","routes","admin","devRoute","payloadDevTools","plugins","seed","images","icons","fonts","mux","globals","g"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/lib/snapshot.ts"],"sourcesContent":["import type { CollectionSlug, GlobalSlug, Payload, Where } from 'payload'\n\n/** One collection's row in the snapshot. `count` is null when counting failed (e.g. a slug the\n * adapter can't count) — distinct from an honest 0. */\nexport type CollectionCount = { slug: string; count: number | null }\n\nexport type SeedSnapshot = {\n /** Whether `ENABLE_SEED=true` is set — the kill switch every seed path checks. */\n enabled: boolean\n endpoint: string\n definitions: { slug: string; kind: 'collection' | 'global'; disabled?: string }[]\n /** Doc counts per collection-kind definition slug (globals always exist, so they're skipped). */\n counts: Record<string, number>\n totalDocs: number\n /** True once any seeded collection has documents. */\n seeded: boolean\n}\n\nexport type ImagesSnapshot = {\n sourceSlug: string\n variantSlug: string | null\n basePath: string\n sourceCount: number | null\n variantCount: number | null\n}\n\nexport type IconsSnapshot = {\n iconSlug: string\n iconSetSlug: string | null\n iconCount: number | null\n /** Title of the active (published) icon set, or null when none is active. */\n activeSet: string | null\n /** Runtime misses from the `iconRequest` diagnostic collection — names requested in code that\n * did not resolve through the active set. Empty when request tracking is off. */\n misses: { name: string; count: number; lastRequestedAt: string | null }[]\n}\n\nexport type FontsSnapshot = {\n fontSlug: string\n fontSetSlug: string | null\n fontOptimizedSlug: string | null\n familyKeys: string[]\n /** Active typeface title per family slot (from the `fontSet` global), or null when unset. */\n slots: Record<string, string | null>\n fontCount: number | null\n exportPath: string\n}\n\nexport type MuxSnapshot = { slug: string; credentialed: boolean; total: number | null; ready: number | null }\n\nexport type RevalidateSnapshot = {\n /** Where the map endpoint lives (`/api/revalidate-map`), or null when disabled. */\n endpointPath: string | null\n /** Tag namespace prefix ('' when unset). */\n prefix: string\n /** Whether the plugin is recording reads/events in this process. */\n observing: boolean\n /** Static reference-graph edge count (\"can embed\" relationships). */\n edges: number\n /** Materialized cached reads / bust events observed so far. */\n reads: number\n events: number\n}\n\n/** Everything `GET /api/dev` reports: environment, per-plugin panels (null = plugin not\n * installed), and doc counts for every collection. Built fresh on each request — dev only. */\nexport type DevSnapshot = {\n generatedAt: string\n env: { nodeEnv: string; nodeVersion: string }\n adminRoute: string\n /** Where the host mounts the `createDevPage` catch-all (the plugin's `devRoute` option). */\n devRoute: string\n plugins: { seed: boolean; images: boolean; icons: boolean; fonts: boolean; mux: boolean; revalidate: boolean }\n seed: SeedSnapshot | null\n images: ImagesSnapshot | null\n icons: IconsSnapshot | null\n fonts: FontsSnapshot | null\n mux: MuxSnapshot | null\n revalidate: RevalidateSnapshot | null\n collections: CollectionCount[]\n globals: string[]\n}\n\nconst countDocs = async (payload: Payload, slug: string, where?: Where): Promise<number | null> => {\n try {\n return (await payload.count({ collection: slug as CollectionSlug, overrideAccess: true, ...(where ? { where } : {}) })).totalDocs\n } catch {\n return null\n }\n}\n\ntype SeedMarker = { options?: { definitions?: { slug: string; kind: 'collection' | 'global'; disabled?: string | boolean }[] } }\n\nconst seedSnapshot = async (payload: Payload, marker: SeedMarker): Promise<SeedSnapshot> => {\n const definitions = (marker.options?.definitions ?? []).map((d) => ({\n slug: d.slug,\n kind: d.kind,\n ...(d.disabled ? { disabled: typeof d.disabled === 'string' ? d.disabled : 'disabled' } : {}),\n }))\n const counts: Record<string, number> = {}\n for (const d of definitions) {\n if (d.kind !== 'collection') continue\n const n = await countDocs(payload, d.slug)\n if (n !== null) counts[d.slug] = n\n }\n const totalDocs = Object.values(counts).reduce((sum, n) => sum + n, 0)\n return { enabled: process.env.ENABLE_SEED === 'true', endpoint: '/api/seed', definitions, counts, totalDocs, seeded: totalDocs > 0 }\n}\n\ntype ImagesMarker = { sourceSlug?: string; variantSlug?: string | null; basePath?: string }\n\nconst imagesSnapshot = async (payload: Payload, marker: ImagesMarker): Promise<ImagesSnapshot> => {\n const sourceSlug = marker.sourceSlug ?? 'images'\n const variantSlug = marker.variantSlug ?? null\n return {\n sourceSlug,\n variantSlug,\n // The marker stores the endpoint-relative path ('/img'); report it as requested (/api/img).\n basePath: `/api${marker.basePath ?? '/img'}`,\n sourceCount: await countDocs(payload, sourceSlug),\n variantCount: variantSlug ? await countDocs(payload, variantSlug) : null,\n }\n}\n\ntype IconsMarker = { iconSlug?: string; iconSetSlug?: string | null; iconRequestSlug?: string | null }\n\nconst iconsSnapshot = async (payload: Payload, marker: IconsMarker): Promise<IconsSnapshot> => {\n const iconSlug = marker.iconSlug ?? 'icon'\n const iconSetSlug = marker.iconSetSlug ?? null\n\n let activeSet: string | null = null\n if (iconSetSlug) {\n try {\n const res = await payload.find({\n collection: iconSetSlug as CollectionSlug,\n where: { active: { equals: true } },\n limit: 1,\n depth: 0,\n overrideAccess: true,\n pagination: false,\n })\n const doc = res.docs[0] as { title?: string } | undefined\n activeSet = doc?.title ?? null\n } catch {}\n }\n\n let misses: IconsSnapshot['misses'] = []\n if (marker.iconRequestSlug) {\n try {\n const res = await payload.find({\n collection: marker.iconRequestSlug as CollectionSlug,\n sort: '-count',\n limit: 20,\n depth: 0,\n overrideAccess: true,\n pagination: false,\n })\n misses = (res.docs as { name?: string; count?: number; lastRequestedAt?: string }[]).flatMap((d) =>\n d.name ? [{ name: d.name, count: d.count ?? 1, lastRequestedAt: d.lastRequestedAt ?? null }] : [],\n )\n } catch {}\n }\n\n return { iconSlug, iconSetSlug, iconCount: await countDocs(payload, iconSlug), activeSet, misses }\n}\n\ntype FontsMarker = {\n fontSlug?: string\n fontSetSlug?: string | null\n fontOptimizedSlug?: string | null\n familyKeys?: string[]\n exportPath?: string\n}\n\nconst fontsSnapshot = async (payload: Payload, marker: FontsMarker): Promise<FontsSnapshot> => {\n const fontSlug = marker.fontSlug ?? 'font'\n const fontSetSlug = marker.fontSetSlug ?? null\n const familyKeys = marker.familyKeys ?? []\n\n const slots: Record<string, string | null> = {}\n for (const key of familyKeys) slots[key] = null\n if (fontSetSlug && familyKeys.length) {\n try {\n // Through `unknown`: in an app context `findGlobal` returns the app's generated global type.\n const set = (await payload.findGlobal({ slug: fontSetSlug as GlobalSlug, depth: 1, overrideAccess: true })) as unknown as Record<\n string,\n unknown\n >\n for (const key of familyKeys) {\n const value = set[key]\n slots[key] = value && typeof value === 'object' && 'title' in value ? ((value as { title?: string }).title ?? null) : null\n }\n } catch {}\n }\n\n return {\n fontSlug,\n fontSetSlug,\n fontOptimizedSlug: marker.fontOptimizedSlug ?? null,\n familyKeys,\n slots,\n fontCount: await countDocs(payload, fontSlug),\n exportPath: `/api${marker.exportPath ?? '/fonts/export'}`,\n }\n}\n\ntype MuxMarker = { options?: { extendCollection?: string } }\n\nconst muxSnapshot = async (payload: Payload, marker: MuxMarker): Promise<MuxSnapshot> => {\n const slug = marker.options?.extendCollection ?? 'mux-video'\n const collection = payload.config.collections.find((c) => c.slug === slug)\n return {\n slug,\n // The mux plugin marks its collection `custom.seedDisabled` when MUX_TOKEN_ID/SECRET are absent.\n credentialed: !collection?.custom?.seedDisabled,\n total: await countDocs(payload, slug),\n ready: await countDocs(payload, slug, { status: { equals: 'ready' } }),\n }\n}\n\ntype RevalidateMarker = { endpointPath?: string | null }\n\n/** The live-inspection shape payload-revalidate stashes on its shared symbol slot (functions\n * can't ride `config.custom` — it feeds the serialized client config). Structural — no import. */\ntype RevalidateInspection = { graph: { edges: unknown[] }; prefix: string; observing: boolean; reads: unknown[]; events: unknown[] }\n\nconst revalidateSnapshot = (marker: RevalidateMarker): RevalidateSnapshot => {\n const inspect = (globalThis as Record<symbol, unknown>)[Symbol.for('pro-laico.payload-revalidate.inspect')] as\n | (() => RevalidateInspection)\n | undefined\n const data = inspect?.()\n return {\n endpointPath: marker.endpointPath ?? null,\n prefix: data?.prefix ?? '',\n observing: data?.observing ?? false,\n edges: data?.graph.edges.length ?? 0,\n reads: data?.reads.length ?? 0,\n events: data?.events.length ?? 0,\n }\n}\n\n/** Build the full dev snapshot from a booted Payload instance. Sibling @pro-laico plugins are\n * discovered through their `config.custom` markers — no imports, so none of them are required. */\nexport async function buildDevSnapshot(payload: Payload): Promise<DevSnapshot> {\n const custom = (payload.config.custom ?? {}) as Record<string, Record<string, unknown> | undefined>\n const seedMarker = custom.payloadSeed\n const imagesMarker = custom.payloadImages\n const iconsMarker = custom.payloadIcons\n const fontsMarker = custom.payloadFonts\n const muxMarker = custom.payloadMux\n const revalidateMarker = custom.payloadRevalidate\n\n const collections: CollectionCount[] = []\n for (const c of payload.config.collections) collections.push({ slug: c.slug, count: await countDocs(payload, c.slug) })\n\n return {\n generatedAt: new Date().toISOString(),\n env: { nodeEnv: process.env.NODE_ENV ?? 'development', nodeVersion: process.version },\n adminRoute: payload.config.routes?.admin ?? '/admin',\n devRoute: (custom.payloadDevTools?.devRoute as string | undefined) ?? '/dev',\n plugins: {\n seed: !!seedMarker,\n images: !!imagesMarker,\n icons: !!iconsMarker,\n fonts: !!fontsMarker,\n mux: !!muxMarker,\n revalidate: !!revalidateMarker,\n },\n seed: seedMarker ? await seedSnapshot(payload, seedMarker) : null,\n images: imagesMarker ? await imagesSnapshot(payload, imagesMarker) : null,\n icons: iconsMarker ? await iconsSnapshot(payload, iconsMarker) : null,\n fonts: fontsMarker ? await fontsSnapshot(payload, fontsMarker) : null,\n mux: muxMarker ? await muxSnapshot(payload, muxMarker) : null,\n revalidate: revalidateMarker ? revalidateSnapshot(revalidateMarker) : null,\n collections,\n globals: (payload.config.globals ?? []).map((g) => g.slug),\n }\n}\n"],"names":["countDocs","payload","slug","where","count","collection","overrideAccess","totalDocs","seedSnapshot","marker","definitions","options","map","d","kind","disabled","counts","n","Object","values","reduce","sum","enabled","process","env","ENABLE_SEED","endpoint","seeded","imagesSnapshot","sourceSlug","variantSlug","basePath","sourceCount","variantCount","iconsSnapshot","iconSlug","iconSetSlug","activeSet","res","find","active","equals","limit","depth","pagination","doc","docs","title","misses","iconRequestSlug","sort","flatMap","name","lastRequestedAt","iconCount","fontsSnapshot","fontSlug","fontSetSlug","familyKeys","slots","key","length","set","findGlobal","value","fontOptimizedSlug","fontCount","exportPath","muxSnapshot","extendCollection","config","collections","c","credentialed","custom","seedDisabled","total","ready","status","revalidateSnapshot","inspect","globalThis","Symbol","for","data","endpointPath","prefix","observing","edges","graph","reads","events","buildDevSnapshot","seedMarker","payloadSeed","imagesMarker","payloadImages","iconsMarker","payloadIcons","fontsMarker","payloadFonts","muxMarker","payloadMux","revalidateMarker","payloadRevalidate","push","generatedAt","Date","toISOString","nodeEnv","NODE_ENV","nodeVersion","version","adminRoute","routes","admin","devRoute","payloadDevTools","plugins","seed","images","icons","fonts","mux","revalidate","globals","g"],"mappings":"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"}
|
package/dist/next/client.d.ts
CHANGED
|
@@ -24,4 +24,9 @@ export declare function IconSetSwitcher({ sets }: {
|
|
|
24
24
|
active: boolean;
|
|
25
25
|
}[];
|
|
26
26
|
}): import("react").JSX.Element;
|
|
27
|
+
/** The `/dev/revalidate` manual bust box — POST one tag to payload-revalidate's map
|
|
28
|
+
* endpoint and refresh, so the event log shows the manual bust immediately. */
|
|
29
|
+
export declare function BustTagCard({ endpointPath }: {
|
|
30
|
+
endpointPath: string;
|
|
31
|
+
}): import("react").JSX.Element;
|
|
27
32
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/next/client.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAI/C;8FAC8F;AAC9F,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,+BAmFxF;AAED;;mBAEmB;AACnB,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,KAAK,EACL,MAAM,EACN,MAAM,GACP,EAAE;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,aAAa,EAAE,CAAA;CACxB,+BAkDA;AAED;oFACoF;AACpF,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;CAAE,+BA0C5G"}
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/next/client.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAI/C;8FAC8F;AAC9F,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,+BAmFxF;AAED;;mBAEmB;AACnB,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,KAAK,EACL,MAAM,EACN,MAAM,GACP,EAAE;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,aAAa,EAAE,CAAA;CACxB,+BAkDA;AAED;oFACoF;AACpF,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;CAAE,+BA0C5G;AAED;gFACgF;AAChF,wBAAgB,WAAW,CAAC,EAAE,YAAY,EAAE,EAAE;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,+BAqDrE"}
|
package/dist/next/client.js
CHANGED
|
@@ -271,5 +271,85 @@ import { useState } from "react";
|
|
|
271
271
|
]
|
|
272
272
|
});
|
|
273
273
|
}
|
|
274
|
+
/** The `/dev/revalidate` manual bust box — POST one tag to payload-revalidate's map
|
|
275
|
+
* endpoint and refresh, so the event log shows the manual bust immediately. */ export function BustTagCard({ endpointPath }) {
|
|
276
|
+
const router = useRouter();
|
|
277
|
+
const [tag, setTag] = useState('');
|
|
278
|
+
const [busy, setBusy] = useState(false);
|
|
279
|
+
const [error, setError] = useState(null);
|
|
280
|
+
const bust = async ()=>{
|
|
281
|
+
if (!tag.trim()) return;
|
|
282
|
+
setBusy(true);
|
|
283
|
+
setError(null);
|
|
284
|
+
try {
|
|
285
|
+
const res = await fetch(endpointPath, {
|
|
286
|
+
method: 'POST',
|
|
287
|
+
credentials: 'include',
|
|
288
|
+
headers: {
|
|
289
|
+
'content-type': 'application/json'
|
|
290
|
+
},
|
|
291
|
+
body: JSON.stringify({
|
|
292
|
+
tag: tag.trim()
|
|
293
|
+
})
|
|
294
|
+
});
|
|
295
|
+
if (res.ok) {
|
|
296
|
+
setTag('');
|
|
297
|
+
router.refresh();
|
|
298
|
+
} else setError((await res.json().catch(()=>null))?.error ?? `Failed (HTTP ${res.status}).`);
|
|
299
|
+
} catch {
|
|
300
|
+
setError('Request failed — is the dev server running?');
|
|
301
|
+
}
|
|
302
|
+
setBusy(false);
|
|
303
|
+
};
|
|
304
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
305
|
+
className: "pdtp-card",
|
|
306
|
+
style: {
|
|
307
|
+
marginTop: 20
|
|
308
|
+
},
|
|
309
|
+
children: [
|
|
310
|
+
/*#__PURE__*/ _jsxs("h2", {
|
|
311
|
+
children: [
|
|
312
|
+
"Bust a tag ",
|
|
313
|
+
/*#__PURE__*/ _jsx("span", {
|
|
314
|
+
className: "pdtp-kind",
|
|
315
|
+
children: "manual"
|
|
316
|
+
})
|
|
317
|
+
]
|
|
318
|
+
}),
|
|
319
|
+
/*#__PURE__*/ _jsxs("form", {
|
|
320
|
+
style: {
|
|
321
|
+
display: 'flex',
|
|
322
|
+
gap: 8
|
|
323
|
+
},
|
|
324
|
+
onSubmit: (e)=>{
|
|
325
|
+
e.preventDefault();
|
|
326
|
+
void bust();
|
|
327
|
+
},
|
|
328
|
+
children: [
|
|
329
|
+
/*#__PURE__*/ _jsx("input", {
|
|
330
|
+
className: "pdtp-code",
|
|
331
|
+
style: {
|
|
332
|
+
flex: 1,
|
|
333
|
+
padding: '6px 10px'
|
|
334
|
+
},
|
|
335
|
+
placeholder: "posts:42 · posts · global:header · all",
|
|
336
|
+
value: tag,
|
|
337
|
+
onChange: (e)=>setTag(e.target.value)
|
|
338
|
+
}),
|
|
339
|
+
/*#__PURE__*/ _jsx("button", {
|
|
340
|
+
type: "submit",
|
|
341
|
+
className: "pdtp-btn pdtp-btn-primary",
|
|
342
|
+
disabled: busy || !tag.trim(),
|
|
343
|
+
children: busy ? 'Busting…' : 'Bust'
|
|
344
|
+
})
|
|
345
|
+
]
|
|
346
|
+
}),
|
|
347
|
+
error ? /*#__PURE__*/ _jsx("div", {
|
|
348
|
+
className: "pdtp-error",
|
|
349
|
+
children: error
|
|
350
|
+
}) : null
|
|
351
|
+
]
|
|
352
|
+
});
|
|
353
|
+
}
|
|
274
354
|
|
|
275
355
|
//# sourceMappingURL=client.js.map
|
package/dist/next/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/next/client.tsx"],"sourcesContent":["'use client'\n\nimport { useRouter } from 'next/navigation'\nimport { useState } from 'react'\nimport type { SeedSnapshot } from '../lib/snapshot'\nimport type { SpecimenStyle } from './specimen'\n\ntype SeedError = { error: string; issues?: string[] }\n\n/** The `/dev` index's seed controls — same flow as the toolbar's Seed view: POST the seed\n * plugin's own endpoint, two-click confirm when destructive, surface `{ error, issues }`. */\nexport function SeedCard({ seed, adminRoute }: { seed: SeedSnapshot; adminRoute: string }) {\n const router = useRouter()\n const [running, setRunning] = useState(false)\n const [confirming, setConfirming] = useState(false)\n const [error, setError] = useState<SeedError | null>(null)\n\n const runSeed = async () => {\n setRunning(true)\n setError(null)\n try {\n const res = await fetch('/api/seed', { method: 'POST', credentials: 'include' })\n if (res.ok) {\n setConfirming(false)\n router.refresh()\n } else {\n const body = (await res.json().catch(() => null)) as SeedError | null\n setError(body?.error ? body : { error: `Seed failed (HTTP ${res.status}).` })\n setConfirming(false)\n }\n } catch {\n setError({ error: 'Seed request failed — is the dev server running?' })\n setConfirming(false)\n }\n setRunning(false)\n }\n\n return (\n <div className=\"pdtp-card\">\n <h2>\n {seed.seeded ? `Seeded — ${seed.totalDocs} docs` : 'Not seeded'}\n {!seed.enabled ? <span className=\"pdtp-kind pdtp-warn\">locked</span> : <span className=\"pdtp-kind\">seed</span>}\n </h2>\n <table className=\"pdtp-table\">\n <tbody>\n {seed.definitions.map((d) => (\n <tr key={d.slug}>\n <td>\n {d.slug}\n {d.disabled ? <span className=\"pdtp-warn\"> · skipped</span> : null}\n </td>\n <td>{d.kind === 'global' ? 'global' : (seed.counts[d.slug] ?? 0)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n <div style={{ marginTop: 12, display: 'flex', gap: 8 }}>\n <button\n type=\"button\"\n className={`pdtp-btn ${seed.seeded ? 'pdtp-btn-danger' : 'pdtp-btn-primary'}`}\n disabled={running}\n onClick={() => (seed.seeded && !confirming ? setConfirming(true) : void runSeed())}\n >\n {running ? 'Seeding…' : confirming ? 'Destructive — click again' : seed.seeded ? 'Reseed' : 'Seed the database'}\n </button>\n {confirming ? (\n <button type=\"button\" className=\"pdtp-btn\" onClick={() => setConfirming(false)}>\n Cancel\n </button>\n ) : null}\n </div>\n {!seed.enabled ? (\n <p className=\"pdtp-note\">\n Set <span className=\"pdtp-code\">ENABLE_SEED=true</span> in <span className=\"pdtp-code\">.env.local</span> — the seed wipes seeded\n collections, so it's off by default.\n </p>\n ) : null}\n <p className=\"pdtp-note\">\n Needs a logged-in <a href={adminRoute}>admin</a> user · CLI: <span className=\"pdtp-code\">ENABLE_SEED=true pnpm seed</span>\n </p>\n {error ? (\n <div className=\"pdtp-error\">\n {error.error}\n {error.issues?.length ? (\n <ul>\n {error.issues.map((issue) => (\n <li key={issue}>{issue}</li>\n ))}\n </ul>\n ) : null}\n </div>\n ) : null}\n </div>\n )\n}\n\n/** The `/dev/fonts` interactive specimen — the sample renders in the family's `--font-set*`\n * variable at the clicked weight/style. Only weights and styles the typeface actually serves\n * are offered. */\nexport function FontSpecimen({\n familyKey,\n title,\n cssVar,\n styles,\n}: {\n familyKey: string\n title: string | null\n cssVar: string\n styles: SpecimenStyle[]\n}) {\n const [styleIdx, setStyleIdx] = useState(0)\n const current = styles[Math.min(styleIdx, styles.length - 1)]\n const [weight, setWeight] = useState(current?.weights.includes(400) ? 400 : (current?.weights[0] ?? 400))\n\n const pickStyle = (idx: number) => {\n setStyleIdx(idx)\n const next = styles[idx]\n if (next && !next.weights.includes(weight)) setWeight(next.weights.includes(400) ? 400 : (next.weights[0] ?? 400))\n }\n\n return (\n <div className=\"pdtp-specimen\">\n <div className=\"pdtp-specimen-head\">\n <span>\n <span className=\"pdtp-code\">{familyKey}</span>{' '}\n <span className=\"pdtp-kind\" style={{ marginLeft: 6 }}>\n {title ?? 'slot unset — fallback stack'}\n {current ? ` · ${current.label}` : ''}\n </span>\n </span>\n {styles.length > 1 ? (\n <span className=\"pdtp-seg\">\n {styles.map((s, idx) => (\n <button key={s.style} type=\"button\" className={idx === styleIdx ? 'pdtp-active' : ''} onClick={() => pickStyle(idx)}>\n {s.style === 'normal' ? 'upright' : 'italic'}\n </button>\n ))}\n </span>\n ) : current ? (\n <span className=\"pdtp-kind\">{current.style === 'normal' ? 'upright only' : 'italic only'}</span>\n ) : null}\n </div>\n\n <div style={{ fontFamily: cssVar, fontWeight: weight, fontStyle: current?.style ?? 'normal' }}>\n <p className=\"pdtp-specimen-big\">The quick brown fox jumps over the lazy dog.</p>\n <p className=\"pdtp-specimen-body\">ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 — 1,234.56 · «fi ffi» ?!&</p>\n </div>\n\n {current ? (\n <div className=\"pdtp-chips\" style={{ marginTop: 14 }}>\n {current.weights.map((w) => (\n <button key={w} type=\"button\" className={`pdtp-chip ${w === weight ? 'pdtp-active' : ''}`} onClick={() => setWeight(w)}>\n {w}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n )\n}\n\n/** The `/dev/icons` set switcher — activates a set via `POST /api/dev/icons/activate` and\n * refreshes, so the grid (and the whole site) re-skins to the newly active set. */\nexport function IconSetSwitcher({ sets }: { sets: { id: string | number; title: string; active: boolean }[] }) {\n const router = useRouter()\n const [busy, setBusy] = useState<string | number | null>(null)\n const [error, setError] = useState<string | null>(null)\n\n const activate = async (id: string | number) => {\n setBusy(id)\n setError(null)\n try {\n const res = await fetch('/api/dev/icons/activate', {\n method: 'POST',\n credentials: 'include',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id }),\n })\n if (res.ok) router.refresh()\n else setError(((await res.json().catch(() => null)) as { error?: string } | null)?.error ?? `Failed (HTTP ${res.status}).`)\n } catch {\n setError('Request failed — is the dev server running?')\n }\n setBusy(null)\n }\n\n return (\n <div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>\n {sets.map((set) => (\n <button\n key={set.id}\n type=\"button\"\n className={`pdtp-btn ${set.active ? 'pdtp-btn-primary' : ''}`}\n disabled={busy !== null || set.active}\n onClick={() => void activate(set.id)}\n >\n {busy === set.id ? 'Activating…' : set.title}\n {set.active ? ' ✓' : ''}\n </button>\n ))}\n </div>\n {error ? <div className=\"pdtp-error\">{error}</div> : null}\n </div>\n )\n}\n"],"names":["useRouter","useState","SeedCard","seed","adminRoute","router","running","setRunning","confirming","setConfirming","error","setError","runSeed","res","fetch","method","credentials","ok","refresh","body","json","catch","status","div","className","h2","seeded","totalDocs","enabled","span","table","tbody","definitions","map","d","tr","td","slug","disabled","kind","counts","style","marginTop","display","gap","button","type","onClick","p","a","href","issues","length","ul","issue","li","FontSpecimen","familyKey","title","cssVar","styles","styleIdx","setStyleIdx","current","Math","min","weight","setWeight","weights","includes","pickStyle","idx","next","marginLeft","label","s","fontFamily","fontWeight","fontStyle","w","IconSetSwitcher","sets","busy","setBusy","activate","id","headers","JSON","stringify","flexWrap","set","active"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/next/client.tsx"],"sourcesContent":["'use client'\n\nimport { useRouter } from 'next/navigation'\nimport { useState } from 'react'\nimport type { SeedSnapshot } from '../lib/snapshot'\nimport type { SpecimenStyle } from './specimen'\n\ntype SeedError = { error: string; issues?: string[] }\n\n/** The `/dev` index's seed controls — same flow as the toolbar's Seed view: POST the seed\n * plugin's own endpoint, two-click confirm when destructive, surface `{ error, issues }`. */\nexport function SeedCard({ seed, adminRoute }: { seed: SeedSnapshot; adminRoute: string }) {\n const router = useRouter()\n const [running, setRunning] = useState(false)\n const [confirming, setConfirming] = useState(false)\n const [error, setError] = useState<SeedError | null>(null)\n\n const runSeed = async () => {\n setRunning(true)\n setError(null)\n try {\n const res = await fetch('/api/seed', { method: 'POST', credentials: 'include' })\n if (res.ok) {\n setConfirming(false)\n router.refresh()\n } else {\n const body = (await res.json().catch(() => null)) as SeedError | null\n setError(body?.error ? body : { error: `Seed failed (HTTP ${res.status}).` })\n setConfirming(false)\n }\n } catch {\n setError({ error: 'Seed request failed — is the dev server running?' })\n setConfirming(false)\n }\n setRunning(false)\n }\n\n return (\n <div className=\"pdtp-card\">\n <h2>\n {seed.seeded ? `Seeded — ${seed.totalDocs} docs` : 'Not seeded'}\n {!seed.enabled ? <span className=\"pdtp-kind pdtp-warn\">locked</span> : <span className=\"pdtp-kind\">seed</span>}\n </h2>\n <table className=\"pdtp-table\">\n <tbody>\n {seed.definitions.map((d) => (\n <tr key={d.slug}>\n <td>\n {d.slug}\n {d.disabled ? <span className=\"pdtp-warn\"> · skipped</span> : null}\n </td>\n <td>{d.kind === 'global' ? 'global' : (seed.counts[d.slug] ?? 0)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n <div style={{ marginTop: 12, display: 'flex', gap: 8 }}>\n <button\n type=\"button\"\n className={`pdtp-btn ${seed.seeded ? 'pdtp-btn-danger' : 'pdtp-btn-primary'}`}\n disabled={running}\n onClick={() => (seed.seeded && !confirming ? setConfirming(true) : void runSeed())}\n >\n {running ? 'Seeding…' : confirming ? 'Destructive — click again' : seed.seeded ? 'Reseed' : 'Seed the database'}\n </button>\n {confirming ? (\n <button type=\"button\" className=\"pdtp-btn\" onClick={() => setConfirming(false)}>\n Cancel\n </button>\n ) : null}\n </div>\n {!seed.enabled ? (\n <p className=\"pdtp-note\">\n Set <span className=\"pdtp-code\">ENABLE_SEED=true</span> in <span className=\"pdtp-code\">.env.local</span> — the seed wipes seeded\n collections, so it's off by default.\n </p>\n ) : null}\n <p className=\"pdtp-note\">\n Needs a logged-in <a href={adminRoute}>admin</a> user · CLI: <span className=\"pdtp-code\">ENABLE_SEED=true pnpm seed</span>\n </p>\n {error ? (\n <div className=\"pdtp-error\">\n {error.error}\n {error.issues?.length ? (\n <ul>\n {error.issues.map((issue) => (\n <li key={issue}>{issue}</li>\n ))}\n </ul>\n ) : null}\n </div>\n ) : null}\n </div>\n )\n}\n\n/** The `/dev/fonts` interactive specimen — the sample renders in the family's `--font-set*`\n * variable at the clicked weight/style. Only weights and styles the typeface actually serves\n * are offered. */\nexport function FontSpecimen({\n familyKey,\n title,\n cssVar,\n styles,\n}: {\n familyKey: string\n title: string | null\n cssVar: string\n styles: SpecimenStyle[]\n}) {\n const [styleIdx, setStyleIdx] = useState(0)\n const current = styles[Math.min(styleIdx, styles.length - 1)]\n const [weight, setWeight] = useState(current?.weights.includes(400) ? 400 : (current?.weights[0] ?? 400))\n\n const pickStyle = (idx: number) => {\n setStyleIdx(idx)\n const next = styles[idx]\n if (next && !next.weights.includes(weight)) setWeight(next.weights.includes(400) ? 400 : (next.weights[0] ?? 400))\n }\n\n return (\n <div className=\"pdtp-specimen\">\n <div className=\"pdtp-specimen-head\">\n <span>\n <span className=\"pdtp-code\">{familyKey}</span>{' '}\n <span className=\"pdtp-kind\" style={{ marginLeft: 6 }}>\n {title ?? 'slot unset — fallback stack'}\n {current ? ` · ${current.label}` : ''}\n </span>\n </span>\n {styles.length > 1 ? (\n <span className=\"pdtp-seg\">\n {styles.map((s, idx) => (\n <button key={s.style} type=\"button\" className={idx === styleIdx ? 'pdtp-active' : ''} onClick={() => pickStyle(idx)}>\n {s.style === 'normal' ? 'upright' : 'italic'}\n </button>\n ))}\n </span>\n ) : current ? (\n <span className=\"pdtp-kind\">{current.style === 'normal' ? 'upright only' : 'italic only'}</span>\n ) : null}\n </div>\n\n <div style={{ fontFamily: cssVar, fontWeight: weight, fontStyle: current?.style ?? 'normal' }}>\n <p className=\"pdtp-specimen-big\">The quick brown fox jumps over the lazy dog.</p>\n <p className=\"pdtp-specimen-body\">ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 — 1,234.56 · «fi ffi» ?!&</p>\n </div>\n\n {current ? (\n <div className=\"pdtp-chips\" style={{ marginTop: 14 }}>\n {current.weights.map((w) => (\n <button key={w} type=\"button\" className={`pdtp-chip ${w === weight ? 'pdtp-active' : ''}`} onClick={() => setWeight(w)}>\n {w}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n )\n}\n\n/** The `/dev/icons` set switcher — activates a set via `POST /api/dev/icons/activate` and\n * refreshes, so the grid (and the whole site) re-skins to the newly active set. */\nexport function IconSetSwitcher({ sets }: { sets: { id: string | number; title: string; active: boolean }[] }) {\n const router = useRouter()\n const [busy, setBusy] = useState<string | number | null>(null)\n const [error, setError] = useState<string | null>(null)\n\n const activate = async (id: string | number) => {\n setBusy(id)\n setError(null)\n try {\n const res = await fetch('/api/dev/icons/activate', {\n method: 'POST',\n credentials: 'include',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id }),\n })\n if (res.ok) router.refresh()\n else setError(((await res.json().catch(() => null)) as { error?: string } | null)?.error ?? `Failed (HTTP ${res.status}).`)\n } catch {\n setError('Request failed — is the dev server running?')\n }\n setBusy(null)\n }\n\n return (\n <div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>\n {sets.map((set) => (\n <button\n key={set.id}\n type=\"button\"\n className={`pdtp-btn ${set.active ? 'pdtp-btn-primary' : ''}`}\n disabled={busy !== null || set.active}\n onClick={() => void activate(set.id)}\n >\n {busy === set.id ? 'Activating…' : set.title}\n {set.active ? ' ✓' : ''}\n </button>\n ))}\n </div>\n {error ? <div className=\"pdtp-error\">{error}</div> : null}\n </div>\n )\n}\n\n/** The `/dev/revalidate` manual bust box — POST one tag to payload-revalidate's map\n * endpoint and refresh, so the event log shows the manual bust immediately. */\nexport function BustTagCard({ endpointPath }: { endpointPath: string }) {\n const router = useRouter()\n const [tag, setTag] = useState('')\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const bust = async () => {\n if (!tag.trim()) return\n setBusy(true)\n setError(null)\n try {\n const res = await fetch(endpointPath, {\n method: 'POST',\n credentials: 'include',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ tag: tag.trim() }),\n })\n if (res.ok) {\n setTag('')\n router.refresh()\n } else setError(((await res.json().catch(() => null)) as { error?: string } | null)?.error ?? `Failed (HTTP ${res.status}).`)\n } catch {\n setError('Request failed — is the dev server running?')\n }\n setBusy(false)\n }\n\n return (\n <div className=\"pdtp-card\" style={{ marginTop: 20 }}>\n <h2>\n Bust a tag <span className=\"pdtp-kind\">manual</span>\n </h2>\n <form\n style={{ display: 'flex', gap: 8 }}\n onSubmit={(e) => {\n e.preventDefault()\n void bust()\n }}\n >\n <input\n className=\"pdtp-code\"\n style={{ flex: 1, padding: '6px 10px' }}\n placeholder=\"posts:42 · posts · global:header · all\"\n value={tag}\n onChange={(e) => setTag(e.target.value)}\n />\n <button type=\"submit\" className=\"pdtp-btn pdtp-btn-primary\" disabled={busy || !tag.trim()}>\n {busy ? 'Busting…' : 'Bust'}\n </button>\n </form>\n {error ? <div className=\"pdtp-error\">{error}</div> : null}\n </div>\n )\n}\n"],"names":["useRouter","useState","SeedCard","seed","adminRoute","router","running","setRunning","confirming","setConfirming","error","setError","runSeed","res","fetch","method","credentials","ok","refresh","body","json","catch","status","div","className","h2","seeded","totalDocs","enabled","span","table","tbody","definitions","map","d","tr","td","slug","disabled","kind","counts","style","marginTop","display","gap","button","type","onClick","p","a","href","issues","length","ul","issue","li","FontSpecimen","familyKey","title","cssVar","styles","styleIdx","setStyleIdx","current","Math","min","weight","setWeight","weights","includes","pickStyle","idx","next","marginLeft","label","s","fontFamily","fontWeight","fontStyle","w","IconSetSwitcher","sets","busy","setBusy","activate","id","headers","JSON","stringify","flexWrap","set","active","BustTagCard","endpointPath","tag","setTag","bust","trim","form","onSubmit","e","preventDefault","input","flex","padding","placeholder","value","onChange","target"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDevPage.d.ts","sourceRoot":"","sources":["../../src/next/createDevPage.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,YAAY,CAAA;AAOlD,MAAM,MAAM,oBAAoB,GAAG;IACjC;;8CAE0C;IAC1C,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;IACd,wFAAwF;IACxF,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,KAAK,YAAY,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAA;CAAE,CAAA;AAEnI;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,IAGhC,0BAA0B,YAAY,
|
|
1
|
+
{"version":3,"file":"createDevPage.d.ts","sourceRoot":"","sources":["../../src/next/createDevPage.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,YAAY,CAAA;AAOlD,MAAM,MAAM,oBAAoB,GAAG;IACjC;;8CAE0C;IAC1C,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;IACd,wFAAwF;IACxF,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,KAAK,YAAY,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAA;CAAE,CAAA;AAEnI;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,IAGhC,0BAA0B,YAAY,0CAgErE"}
|
|
@@ -7,7 +7,7 @@ import { getPayloadClient } from "../lib/getPayloadClient.js";
|
|
|
7
7
|
import { buildDevSnapshot } from "../lib/snapshot.js";
|
|
8
8
|
import { SeedCard } from "./client.js";
|
|
9
9
|
import { PDTP_CSS } from "./pageStyles.js";
|
|
10
|
-
import { FontsView, IconsView, ImagesView, MuxView } from "./views.js";
|
|
10
|
+
import { FontsView, IconsView, ImagesView, MuxView, RevalidateView } from "./views.js";
|
|
11
11
|
/**
|
|
12
12
|
* The `/dev` pages — real routes inside your app, one drop-in file:
|
|
13
13
|
*
|
|
@@ -85,6 +85,15 @@ import { FontsView, IconsView, ImagesView, MuxView } from "./views.js";
|
|
|
85
85
|
snapshot: snapshot
|
|
86
86
|
})
|
|
87
87
|
});
|
|
88
|
+
case 'revalidate':
|
|
89
|
+
if (!snapshot.revalidate || rest.length) notFound();
|
|
90
|
+
return /*#__PURE__*/ _jsx(Shell, {
|
|
91
|
+
snapshot: snapshot,
|
|
92
|
+
title: "Revalidate",
|
|
93
|
+
children: /*#__PURE__*/ _jsx(RevalidateView, {
|
|
94
|
+
snapshot: snapshot
|
|
95
|
+
})
|
|
96
|
+
});
|
|
88
97
|
case 'tests':
|
|
89
98
|
{
|
|
90
99
|
if (!tests.length || rest.length > 1) notFound();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/next/createDevPage.tsx"],"sourcesContent":["import { cookies } from 'next/headers'\nimport { notFound } from 'next/navigation'\nimport type { ReactNode } from 'react'\nimport { STAGE_COOKIE } from '../cookies'\nimport { parseStage, type Test } from '../harness'\nimport { getPayloadClient } from '../lib/getPayloadClient'\nimport { buildDevSnapshot, type DevSnapshot } from '../lib/snapshot'\nimport { SeedCard } from './client'\nimport { PDTP_CSS } from './pageStyles'\nimport { FontsView, IconsView, ImagesView, MuxView } from './views'\n\nexport type CreateDevPageOptions = {\n /** Component tests (from `defineTest`) — each gets ONE page at `/dev/tests/<key>`; which\n * version it shows is controlled from the dev toolbar (via the selection cookie). Pass the\n * same array to `<DevToolbar tests>`. */\n tests?: Test[]\n /** Force the pages on/off. Defaults to `NODE_ENV === 'development'` (404 otherwise). */\n enabled?: boolean\n}\n\ntype DevPageProps = { params: Promise<{ view?: string[] }>; searchParams?: Promise<Record<string, string | string[] | undefined>> }\n\n/**\n * The `/dev` pages — real routes inside your app, one drop-in file:\n *\n * // app/(frontend)/dev/[[...view]]/page.tsx\n * import { createDevPage } from '@pro-laico/payload-dev-tools/next'\n * import { devTests } from '@/dev/tests'\n * export const dynamic = 'force-dynamic'\n * export default createDevPage({ tests: devTests })\n *\n * Views: `/dev` (overview + seed controls), `/dev/icons` (grid + active-set switcher),\n * `/dev/fonts` (specimens in the real served fonts), `/dev/images`, `/dev/mux`, and\n * `/dev/tests/<key>` (one page per test; the shown version is toggled from the toolbar). The\n * pages render content only — navigation lives in the `<DevToolbar>`, which stays open while you\n * browse between them. Because the file lives in your `(frontend)` group, everything inherits\n * your layout — header, fonts, globals — which is the point: visual confirmation happens in the\n * app, not a facsimile of it. The component resolves Payload itself (config stash → the\n * `@payload-config` alias), so it takes no config prop. Your own labs coexist: a static route\n * like `app/(frontend)/dev/blocks/page.tsx` always beats this catch-all.\n */\nexport function createDevPage(options: CreateDevPageOptions = {}) {\n const { tests = [], enabled } = options\n\n return async function DevPage({ params, searchParams }: DevPageProps) {\n if (!(enabled ?? process.env.NODE_ENV === 'development')) notFound()\n\n const { view = [] } = await params\n const query = (await searchParams) ?? {}\n const payload = await getPayloadClient()\n const snapshot = await buildDevSnapshot(payload)\n\n const [section, ...rest] = view\n switch (section) {\n case undefined:\n return (\n <Shell snapshot={snapshot} title={snapshot.devRoute}>\n <DevIndex snapshot={snapshot} />\n </Shell>\n )\n case 'icons':\n if (!snapshot.icons || rest.length) notFound()\n return (\n <Shell snapshot={snapshot} title=\"Icons\">\n <IconsView payload={payload} snapshot={snapshot} />\n </Shell>\n )\n case 'fonts':\n if (!snapshot.fonts || rest.length) notFound()\n return (\n <Shell snapshot={snapshot} title=\"Fonts\">\n <FontsView payload={payload} snapshot={snapshot} />\n </Shell>\n )\n case 'images':\n if (!snapshot.images || rest.length) notFound()\n return (\n <Shell snapshot={snapshot} title=\"Images\">\n <ImagesView payload={payload} snapshot={snapshot} searchParams={query} />\n </Shell>\n )\n case 'mux':\n if (!snapshot.mux || rest.length) notFound()\n return (\n <Shell snapshot={snapshot} title=\"Mux\">\n <MuxView payload={payload} snapshot={snapshot} />\n </Shell>\n )\n case 'tests': {\n if (!tests.length || rest.length > 1) notFound()\n if (rest.length === 1) return <TestPage tests={tests} testKey={rest[0] ?? ''} />\n return (\n <Shell snapshot={snapshot} title=\"Tests\">\n <TestsIndex tests={tests} />\n </Shell>\n )\n }\n default:\n notFound()\n }\n }\n}\n\n/** Content chrome only — heading + env line. Navigation is the toolbar's job. */\nconst Shell = ({ snapshot, title, children }: { snapshot: DevSnapshot; title: string; children: ReactNode }) => (\n <div className=\"pdtp\">\n {/* dangerouslySetInnerHTML: our own static CSS — React would escape selector characters as a text child */}\n <style dangerouslySetInnerHTML={{ __html: PDTP_CSS }} />\n <div className=\"pdtp-container\">\n <div className=\"pdtp-head\">\n <h1>{title}</h1>\n <span className=\"pdtp-badge\">dev only</span>\n <span className=\"pdtp-env\">\n {snapshot.env.nodeEnv} · node {snapshot.env.nodeVersion} · navigate via the dev toolbar ↘\n </span>\n </div>\n {children}\n </div>\n </div>\n)\n\nconst DevIndex = ({ snapshot }: { snapshot: DevSnapshot }) => (\n <>\n <div className=\"pdtp-chips\">\n {Object.entries(snapshot.plugins).map(([name, on]) => (\n <span key={name}>\n <span className={`pdtp-dot ${on ? 'pdtp-dot-on' : 'pdtp-dot-off'}`} />\n payload-{name}\n </span>\n ))}\n </div>\n\n <div className=\"pdtp-section\">\n <div className=\"pdtp-grid\">\n {snapshot.seed ? <SeedCard seed={snapshot.seed} adminRoute={snapshot.adminRoute} /> : null}\n <div className=\"pdtp-card\">\n <h2>\n Collections <span className=\"pdtp-kind\">docs</span>\n </h2>\n <table className=\"pdtp-table\">\n <tbody>\n {snapshot.collections.map((c) => (\n <tr key={c.slug}>\n <td>{c.slug}</td>\n <td className=\"pdtp-mono\">{c.count ?? '?'}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <p className=\"pdtp-note\">\n Machine-readable: <span className=\"pdtp-code\">GET /api/dev</span> serves this as JSON (browsers land here instead).\n </p>\n </>\n)\n\nconst TestsIndex = ({ tests }: { tests: Test[] }) => (\n <>\n <table className=\"pdtp-table\">\n <thead>\n <tr>\n <th>test</th>\n <th>kind</th>\n <th>versions</th>\n </tr>\n </thead>\n <tbody>\n {tests.map((t) => (\n <tr key={t.key}>\n <td>{t.label}</td>\n <td className=\"pdtp-mono\">{t.kind}</td>\n <td className=\"pdtp-mono\">{t.versions.map((v) => v.label).join(' · ')}</td>\n </tr>\n ))}\n </tbody>\n </table>\n <p className=\"pdtp-note\">\n Each test is one page — open it (and toggle versions) from the toolbar's Tests view, or script it via{' '}\n <span className=\"pdtp-code\">/api/dev/stage?test=…&version=…</span>\n </p>\n </>\n)\n\n/** One page per test. The shown version comes from the toolbar's selection cookie (defaulting to\n * the first version) and renders inside your real frontend layout with NO extra chrome — the\n * toolbar's Tests view names what you're looking at. The `display: contents` wrapper is\n * layout-invisible; it exists only so screenshot tooling can assert `data-pdt-test` /\n * `data-pdt-version`. */\nconst TestPage = async ({ tests, testKey }: { tests: Test[]; testKey: string }) => {\n const test = tests.find((t) => t.key === testKey)\n if (!test) notFound()\n\n const jar = await cookies()\n const stage = parseStage(jar.get(STAGE_COOKIE)?.value, tests)\n const version = (stage?.test.key === test.key ? stage.version : undefined) ?? test.versions[0]\n if (!version) notFound()\n\n return (\n <div style={{ display: 'contents' }} data-pdt-test={test.key} data-pdt-version={version.id}>\n {await version.render()}\n </div>\n )\n}\n"],"names":["cookies","notFound","STAGE_COOKIE","parseStage","getPayloadClient","buildDevSnapshot","SeedCard","PDTP_CSS","FontsView","IconsView","ImagesView","MuxView","createDevPage","options","tests","enabled","DevPage","params","searchParams","process","env","NODE_ENV","view","query","payload","snapshot","section","rest","undefined","Shell","title","devRoute","DevIndex","icons","length","fonts","images","mux","TestPage","testKey","TestsIndex","children","div","className","style","dangerouslySetInnerHTML","__html","h1","span","nodeEnv","nodeVersion","Object","entries","plugins","map","name","on","seed","adminRoute","h2","table","tbody","collections","c","tr","td","slug","count","p","thead","th","t","label","kind","versions","v","join","key","test","find","jar","stage","get","value","version","display","data-pdt-test","data-pdt-version","id","render"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/next/createDevPage.tsx"],"sourcesContent":["import { cookies } from 'next/headers'\nimport { notFound } from 'next/navigation'\nimport type { ReactNode } from 'react'\nimport { STAGE_COOKIE } from '../cookies'\nimport { parseStage, type Test } from '../harness'\nimport { getPayloadClient } from '../lib/getPayloadClient'\nimport { buildDevSnapshot, type DevSnapshot } from '../lib/snapshot'\nimport { SeedCard } from './client'\nimport { PDTP_CSS } from './pageStyles'\nimport { FontsView, IconsView, ImagesView, MuxView, RevalidateView } from './views'\n\nexport type CreateDevPageOptions = {\n /** Component tests (from `defineTest`) — each gets ONE page at `/dev/tests/<key>`; which\n * version it shows is controlled from the dev toolbar (via the selection cookie). Pass the\n * same array to `<DevToolbar tests>`. */\n tests?: Test[]\n /** Force the pages on/off. Defaults to `NODE_ENV === 'development'` (404 otherwise). */\n enabled?: boolean\n}\n\ntype DevPageProps = { params: Promise<{ view?: string[] }>; searchParams?: Promise<Record<string, string | string[] | undefined>> }\n\n/**\n * The `/dev` pages — real routes inside your app, one drop-in file:\n *\n * // app/(frontend)/dev/[[...view]]/page.tsx\n * import { createDevPage } from '@pro-laico/payload-dev-tools/next'\n * import { devTests } from '@/dev/tests'\n * export const dynamic = 'force-dynamic'\n * export default createDevPage({ tests: devTests })\n *\n * Views: `/dev` (overview + seed controls), `/dev/icons` (grid + active-set switcher),\n * `/dev/fonts` (specimens in the real served fonts), `/dev/images`, `/dev/mux`, and\n * `/dev/tests/<key>` (one page per test; the shown version is toggled from the toolbar). The\n * pages render content only — navigation lives in the `<DevToolbar>`, which stays open while you\n * browse between them. Because the file lives in your `(frontend)` group, everything inherits\n * your layout — header, fonts, globals — which is the point: visual confirmation happens in the\n * app, not a facsimile of it. The component resolves Payload itself (config stash → the\n * `@payload-config` alias), so it takes no config prop. Your own labs coexist: a static route\n * like `app/(frontend)/dev/blocks/page.tsx` always beats this catch-all.\n */\nexport function createDevPage(options: CreateDevPageOptions = {}) {\n const { tests = [], enabled } = options\n\n return async function DevPage({ params, searchParams }: DevPageProps) {\n if (!(enabled ?? process.env.NODE_ENV === 'development')) notFound()\n\n const { view = [] } = await params\n const query = (await searchParams) ?? {}\n const payload = await getPayloadClient()\n const snapshot = await buildDevSnapshot(payload)\n\n const [section, ...rest] = view\n switch (section) {\n case undefined:\n return (\n <Shell snapshot={snapshot} title={snapshot.devRoute}>\n <DevIndex snapshot={snapshot} />\n </Shell>\n )\n case 'icons':\n if (!snapshot.icons || rest.length) notFound()\n return (\n <Shell snapshot={snapshot} title=\"Icons\">\n <IconsView payload={payload} snapshot={snapshot} />\n </Shell>\n )\n case 'fonts':\n if (!snapshot.fonts || rest.length) notFound()\n return (\n <Shell snapshot={snapshot} title=\"Fonts\">\n <FontsView payload={payload} snapshot={snapshot} />\n </Shell>\n )\n case 'images':\n if (!snapshot.images || rest.length) notFound()\n return (\n <Shell snapshot={snapshot} title=\"Images\">\n <ImagesView payload={payload} snapshot={snapshot} searchParams={query} />\n </Shell>\n )\n case 'mux':\n if (!snapshot.mux || rest.length) notFound()\n return (\n <Shell snapshot={snapshot} title=\"Mux\">\n <MuxView payload={payload} snapshot={snapshot} />\n </Shell>\n )\n case 'revalidate':\n if (!snapshot.revalidate || rest.length) notFound()\n return (\n <Shell snapshot={snapshot} title=\"Revalidate\">\n <RevalidateView snapshot={snapshot} />\n </Shell>\n )\n case 'tests': {\n if (!tests.length || rest.length > 1) notFound()\n if (rest.length === 1) return <TestPage tests={tests} testKey={rest[0] ?? ''} />\n return (\n <Shell snapshot={snapshot} title=\"Tests\">\n <TestsIndex tests={tests} />\n </Shell>\n )\n }\n default:\n notFound()\n }\n }\n}\n\n/** Content chrome only — heading + env line. Navigation is the toolbar's job. */\nconst Shell = ({ snapshot, title, children }: { snapshot: DevSnapshot; title: string; children: ReactNode }) => (\n <div className=\"pdtp\">\n {/* dangerouslySetInnerHTML: our own static CSS — React would escape selector characters as a text child */}\n <style dangerouslySetInnerHTML={{ __html: PDTP_CSS }} />\n <div className=\"pdtp-container\">\n <div className=\"pdtp-head\">\n <h1>{title}</h1>\n <span className=\"pdtp-badge\">dev only</span>\n <span className=\"pdtp-env\">\n {snapshot.env.nodeEnv} · node {snapshot.env.nodeVersion} · navigate via the dev toolbar ↘\n </span>\n </div>\n {children}\n </div>\n </div>\n)\n\nconst DevIndex = ({ snapshot }: { snapshot: DevSnapshot }) => (\n <>\n <div className=\"pdtp-chips\">\n {Object.entries(snapshot.plugins).map(([name, on]) => (\n <span key={name}>\n <span className={`pdtp-dot ${on ? 'pdtp-dot-on' : 'pdtp-dot-off'}`} />\n payload-{name}\n </span>\n ))}\n </div>\n\n <div className=\"pdtp-section\">\n <div className=\"pdtp-grid\">\n {snapshot.seed ? <SeedCard seed={snapshot.seed} adminRoute={snapshot.adminRoute} /> : null}\n <div className=\"pdtp-card\">\n <h2>\n Collections <span className=\"pdtp-kind\">docs</span>\n </h2>\n <table className=\"pdtp-table\">\n <tbody>\n {snapshot.collections.map((c) => (\n <tr key={c.slug}>\n <td>{c.slug}</td>\n <td className=\"pdtp-mono\">{c.count ?? '?'}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <p className=\"pdtp-note\">\n Machine-readable: <span className=\"pdtp-code\">GET /api/dev</span> serves this as JSON (browsers land here instead).\n </p>\n </>\n)\n\nconst TestsIndex = ({ tests }: { tests: Test[] }) => (\n <>\n <table className=\"pdtp-table\">\n <thead>\n <tr>\n <th>test</th>\n <th>kind</th>\n <th>versions</th>\n </tr>\n </thead>\n <tbody>\n {tests.map((t) => (\n <tr key={t.key}>\n <td>{t.label}</td>\n <td className=\"pdtp-mono\">{t.kind}</td>\n <td className=\"pdtp-mono\">{t.versions.map((v) => v.label).join(' · ')}</td>\n </tr>\n ))}\n </tbody>\n </table>\n <p className=\"pdtp-note\">\n Each test is one page — open it (and toggle versions) from the toolbar's Tests view, or script it via{' '}\n <span className=\"pdtp-code\">/api/dev/stage?test=…&version=…</span>\n </p>\n </>\n)\n\n/** One page per test. The shown version comes from the toolbar's selection cookie (defaulting to\n * the first version) and renders inside your real frontend layout with NO extra chrome — the\n * toolbar's Tests view names what you're looking at. The `display: contents` wrapper is\n * layout-invisible; it exists only so screenshot tooling can assert `data-pdt-test` /\n * `data-pdt-version`. */\nconst TestPage = async ({ tests, testKey }: { tests: Test[]; testKey: string }) => {\n const test = tests.find((t) => t.key === testKey)\n if (!test) notFound()\n\n const jar = await cookies()\n const stage = parseStage(jar.get(STAGE_COOKIE)?.value, tests)\n const version = (stage?.test.key === test.key ? stage.version : undefined) ?? test.versions[0]\n if (!version) notFound()\n\n return (\n <div style={{ display: 'contents' }} data-pdt-test={test.key} data-pdt-version={version.id}>\n {await version.render()}\n </div>\n )\n}\n"],"names":["cookies","notFound","STAGE_COOKIE","parseStage","getPayloadClient","buildDevSnapshot","SeedCard","PDTP_CSS","FontsView","IconsView","ImagesView","MuxView","RevalidateView","createDevPage","options","tests","enabled","DevPage","params","searchParams","process","env","NODE_ENV","view","query","payload","snapshot","section","rest","undefined","Shell","title","devRoute","DevIndex","icons","length","fonts","images","mux","revalidate","TestPage","testKey","TestsIndex","children","div","className","style","dangerouslySetInnerHTML","__html","h1","span","nodeEnv","nodeVersion","Object","entries","plugins","map","name","on","seed","adminRoute","h2","table","tbody","collections","c","tr","td","slug","count","p","thead","th","t","label","kind","versions","v","join","key","test","find","jar","stage","get","value","version","display","data-pdt-test","data-pdt-version","id","render"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** The dev pages' stylesheet, injected once by the page shell. Scoped under `.pdtp` and
|
|
2
2
|
* self-contained (own dark theme) — the pages inherit the host's frontend layout (header,
|
|
3
3
|
* fonts, globals) but never depend on its utility classes. */
|
|
4
|
-
export declare const PDTP_CSS = "\n.pdtp { color-scheme: dark;\n --pdtp-accent: oklch(0.72 0.16 250); --pdtp-bg: oklch(0.145 0 0); --pdtp-card: oklch(0.2 0 0);\n --pdtp-fg: oklch(0.985 0 0); --pdtp-muted: oklch(0.708 0 0); --pdtp-border: oklch(1 0 0 / 12%);\n --pdtp-hover: oklch(1 0 0 / 7%); --pdtp-danger: oklch(0.65 0.18 25); --pdtp-warn: oklch(0.8 0.14 85);\n background: var(--pdtp-bg); color: var(--pdtp-fg); min-height: 60vh;\n font-family: ui-sans-serif, system-ui, sans-serif; font-size: 15px; line-height: 1.5; }\n.pdtp *, .pdtp *::before, .pdtp *::after { box-sizing: border-box; }\n.pdtp a { color: var(--pdtp-accent); text-decoration: none; }\n.pdtp a:hover { text-decoration: underline; }\n/* :where() keeps this reset at zero specificity so component classes below always win it. */\n:where(.pdtp) button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }\n\n.pdtp-container { max-width: 1000px; margin: 0 auto; padding: 40px 24px 80px; }\n.pdtp-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 24px; }\n.pdtp-head h1 { margin: 0; font-size: 1.5rem; letter-spacing: -0.02em; color: var(--pdtp-fg); }\n.pdtp-badge { font-family: ui-monospace, Consolas, monospace; font-size: 10px; text-transform: uppercase;\n letter-spacing: 0.08em; color: var(--pdtp-muted); border: 1px solid var(--pdtp-border); border-radius: 4px; padding: 2px 7px; }\n.pdtp-env { color: var(--pdtp-muted); font-size: 0.85rem; }\n\n.pdtp-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }\n.pdtp-card { border: 1px solid var(--pdtp-border); background: var(--pdtp-card); border-radius: 12px; padding: 16px; }\n.pdtp-card h2 { margin: 0 0 10px; font-size: 1rem; font-weight: 600; color: var(--pdtp-fg); display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }\n.pdtp-kind { font-family: ui-monospace, Consolas, monospace; font-size: 10.5px; text-transform: uppercase;\n letter-spacing: 0.06em; color: var(--pdtp-muted); font-weight: 400; }\n.pdtp-section { margin: 32px 0 0; }\n.pdtp-section > h2 { margin: 0 0 12px; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--pdtp-muted); font-weight: 600; }\n\n.pdtp-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }\n.pdtp-table td, .pdtp-table th { text-align: left; padding: 6px 10px; border-bottom: 1px solid var(--pdtp-border); }\n.pdtp-table th { color: var(--pdtp-muted); font-weight: 500; font-size: 0.8rem; }\n.pdtp-table td:last-child, .pdtp-table th:last-child { text-align: right; }\n.pdtp-mono { font-family: ui-monospace, Consolas, monospace; font-size: 0.85em; }\n.pdtp-code { font-family: ui-monospace, Consolas, monospace; font-size: 0.85em; background: oklch(0.26 0 0); padding: 1px 6px; border-radius: 4px; }\n.pdtp-muted { color: var(--pdtp-muted); }\n.pdtp-warn { color: var(--pdtp-warn); }\n\n.pdtp-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 7px; }\n.pdtp-dot-on { background: oklch(0.75 0.15 165); } .pdtp-dot-off { background: oklch(0.45 0 0); }\n.pdtp-chips { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 0.9rem; }\n\n.pdtp-chip { border: 1px solid var(--pdtp-border); border-radius: 999px; padding: 5px 14px; font-size: 0.85rem;\n background: oklch(0.26 0 0); transition: border-color 0.15s ease, background 0.15s ease; }\n.pdtp-chip:hover { background: oklch(0.31 0 0); border-color: oklch(0.45 0 0); }\n.pdtp-chip.pdtp-active { background: var(--pdtp-accent); border-color: var(--pdtp-accent); color: oklch(0.13 0 0); font-weight: 600; }\n.pdtp-seg { display: inline-flex; overflow: hidden; border: 1px solid var(--pdtp-border); border-radius: 999px; }\n.pdtp-seg button { padding: 4px 13px; font-size: 0.8rem; }\n.pdtp-seg button:hover { background: var(--pdtp-hover); }\n.pdtp-seg button.pdtp-active { background: var(--pdtp-accent); color: oklch(0.13 0 0); font-weight: 600; }\n\n.pdtp-btn { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--pdtp-border);\n border-radius: 8px; padding: 7px 14px; font-size: 0.9rem; font-weight: 500; }\n.pdtp-btn:hover { background: var(--pdtp-hover); text-decoration: none; }\n.pdtp-btn:disabled { opacity: 0.55; cursor: default; }\n.pdtp-btn-primary { background: var(--pdtp-accent); border-color: var(--pdtp-accent); color: oklch(0.13 0 0); font-weight: 600; }\n.pdtp-btn-danger { border-color: color-mix(in oklch, var(--pdtp-danger), transparent 45%); color: var(--pdtp-danger); }\n.pdtp-error { margin-top: 10px; border: 1px solid color-mix(in oklch, var(--pdtp-danger), transparent 55%);\n border-radius: 8px; padding: 10px 12px; font-size: 0.85rem; color: var(--pdtp-danger); }\n.pdtp-error ul { margin: 6px 0 0; padding-left: 18px; color: var(--pdtp-fg); }\n.pdtp-note { color: var(--pdtp-muted); font-size: 0.82rem; margin: 10px 0 0; }\n\n.pdtp-icon-grid { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }\n.pdtp-icon-cell { display: flex; flex-direction: column; align-items: center; gap: 8px; border: 1px solid var(--pdtp-border);\n border-radius: 10px; padding: 14px 8px 10px; background: var(--pdtp-card); }\n.pdtp-icon-cell svg { width: 28px; height: 28px; color: var(--pdtp-fg); }\n.pdtp-icon-cell figcaption { font-family: ui-monospace, Consolas, monospace; font-size: 10.5px; color: var(--pdtp-muted);\n max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n\n.pdtp-img-grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }\n.pdtp-img-cell { border: 1px solid var(--pdtp-border); border-radius: 10px; overflow: hidden; background: var(--pdtp-card); }\n.pdtp-img-cell img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }\n.pdtp-img-cell figcaption { padding: 7px 10px; font-family: ui-monospace, Consolas, monospace; font-size: 10.5px;\n color: var(--pdtp-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n\n.pdtp-specimen { border: 1px solid var(--pdtp-border); background: var(--pdtp-card); border-radius: 12px; padding: 20px; margin-bottom: 14px; }\n.pdtp-specimen-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-bottom: 12px; }\n.pdtp-specimen-big { font-size: 2.2rem; line-height: 1.15; margin: 0 0 8px; overflow-wrap: break-word; }\n.pdtp-specimen-body { margin: 0; color: var(--pdtp-muted); }\n";
|
|
4
|
+
export declare const PDTP_CSS = "\n.pdtp { color-scheme: dark;\n --pdtp-accent: oklch(0.72 0.16 250); --pdtp-bg: oklch(0.145 0 0); --pdtp-card: oklch(0.2 0 0);\n --pdtp-fg: oklch(0.985 0 0); --pdtp-muted: oklch(0.708 0 0); --pdtp-border: oklch(1 0 0 / 12%);\n --pdtp-hover: oklch(1 0 0 / 7%); --pdtp-danger: oklch(0.65 0.18 25); --pdtp-warn: oklch(0.8 0.14 85);\n background: var(--pdtp-bg); color: var(--pdtp-fg); min-height: 60vh;\n font-family: ui-sans-serif, system-ui, sans-serif; font-size: 15px; line-height: 1.5; }\n.pdtp *, .pdtp *::before, .pdtp *::after { box-sizing: border-box; }\n.pdtp a { color: var(--pdtp-accent); text-decoration: none; }\n.pdtp a:hover { text-decoration: underline; }\n/* :where() keeps this reset at zero specificity so component classes below always win it. */\n:where(.pdtp) button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }\n\n.pdtp-container { max-width: 1000px; margin: 0 auto; padding: 40px 24px 80px; }\n.pdtp-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 24px; }\n.pdtp-head h1 { margin: 0; font-size: 1.5rem; letter-spacing: -0.02em; color: var(--pdtp-fg); }\n.pdtp-badge { font-family: ui-monospace, Consolas, monospace; font-size: 10px; text-transform: uppercase;\n letter-spacing: 0.08em; color: var(--pdtp-muted); border: 1px solid var(--pdtp-border); border-radius: 4px; padding: 2px 7px; }\n.pdtp-env { color: var(--pdtp-muted); font-size: 0.85rem; }\n\n.pdtp-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }\n.pdtp-card { border: 1px solid var(--pdtp-border); background: var(--pdtp-card); border-radius: 12px; padding: 16px; }\n.pdtp-card h2 { margin: 0 0 10px; font-size: 1rem; font-weight: 600; color: var(--pdtp-fg); display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }\n.pdtp-kind { font-family: ui-monospace, Consolas, monospace; font-size: 10.5px; text-transform: uppercase;\n letter-spacing: 0.06em; color: var(--pdtp-muted); font-weight: 400; }\n.pdtp-section { margin: 32px 0 0; }\n.pdtp-section > h2 { margin: 0 0 12px; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--pdtp-muted); font-weight: 600; }\n\n.pdtp-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }\n.pdtp-table td, .pdtp-table th { text-align: left; padding: 6px 10px; border-bottom: 1px solid var(--pdtp-border); }\n.pdtp-table th { color: var(--pdtp-muted); font-weight: 500; font-size: 0.8rem; }\n.pdtp-table td:last-child, .pdtp-table th:last-child { text-align: right; }\n.pdtp-mono { font-family: ui-monospace, Consolas, monospace; font-size: 0.85em; }\n.pdtp-code { font-family: ui-monospace, Consolas, monospace; font-size: 0.85em; background: oklch(0.26 0 0); padding: 1px 6px; border-radius: 4px; }\n.pdtp-muted { color: var(--pdtp-muted); }\n.pdtp-warn { color: var(--pdtp-warn); }\n\n.pdtp-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 7px; }\n.pdtp-dot-on { background: oklch(0.75 0.15 165); } .pdtp-dot-off { background: oklch(0.45 0 0); }\n.pdtp-chips { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 0.9rem; }\n\n.pdtp-chip { border: 1px solid var(--pdtp-border); border-radius: 999px; padding: 5px 14px; font-size: 0.85rem;\n background: oklch(0.26 0 0); transition: border-color 0.15s ease, background 0.15s ease; }\n.pdtp-chip:hover { background: oklch(0.31 0 0); border-color: oklch(0.45 0 0); }\n.pdtp-chip.pdtp-active { background: var(--pdtp-accent); border-color: var(--pdtp-accent); color: oklch(0.13 0 0); font-weight: 600; }\n.pdtp-seg { display: inline-flex; overflow: hidden; border: 1px solid var(--pdtp-border); border-radius: 999px; }\n.pdtp-seg button { padding: 4px 13px; font-size: 0.8rem; }\n.pdtp-seg button:hover { background: var(--pdtp-hover); }\n.pdtp-seg button.pdtp-active { background: var(--pdtp-accent); color: oklch(0.13 0 0); font-weight: 600; }\n\n.pdtp-btn { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--pdtp-border);\n border-radius: 8px; padding: 7px 14px; font-size: 0.9rem; font-weight: 500; }\n.pdtp-btn:hover { background: var(--pdtp-hover); text-decoration: none; }\n.pdtp-btn:disabled { opacity: 0.55; cursor: default; }\n.pdtp-btn-primary { background: var(--pdtp-accent); border-color: var(--pdtp-accent); color: oklch(0.13 0 0); font-weight: 600; }\n.pdtp-btn-danger { border-color: color-mix(in oklch, var(--pdtp-danger), transparent 45%); color: var(--pdtp-danger); }\n.pdtp-error { margin-top: 10px; border: 1px solid color-mix(in oklch, var(--pdtp-danger), transparent 55%);\n border-radius: 8px; padding: 10px 12px; font-size: 0.85rem; color: var(--pdtp-danger); }\n.pdtp-error ul { margin: 6px 0 0; padding-left: 18px; color: var(--pdtp-fg); }\n.pdtp-note { color: var(--pdtp-muted); font-size: 0.82rem; margin: 10px 0 0; }\n\n.pdtp-icon-grid { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }\n.pdtp-icon-cell { display: flex; flex-direction: column; align-items: center; gap: 8px; border: 1px solid var(--pdtp-border);\n border-radius: 10px; padding: 14px 8px 10px; background: var(--pdtp-card); }\n.pdtp-icon-cell svg { width: 28px; height: 28px; color: var(--pdtp-fg); }\n.pdtp-icon-cell figcaption { font-family: ui-monospace, Consolas, monospace; font-size: 10.5px; color: var(--pdtp-muted);\n max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n\n.pdtp-img-grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }\n.pdtp-img-cell { border: 1px solid var(--pdtp-border); border-radius: 10px; overflow: hidden; background: var(--pdtp-card); }\n.pdtp-img-cell img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }\n.pdtp-img-cell figcaption { padding: 7px 10px; font-family: ui-monospace, Consolas, monospace; font-size: 10.5px;\n color: var(--pdtp-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n\n/* /dev/revalidate \u2014 the dependency explorer */\n.pdtp-flow { height: 440px; border: 1px solid var(--pdtp-border); border-radius: 12px; overflow: hidden; background: var(--pdtp-card); }\n.pdtp-flow .react-flow { background: var(--pdtp-card); }\n.pdtp-flow-node { display: flex; align-items: center; gap: 8px; border: 1px solid var(--pdtp-border); background: oklch(0.26 0 0);\n border-radius: 8px; padding: 8px 12px; font-size: 13px; cursor: pointer; transition: border-color 0.15s ease; }\n.pdtp-flow-node:hover { border-color: oklch(0.5 0 0); }\n.pdtp-flow-node-active { border-color: var(--pdtp-accent); box-shadow: 0 0 0 1px var(--pdtp-accent); }\n.pdtp-flow-badges { display: inline-flex; gap: 6px; }\n.pdtp-flow-badges em { font-style: normal; font-family: ui-monospace, Consolas, monospace; font-size: 10px; color: var(--pdtp-muted);\n border: 1px solid var(--pdtp-border); border-radius: 4px; padding: 1px 5px; white-space: nowrap; }\n.pdtp-flow-badges em.pdtp-flow-warn { color: var(--pdtp-warn); border-color: color-mix(in oklch, var(--pdtp-warn), transparent 55%); }\n.pdtp-flow-handle { opacity: 0; pointer-events: none; }\n.pdtp-rev-cols { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }\n.pdtp-rev-subhead { margin: 0 0 8px; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--pdtp-muted); font-weight: 600; }\n.pdtp-rev-list { margin: 0; padding-left: 18px; font-size: 0.9rem; }\n.pdtp-rev-list li { margin: 3px 0; }\n\n.pdtp-specimen { border: 1px solid var(--pdtp-border); background: var(--pdtp-card); border-radius: 12px; padding: 20px; margin-bottom: 14px; }\n.pdtp-specimen-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-bottom: 12px; }\n.pdtp-specimen-big { font-size: 2.2rem; line-height: 1.15; margin: 0 0 8px; overflow-wrap: break-word; }\n.pdtp-specimen-body { margin: 0; color: var(--pdtp-muted); }\n";
|
|
5
5
|
//# sourceMappingURL=pageStyles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageStyles.d.ts","sourceRoot":"","sources":["../../src/next/pageStyles.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAC/D,eAAO,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"pageStyles.d.ts","sourceRoot":"","sources":["../../src/next/pageStyles.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAC/D,eAAO,MAAM,QAAQ,q0PA+FpB,CAAA"}
|