payload-nested-docs-page-tree 1.4.5 → 1.5.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/README.md +169 -257
- package/dist/components/PageTreeListView.client.d.ts +3 -2
- package/dist/components/PageTreeListView.client.js +11 -31
- package/dist/components/PageTreeListView.client.js.map +1 -1
- package/dist/components/PageTreeListView.module.css +63 -0
- package/dist/components/PageTreeListView.server.js +61 -16
- package/dist/components/PageTreeListView.server.js.map +1 -1
- package/dist/components/PageTreeStatusBadge.d.ts +6 -0
- package/dist/components/PageTreeStatusBadge.js +77 -0
- package/dist/components/PageTreeStatusBadge.js.map +1 -0
- package/dist/components/PageTreeTitleCell.js +3 -2
- package/dist/components/PageTreeTitleCell.js.map +1 -1
- package/dist/endpoints/createMovePageEndpoint.js +13 -14
- package/dist/endpoints/createMovePageEndpoint.js.map +1 -1
- package/dist/endpoints/createReorderPageEndpoint.js +3 -4
- package/dist/endpoints/createReorderPageEndpoint.js.map +1 -1
- package/dist/endpoints/shared.d.ts +1 -14
- package/dist/endpoints/shared.js +3 -6
- package/dist/endpoints/shared.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +15 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/badgeLinks.d.ts +29 -0
- package/dist/utilities/badgeLinks.js +47 -0
- package/dist/utilities/badgeLinks.js.map +1 -0
- package/dist/utilities/diagnostics.js +1 -1
- package/dist/utilities/diagnostics.js.map +1 -1
- package/dist/utilities/pageTreeConfig.js +1 -0
- package/dist/utilities/pageTreeConfig.js.map +1 -1
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ export type NestedDocsPageTreePluginResolvedHomeIndicatorConfig = {
|
|
|
20
20
|
};
|
|
21
21
|
export type NestedDocsPageTreePluginConfig = {
|
|
22
22
|
badges?: NestedDocsPageTreePluginBadgeConfig;
|
|
23
|
+
/** Opt in to status badge links. Preview uses the collection's admin.preview. */
|
|
24
|
+
badgesLinks?: NestedDocsPageTreePluginBadgesLinks;
|
|
23
25
|
breadcrumbsFieldSlug?: string;
|
|
24
26
|
collections: CollectionSlug[];
|
|
25
27
|
defaultLimit?: number;
|
|
@@ -35,7 +37,7 @@ export type NestedDocsPageTreePluginConfig = {
|
|
|
35
37
|
homeIndicator?: NestedDocsPageTreePluginHomeIndicatorConfig;
|
|
36
38
|
parentFieldSlug?: string;
|
|
37
39
|
/**
|
|
38
|
-
* Publish a hierarchy move immediately instead of staging it as a draft
|
|
40
|
+
* Publish a hierarchy move immediately instead of staging it as a draft - but
|
|
39
41
|
* ONLY when the moved document had no unpublished changes before the move (its
|
|
40
42
|
* latest version is already published). A document with pending draft edits (a
|
|
41
43
|
* "changed" or draft-only doc) always stays staged, so in-progress edits are
|
|
@@ -51,13 +53,25 @@ export type NestedDocsPageTreePluginConfig = {
|
|
|
51
53
|
};
|
|
52
54
|
export type NestedDocsPageTreePluginCollectionCustom = {
|
|
53
55
|
badges: NestedDocsPageTreePluginResolvedBadgeConfig;
|
|
56
|
+
badgesLinks?: NestedDocsPageTreePluginBadgesLinks;
|
|
54
57
|
breadcrumbsFieldSlug: string;
|
|
55
58
|
defaultLimit: number;
|
|
56
59
|
hideBreadcrumbs: boolean;
|
|
57
60
|
homeIndicator: NestedDocsPageTreePluginResolvedHomeIndicatorConfig;
|
|
58
61
|
parentFieldSlug: string;
|
|
59
62
|
};
|
|
63
|
+
export type NestedDocsPageTreePluginBadgesLinks = {
|
|
64
|
+
/** Which links to offer for a draft with a published version. @default 'both' */
|
|
65
|
+
draftHasPublishedVersion?: 'both' | 'live' | 'preview';
|
|
66
|
+
/** Website base URL, resolved with the published document's last breadcrumb URL. */
|
|
67
|
+
liveURL?: string;
|
|
68
|
+
};
|
|
69
|
+
export type PageTreeStatusLinks = {
|
|
70
|
+
previewURL?: string;
|
|
71
|
+
publicURL?: string;
|
|
72
|
+
};
|
|
60
73
|
export type PageTreeSourceDoc = Record<string, unknown> & {
|
|
74
|
+
__pageTreeStatusLinks?: PageTreeStatusLinks;
|
|
61
75
|
_displayStatus?: null | string;
|
|
62
76
|
_status?: null | string;
|
|
63
77
|
id?: number | string;
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { CollectionSlug } from 'payload'\n\nimport type { NestedDocsPageTreePluginDiagnosticsConfig } from './utilities/diagnostics.js'\n\nexport type {\n NestedDocsPageTreePluginDiagnosticEvent,\n NestedDocsPageTreePluginDiagnosticsConfig,\n} from './utilities/diagnostics.js'\n\nexport const nestedDocsPageTreePluginBadgeStatuses = ['published', 'changed', 'draft'] as const\n\nexport type NestedDocsPageTreePluginBadgeStatus =\n (typeof nestedDocsPageTreePluginBadgeStatuses)[number]\n\nexport type NestedDocsPageTreePluginBadgeMap = Partial<\n Record<NestedDocsPageTreePluginBadgeStatus, string>\n>\n\nexport type NestedDocsPageTreePluginBadgeConfig = {\n colors?: NestedDocsPageTreePluginBadgeMap\n labels?: NestedDocsPageTreePluginBadgeMap\n}\n\nexport type NestedDocsPageTreePluginResolvedBadgeConfig = {\n colors: NestedDocsPageTreePluginBadgeMap\n labels: NestedDocsPageTreePluginBadgeMap\n}\n\nexport type NestedDocsPageTreePluginHomeIndicatorConfig =\n | false\n | {\n collections?: CollectionSlug[]\n }\n\nexport type NestedDocsPageTreePluginResolvedHomeIndicatorConfig = {\n enabled: boolean\n}\n\nexport type NestedDocsPageTreePluginConfig = {\n badges?: NestedDocsPageTreePluginBadgeConfig\n breadcrumbsFieldSlug?: string\n collections: CollectionSlug[]\n defaultLimit?: number\n /**\n * When set, the plugin emits structured diagnostic events for page-tree\n * triggered moves, including before/after snapshots of the published main row.\n * Disabled by default. Pass `true` to log to `console`, or pass an object\n * with a custom `logger` to route events elsewhere.\n */\n diagnostics?: NestedDocsPageTreePluginDiagnosticsConfig\n disabled?: boolean\n hideBreadcrumbs?: boolean\n homeIndicator?: NestedDocsPageTreePluginHomeIndicatorConfig\n parentFieldSlug?: string\n /**\n * Publish a hierarchy move immediately instead of staging it as a draft
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { CollectionSlug } from 'payload'\n\nimport type { NestedDocsPageTreePluginDiagnosticsConfig } from './utilities/diagnostics.js'\n\nexport type {\n NestedDocsPageTreePluginDiagnosticEvent,\n NestedDocsPageTreePluginDiagnosticsConfig,\n} from './utilities/diagnostics.js'\n\nexport const nestedDocsPageTreePluginBadgeStatuses = ['published', 'changed', 'draft'] as const\n\nexport type NestedDocsPageTreePluginBadgeStatus =\n (typeof nestedDocsPageTreePluginBadgeStatuses)[number]\n\nexport type NestedDocsPageTreePluginBadgeMap = Partial<\n Record<NestedDocsPageTreePluginBadgeStatus, string>\n>\n\nexport type NestedDocsPageTreePluginBadgeConfig = {\n colors?: NestedDocsPageTreePluginBadgeMap\n labels?: NestedDocsPageTreePluginBadgeMap\n}\n\nexport type NestedDocsPageTreePluginResolvedBadgeConfig = {\n colors: NestedDocsPageTreePluginBadgeMap\n labels: NestedDocsPageTreePluginBadgeMap\n}\n\nexport type NestedDocsPageTreePluginHomeIndicatorConfig =\n | false\n | {\n collections?: CollectionSlug[]\n }\n\nexport type NestedDocsPageTreePluginResolvedHomeIndicatorConfig = {\n enabled: boolean\n}\n\nexport type NestedDocsPageTreePluginConfig = {\n badges?: NestedDocsPageTreePluginBadgeConfig\n /** Opt in to status badge links. Preview uses the collection's admin.preview. */\n badgesLinks?: NestedDocsPageTreePluginBadgesLinks\n breadcrumbsFieldSlug?: string\n collections: CollectionSlug[]\n defaultLimit?: number\n /**\n * When set, the plugin emits structured diagnostic events for page-tree\n * triggered moves, including before/after snapshots of the published main row.\n * Disabled by default. Pass `true` to log to `console`, or pass an object\n * with a custom `logger` to route events elsewhere.\n */\n diagnostics?: NestedDocsPageTreePluginDiagnosticsConfig\n disabled?: boolean\n hideBreadcrumbs?: boolean\n homeIndicator?: NestedDocsPageTreePluginHomeIndicatorConfig\n parentFieldSlug?: string\n /**\n * Publish a hierarchy move immediately instead of staging it as a draft - but\n * ONLY when the moved document had no unpublished changes before the move (its\n * latest version is already published). A document with pending draft edits (a\n * \"changed\" or draft-only doc) always stays staged, so in-progress edits are\n * never published as a side effect of a move. Only affects collections with\n * drafts enabled; collections without drafts move live regardless.\n *\n * Disabled by default: every move is staged as a draft and the live URL/path\n * changes only when the document is next published.\n *\n * @default false\n */\n publishOnMove?: boolean\n}\n\nexport type NestedDocsPageTreePluginCollectionCustom = {\n badges: NestedDocsPageTreePluginResolvedBadgeConfig\n badgesLinks?: NestedDocsPageTreePluginBadgesLinks\n breadcrumbsFieldSlug: string\n defaultLimit: number\n hideBreadcrumbs: boolean\n homeIndicator: NestedDocsPageTreePluginResolvedHomeIndicatorConfig\n parentFieldSlug: string\n}\n\nexport type NestedDocsPageTreePluginBadgesLinks = {\n /** Which links to offer for a draft with a published version. @default 'both' */\n draftHasPublishedVersion?: 'both' | 'live' | 'preview'\n /** Website base URL, resolved with the published document's last breadcrumb URL. */\n liveURL?: string\n}\n\nexport type PageTreeStatusLinks = {\n previewURL?: string\n publicURL?: string\n}\n\nexport type PageTreeSourceDoc = Record<string, unknown> & {\n __pageTreeStatusLinks?: PageTreeStatusLinks\n _displayStatus?: null | string\n _status?: null | string\n id?: number | string\n slug?: null | string\n}\n\nexport const nestedDocsPageTreePluginCustomKey = 'nestedDocsPageTreePlugin'\n\n/**\n * Set on Payload's hook context for every page-tree write that leaves the\n * published site unchanged: sibling reorders, and parent moves staged as\n * drafts. Deploy/revalidate hooks read it to skip rebuilds they do not need.\n *\n * It is deliberately NOT set when `publishOnMove` publishes a move, because\n * that move changed the live URL of the page and its descendants and the site\n * does need rebuilding. That way one guard covers every configuration:\n *\n * ```ts\n * if (req.context?.[pageTreeMoveContextKey]) return\n * ```\n *\n * Note the flag describes the *effect* of the write, not its kind - it is\n * absent on published moves even though those are still page-tree moves. Use\n * `pageTreeWriteContextKey` when you need \"was this a page-tree write at all\".\n */\nexport const pageTreeMoveContextKey = 'pageTreeMove'\n\n/**\n * Internal: set on every page-tree write regardless of whether it published.\n * Diagnostics uses it so that published moves are still traced, which is the\n * case most worth observing. Not part of the public API.\n */\nexport const pageTreeWriteContextKey = 'pageTreeWrite'\n\nexport type PageTreeMoveContext = {\n [pageTreeMoveContextKey]?: boolean\n [pageTreeWriteContextKey]?: boolean\n}\n"],"names":["nestedDocsPageTreePluginBadgeStatuses","nestedDocsPageTreePluginCustomKey","pageTreeMoveContextKey","pageTreeWriteContextKey"],"mappings":"AASA,OAAO,MAAMA,wCAAwC;IAAC;IAAa;IAAW;CAAQ,CAAS;AA6F/F,OAAO,MAAMC,oCAAoC,2BAA0B;AAE3E;;;;;;;;;;;;;;;;CAgBC,GACD,OAAO,MAAMC,yBAAyB,eAAc;AAEpD;;;;CAIC,GACD,OAAO,MAAMC,0BAA0B,gBAAe"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { NestedDocsPageTreePluginBadgesLinks, PageTreeSourceDoc, PageTreeStatusLinks } from '../types.js';
|
|
2
|
+
export type BadgeLinkRequest = {
|
|
3
|
+
locale?: null | string;
|
|
4
|
+
payload: {
|
|
5
|
+
logger: {
|
|
6
|
+
error(value: unknown): unknown;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
url?: string;
|
|
10
|
+
};
|
|
11
|
+
export type BadgeLinkCollectionConfig<TRequest extends BadgeLinkRequest> = {
|
|
12
|
+
admin: {
|
|
13
|
+
preview?: (doc: Record<string, unknown>, options: {
|
|
14
|
+
locale: string;
|
|
15
|
+
req: TRequest;
|
|
16
|
+
token: null | string;
|
|
17
|
+
}) => null | Promise<null | string> | string;
|
|
18
|
+
};
|
|
19
|
+
slug: string;
|
|
20
|
+
};
|
|
21
|
+
export declare function resolvePageTreeBadgeLinks<TRequest extends BadgeLinkRequest>(args: {
|
|
22
|
+
badgesLinks?: NestedDocsPageTreePluginBadgesLinks;
|
|
23
|
+
breadcrumbsFieldSlug: string;
|
|
24
|
+
collectionConfig: BadgeLinkCollectionConfig<TRequest>;
|
|
25
|
+
draftDoc: PageTreeSourceDoc;
|
|
26
|
+
publishedDoc?: PageTreeSourceDoc;
|
|
27
|
+
req: TRequest;
|
|
28
|
+
token: null | string;
|
|
29
|
+
}): Promise<PageTreeStatusLinks>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { getPageTreeDisplayStatus } from './status.js';
|
|
2
|
+
export async function resolvePageTreeBadgeLinks(args) {
|
|
3
|
+
const { badgesLinks, breadcrumbsFieldSlug, collectionConfig, draftDoc, publishedDoc, req, token } = args;
|
|
4
|
+
if (!badgesLinks) {
|
|
5
|
+
return {};
|
|
6
|
+
}
|
|
7
|
+
const mode = badgesLinks.draftHasPublishedVersion ?? 'both';
|
|
8
|
+
const status = getPageTreeDisplayStatus(draftDoc);
|
|
9
|
+
const links = {};
|
|
10
|
+
async function resolve(kind, generate) {
|
|
11
|
+
try {
|
|
12
|
+
const value = await generate();
|
|
13
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const url = new URL(value.trim(), req.url);
|
|
17
|
+
if (url.protocol === 'http:' || url.protocol === 'https:') {
|
|
18
|
+
links[kind] = url.href;
|
|
19
|
+
}
|
|
20
|
+
} catch {
|
|
21
|
+
req.payload.logger.error({
|
|
22
|
+
collection: collectionConfig.slug,
|
|
23
|
+
destination: kind,
|
|
24
|
+
docID: draftDoc.id,
|
|
25
|
+
msg: 'Could not resolve page tree badge URL'
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if ((status === 'published' || status === 'changed' && mode !== 'preview') && badgesLinks.liveURL && publishedDoc?._status === 'published') {
|
|
30
|
+
const breadcrumbs = publishedDoc[breadcrumbsFieldSlug];
|
|
31
|
+
const path = Array.isArray(breadcrumbs) ? breadcrumbs.at(-1)?.url : undefined;
|
|
32
|
+
if (typeof path === 'string' && path.trim()) {
|
|
33
|
+
await resolve('publicURL', ()=>new URL(path.trim(), badgesLinks.liveURL).href);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if ((status === 'draft' || status === 'changed' && mode !== 'live') && collectionConfig.admin.preview) {
|
|
37
|
+
const preview = collectionConfig.admin.preview;
|
|
38
|
+
await resolve('previewURL', ()=>preview(draftDoc, {
|
|
39
|
+
locale: req.locale,
|
|
40
|
+
req,
|
|
41
|
+
token
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
return links;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=badgeLinks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/badgeLinks.ts"],"sourcesContent":["import type {\n NestedDocsPageTreePluginBadgesLinks,\n PageTreeSourceDoc,\n PageTreeStatusLinks,\n} from '../types.js'\n\nimport { getPageTreeDisplayStatus } from './status.js'\n\nexport type BadgeLinkRequest = {\n locale?: null | string\n payload: {\n logger: {\n error(value: unknown): unknown\n }\n }\n url?: string\n}\n\nexport type BadgeLinkCollectionConfig<TRequest extends BadgeLinkRequest> = {\n admin: {\n preview?: (\n doc: Record<string, unknown>,\n options: { locale: string; req: TRequest; token: null | string },\n ) => null | Promise<null | string> | string\n }\n slug: string\n}\n\nexport async function resolvePageTreeBadgeLinks<TRequest extends BadgeLinkRequest>(args: {\n badgesLinks?: NestedDocsPageTreePluginBadgesLinks\n breadcrumbsFieldSlug: string\n collectionConfig: BadgeLinkCollectionConfig<TRequest>\n draftDoc: PageTreeSourceDoc\n publishedDoc?: PageTreeSourceDoc\n req: TRequest\n token: null | string\n}): Promise<PageTreeStatusLinks> {\n const {\n badgesLinks,\n breadcrumbsFieldSlug,\n collectionConfig,\n draftDoc,\n publishedDoc,\n req,\n token,\n } = args\n if (!badgesLinks) {\n return {}\n }\n const mode = badgesLinks.draftHasPublishedVersion ?? 'both'\n const status = getPageTreeDisplayStatus(draftDoc)\n const links: PageTreeStatusLinks = {}\n\n async function resolve(kind: keyof PageTreeStatusLinks, generate: () => unknown) {\n try {\n const value = await generate()\n if (typeof value !== 'string' || !value.trim()) {\n return\n }\n const url = new URL(value.trim(), req.url)\n if (url.protocol === 'http:' || url.protocol === 'https:') {\n links[kind] = url.href\n }\n } catch {\n req.payload.logger.error({\n collection: collectionConfig.slug,\n destination: kind,\n docID: draftDoc.id,\n msg: 'Could not resolve page tree badge URL',\n })\n }\n }\n\n if (\n (status === 'published' || (status === 'changed' && mode !== 'preview')) &&\n badgesLinks.liveURL &&\n publishedDoc?._status === 'published'\n ) {\n const breadcrumbs = publishedDoc[breadcrumbsFieldSlug]\n const path: unknown = Array.isArray(breadcrumbs) ? breadcrumbs.at(-1)?.url : undefined\n if (typeof path === 'string' && path.trim()) {\n await resolve('publicURL', () => new URL(path.trim(), badgesLinks.liveURL).href)\n }\n }\n if (\n (status === 'draft' || (status === 'changed' && mode !== 'live')) &&\n collectionConfig.admin.preview\n ) {\n const preview = collectionConfig.admin.preview\n await resolve('previewURL', () =>\n preview(draftDoc, {\n locale: req.locale!,\n req,\n token,\n }),\n )\n }\n return links\n}\n"],"names":["getPageTreeDisplayStatus","resolvePageTreeBadgeLinks","args","badgesLinks","breadcrumbsFieldSlug","collectionConfig","draftDoc","publishedDoc","req","token","mode","draftHasPublishedVersion","status","links","resolve","kind","generate","value","trim","url","URL","protocol","href","payload","logger","error","collection","slug","destination","docID","id","msg","liveURL","_status","breadcrumbs","path","Array","isArray","at","undefined","admin","preview","locale"],"mappings":"AAMA,SAASA,wBAAwB,QAAQ,cAAa;AAsBtD,OAAO,eAAeC,0BAA6DC,IAQlF;IACC,MAAM,EACJC,WAAW,EACXC,oBAAoB,EACpBC,gBAAgB,EAChBC,QAAQ,EACRC,YAAY,EACZC,GAAG,EACHC,KAAK,EACN,GAAGP;IACJ,IAAI,CAACC,aAAa;QAChB,OAAO,CAAC;IACV;IACA,MAAMO,OAAOP,YAAYQ,wBAAwB,IAAI;IACrD,MAAMC,SAASZ,yBAAyBM;IACxC,MAAMO,QAA6B,CAAC;IAEpC,eAAeC,QAAQC,IAA+B,EAAEC,QAAuB;QAC7E,IAAI;YACF,MAAMC,QAAQ,MAAMD;YACpB,IAAI,OAAOC,UAAU,YAAY,CAACA,MAAMC,IAAI,IAAI;gBAC9C;YACF;YACA,MAAMC,MAAM,IAAIC,IAAIH,MAAMC,IAAI,IAAIV,IAAIW,GAAG;YACzC,IAAIA,IAAIE,QAAQ,KAAK,WAAWF,IAAIE,QAAQ,KAAK,UAAU;gBACzDR,KAAK,CAACE,KAAK,GAAGI,IAAIG,IAAI;YACxB;QACF,EAAE,OAAM;YACNd,IAAIe,OAAO,CAACC,MAAM,CAACC,KAAK,CAAC;gBACvBC,YAAYrB,iBAAiBsB,IAAI;gBACjCC,aAAab;gBACbc,OAAOvB,SAASwB,EAAE;gBAClBC,KAAK;YACP;QACF;IACF;IAEA,IACE,AAACnB,CAAAA,WAAW,eAAgBA,WAAW,aAAaF,SAAS,SAAS,KACtEP,YAAY6B,OAAO,IACnBzB,cAAc0B,YAAY,aAC1B;QACA,MAAMC,cAAc3B,YAAY,CAACH,qBAAqB;QACtD,MAAM+B,OAAgBC,MAAMC,OAAO,CAACH,eAAeA,YAAYI,EAAE,CAAC,CAAC,IAAInB,MAAMoB;QAC7E,IAAI,OAAOJ,SAAS,YAAYA,KAAKjB,IAAI,IAAI;YAC3C,MAAMJ,QAAQ,aAAa,IAAM,IAAIM,IAAIe,KAAKjB,IAAI,IAAIf,YAAY6B,OAAO,EAAEV,IAAI;QACjF;IACF;IACA,IACE,AAACV,CAAAA,WAAW,WAAYA,WAAW,aAAaF,SAAS,MAAM,KAC/DL,iBAAiBmC,KAAK,CAACC,OAAO,EAC9B;QACA,MAAMA,UAAUpC,iBAAiBmC,KAAK,CAACC,OAAO;QAC9C,MAAM3B,QAAQ,cAAc,IAC1B2B,QAAQnC,UAAU;gBAChBoC,QAAQlC,IAAIkC,MAAM;gBAClBlC;gBACAC;YACF;IAEJ;IACA,OAAOI;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/diagnostics.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nimport { stringifyDocID } from './pageTree.js'\n\nexport type NestedDocsPageTreePluginDiagnosticEvent = {\n collection: string\n data: Record<string, unknown>\n /** Stable identifier for grouping events from the same logical operation. */\n flow: string\n level: 'error' | 'info' | 'warn'\n message: string\n source:\n | 'move-endpoint:body-rejected'\n | 'move-endpoint:enter'\n | 'move-endpoint:error'\n | 'move-endpoint:ok'\n | 'move-endpoint:snapshot-after'\n | 'move-endpoint:snapshot-before'\n | 'page-tree-change:after'\n | 'page-tree-change:status-flip'\n | 'reorder-endpoint:body-rejected'\n | 'reorder-endpoint:enter'\n | 'reorder-endpoint:error'\n | 'reorder-endpoint:initial-migration'\n | 'reorder-endpoint:ok'\n /** ISO timestamp; included so log dumps are self-describing. */\n t: string\n}\n\nexport type NestedDocsPageTreePluginDiagnosticsConfig =\n | {\n enabled: boolean\n /**\n * Custom event sink. Defaults to a single-line `console.log` per event.\n * Useful for routing diagnostics through `req.payload.logger` or similar.\n */\n logger?: (event: NestedDocsPageTreePluginDiagnosticEvent) => void\n }\n | boolean\n\nexport type Diagnostics = {\n enabled: boolean\n log: (event: Omit<NestedDocsPageTreePluginDiagnosticEvent, 't'>) => void\n}\n\nconst NOOP_DIAGNOSTICS: Diagnostics = {\n enabled: false,\n log: () => {},\n}\n\nconst DEFAULT_TAG = '[payload-nested-docs-page-tree]'\nconst DEFAULT_TAG_COLOR = '\\x1b[38;2;59;130;246m'\nconst DEFAULT_TAG_STYLE = '\\x1b[1m'\nconst RESET_STYLE = '\\x1b[0m'\n\n/** Context key used to thread a diagnostics flow id from the move endpoint into afterChange logs. */\nexport const DIAGNOSTICS_FLOW_CONTEXT_KEY = '__pageTreeDiagnosticsFlow'\n\nfunction defaultLogger(event: NestedDocsPageTreePluginDiagnosticEvent): void {\n // One line per event keeps terminal copy-paste usable while preserving all fields.\n // eslint-disable-next-line no-console\n console.log(\n `${DEFAULT_TAG_STYLE}${DEFAULT_TAG_COLOR}${DEFAULT_TAG} ${event.source}${RESET_STYLE} ${event.message}`,\n JSON.stringify(event),\n )\n}\n\nexport function resolveDiagnostics(\n config: NestedDocsPageTreePluginDiagnosticsConfig | undefined,\n): Diagnostics {\n if (!config) {\n return NOOP_DIAGNOSTICS\n }\n\n const enabled = typeof config === 'boolean' ? config : Boolean(config.enabled)\n\n if (!enabled) {\n return NOOP_DIAGNOSTICS\n }\n\n const logger = typeof config === 'object' && config.logger ? config.logger : defaultLogger\n\n return {\n enabled: true,\n log(event) {\n try {\n logger({ ...event, t: new Date().toISOString() })\n } catch {\n // Diagnostics must never break a request.\n }\n },\n }\n}\n\n/** Generate a short flow id so multi-event sequences group together in logs. */\nexport function createFlowID(prefix: string): string {\n return `${prefix}-${Math.random().toString(36).slice(2, 8)}-${Date.now().toString(36)}`\n}\n\n/**\n * Read a doc directly from the published main-row layer (`draft: false`).\n * Returns null when the doc is unpublished or unreadable so callers can log\n * the absence instead of failing the request.\n */\nexport async function readMainRowSnapshot(args: {\n collectionSlug: string\n fields: ReadonlyArray<string>\n id: number | string\n req: PayloadRequest\n}): Promise<null | Record<string, unknown>> {\n const { id, collectionSlug, fields, req } = args\n\n try {\n const doc = (await req.payload.findByID({\n id
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/diagnostics.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nimport { stringifyDocID } from './pageTree.js'\n\nexport type NestedDocsPageTreePluginDiagnosticEvent = {\n collection: string\n data: Record<string, unknown>\n /** Stable identifier for grouping events from the same logical operation. */\n flow: string\n level: 'error' | 'info' | 'warn'\n message: string\n source:\n | 'move-endpoint:body-rejected'\n | 'move-endpoint:enter'\n | 'move-endpoint:error'\n | 'move-endpoint:ok'\n | 'move-endpoint:snapshot-after'\n | 'move-endpoint:snapshot-before'\n | 'page-tree-change:after'\n | 'page-tree-change:status-flip'\n | 'reorder-endpoint:body-rejected'\n | 'reorder-endpoint:enter'\n | 'reorder-endpoint:error'\n | 'reorder-endpoint:initial-migration'\n | 'reorder-endpoint:ok'\n /** ISO timestamp; included so log dumps are self-describing. */\n t: string\n}\n\nexport type NestedDocsPageTreePluginDiagnosticsConfig =\n | {\n enabled: boolean\n /**\n * Custom event sink. Defaults to a single-line `console.log` per event.\n * Useful for routing diagnostics through `req.payload.logger` or similar.\n */\n logger?: (event: NestedDocsPageTreePluginDiagnosticEvent) => void\n }\n | boolean\n\nexport type Diagnostics = {\n enabled: boolean\n log: (event: Omit<NestedDocsPageTreePluginDiagnosticEvent, 't'>) => void\n}\n\nconst NOOP_DIAGNOSTICS: Diagnostics = {\n enabled: false,\n log: () => {},\n}\n\nconst DEFAULT_TAG = '[payload-nested-docs-page-tree]'\nconst DEFAULT_TAG_COLOR = '\\x1b[38;2;59;130;246m'\nconst DEFAULT_TAG_STYLE = '\\x1b[1m'\nconst RESET_STYLE = '\\x1b[0m'\n\n/** Context key used to thread a diagnostics flow id from the move endpoint into afterChange logs. */\nexport const DIAGNOSTICS_FLOW_CONTEXT_KEY = '__pageTreeDiagnosticsFlow'\n\nfunction defaultLogger(event: NestedDocsPageTreePluginDiagnosticEvent): void {\n // One line per event keeps terminal copy-paste usable while preserving all fields.\n // eslint-disable-next-line no-console\n console.log(\n `${DEFAULT_TAG_STYLE}${DEFAULT_TAG_COLOR}${DEFAULT_TAG} ${event.source}${RESET_STYLE} ${event.message}`,\n JSON.stringify(event),\n )\n}\n\nexport function resolveDiagnostics(\n config: NestedDocsPageTreePluginDiagnosticsConfig | undefined,\n): Diagnostics {\n if (!config) {\n return NOOP_DIAGNOSTICS\n }\n\n const enabled = typeof config === 'boolean' ? config : Boolean(config.enabled)\n\n if (!enabled) {\n return NOOP_DIAGNOSTICS\n }\n\n const logger = typeof config === 'object' && config.logger ? config.logger : defaultLogger\n\n return {\n enabled: true,\n log(event) {\n try {\n logger({ ...event, t: new Date().toISOString() })\n } catch {\n // Diagnostics must never break a request.\n }\n },\n }\n}\n\n/** Generate a short flow id so multi-event sequences group together in logs. */\nexport function createFlowID(prefix: string): string {\n return `${prefix}-${Math.random().toString(36).slice(2, 8)}-${Date.now().toString(36)}`\n}\n\n/**\n * Read a doc directly from the published main-row layer (`draft: false`).\n * Returns null when the doc is unpublished or unreadable so callers can log\n * the absence instead of failing the request.\n */\nexport async function readMainRowSnapshot(args: {\n collectionSlug: string\n fields: ReadonlyArray<string>\n id: number | string\n req: PayloadRequest\n}): Promise<null | Record<string, unknown>> {\n const { id, collectionSlug, fields, req } = args\n\n try {\n const doc = (await req.payload.findByID({\n id,\n collection: collectionSlug,\n depth: 0,\n disableErrors: true,\n draft: false,\n overrideAccess: true,\n req,\n })) as unknown as null | Record<string, unknown>\n\n if (!doc) {\n return null\n }\n\n const snapshot: Record<string, unknown> = {\n id: stringifyDocID(typeof doc.id === 'number' || typeof doc.id === 'string' ? doc.id : undefined),\n }\n\n for (const field of fields) {\n snapshot[field] = projectField(doc[field])\n }\n\n return snapshot\n } catch {\n return null\n }\n}\n\n/** Collapse populated relationship docs to their id so logs stay compact. */\nexport function projectField(value: unknown): unknown {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const candidate = value as { id?: unknown }\n\n if ('id' in candidate) {\n const id = candidate.id\n\n return typeof id === 'number' || typeof id === 'string' ? stringifyDocID(id) : value\n }\n }\n\n return value\n}\n"],"names":["stringifyDocID","NOOP_DIAGNOSTICS","enabled","log","DEFAULT_TAG","DEFAULT_TAG_COLOR","DEFAULT_TAG_STYLE","RESET_STYLE","DIAGNOSTICS_FLOW_CONTEXT_KEY","defaultLogger","event","console","source","message","JSON","stringify","resolveDiagnostics","config","Boolean","logger","t","Date","toISOString","createFlowID","prefix","Math","random","toString","slice","now","readMainRowSnapshot","args","id","collectionSlug","fields","req","doc","payload","findByID","collection","depth","disableErrors","draft","overrideAccess","snapshot","undefined","field","projectField","value","Array","isArray","candidate"],"mappings":"AAEA,SAASA,cAAc,QAAQ,gBAAe;AA2C9C,MAAMC,mBAAgC;IACpCC,SAAS;IACTC,KAAK,KAAO;AACd;AAEA,MAAMC,cAAc;AACpB,MAAMC,oBAAoB;AAC1B,MAAMC,oBAAoB;AAC1B,MAAMC,cAAc;AAEpB,mGAAmG,GACnG,OAAO,MAAMC,+BAA+B,4BAA2B;AAEvE,SAASC,cAAcC,KAA8C;IACnE,mFAAmF;IACnF,sCAAsC;IACtCC,QAAQR,GAAG,CACT,GAAGG,oBAAoBD,oBAAoBD,YAAY,CAAC,EAAEM,MAAME,MAAM,GAAGL,YAAY,CAAC,EAAEG,MAAMG,OAAO,EAAE,EACvGC,KAAKC,SAAS,CAACL;AAEnB;AAEA,OAAO,SAASM,mBACdC,MAA6D;IAE7D,IAAI,CAACA,QAAQ;QACX,OAAOhB;IACT;IAEA,MAAMC,UAAU,OAAOe,WAAW,YAAYA,SAASC,QAAQD,OAAOf,OAAO;IAE7E,IAAI,CAACA,SAAS;QACZ,OAAOD;IACT;IAEA,MAAMkB,SAAS,OAAOF,WAAW,YAAYA,OAAOE,MAAM,GAAGF,OAAOE,MAAM,GAAGV;IAE7E,OAAO;QACLP,SAAS;QACTC,KAAIO,KAAK;YACP,IAAI;gBACFS,OAAO;oBAAE,GAAGT,KAAK;oBAAEU,GAAG,IAAIC,OAAOC,WAAW;gBAAG;YACjD,EAAE,OAAM;YACN,0CAA0C;YAC5C;QACF;IACF;AACF;AAEA,8EAA8E,GAC9E,OAAO,SAASC,aAAaC,MAAc;IACzC,OAAO,GAAGA,OAAO,CAAC,EAAEC,KAAKC,MAAM,GAAGC,QAAQ,CAAC,IAAIC,KAAK,CAAC,GAAG,GAAG,CAAC,EAAEP,KAAKQ,GAAG,GAAGF,QAAQ,CAAC,KAAK;AACzF;AAEA;;;;CAIC,GACD,OAAO,eAAeG,oBAAoBC,IAKzC;IACC,MAAM,EAAEC,EAAE,EAAEC,cAAc,EAAEC,MAAM,EAAEC,GAAG,EAAE,GAAGJ;IAE5C,IAAI;QACF,MAAMK,MAAO,MAAMD,IAAIE,OAAO,CAACC,QAAQ,CAAC;YACtCN;YACAO,YAAYN;YACZO,OAAO;YACPC,eAAe;YACfC,OAAO;YACPC,gBAAgB;YAChBR;QACF;QAEA,IAAI,CAACC,KAAK;YACR,OAAO;QACT;QAEA,MAAMQ,WAAoC;YACxCZ,IAAIhC,eAAe,OAAOoC,IAAIJ,EAAE,KAAK,YAAY,OAAOI,IAAIJ,EAAE,KAAK,WAAWI,IAAIJ,EAAE,GAAGa;QACzF;QAEA,KAAK,MAAMC,SAASZ,OAAQ;YAC1BU,QAAQ,CAACE,MAAM,GAAGC,aAAaX,GAAG,CAACU,MAAM;QAC3C;QAEA,OAAOF;IACT,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,2EAA2E,GAC3E,OAAO,SAASG,aAAaC,KAAc;IACzC,IAAIA,SAAS,OAAOA,UAAU,YAAY,CAACC,MAAMC,OAAO,CAACF,QAAQ;QAC/D,MAAMG,YAAYH;QAElB,IAAI,QAAQG,WAAW;YACrB,MAAMnB,KAAKmB,UAAUnB,EAAE;YAEvB,OAAO,OAAOA,OAAO,YAAY,OAAOA,OAAO,WAAWhC,eAAegC,MAAMgB;QACjF;IACF;IAEA,OAAOA;AACT"}
|
|
@@ -11,6 +11,7 @@ export function getCollectionPageTreeConfig(collection) {
|
|
|
11
11
|
}
|
|
12
12
|
return {
|
|
13
13
|
badges: normalizeNestedDocsPageTreePluginBadgeConfig(config.badges),
|
|
14
|
+
badgesLinks: config.badgesLinks,
|
|
14
15
|
breadcrumbsFieldSlug: config.breadcrumbsFieldSlug,
|
|
15
16
|
defaultLimit: config.defaultLimit,
|
|
16
17
|
hideBreadcrumbs: config.hideBreadcrumbs,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/pageTreeConfig.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\n\nimport type { NestedDocsPageTreePluginCollectionCustom } from '../types.js'\nimport { nestedDocsPageTreePluginCustomKey } from '../types.js'\nimport { normalizeNestedDocsPageTreePluginBadgeConfig } from './badgeConfig.js'\n\nexport function getCollectionPageTreeConfig(\n collection: Pick<CollectionConfig, 'custom'>,\n): null | NestedDocsPageTreePluginCollectionCustom {\n const value = collection.custom?.[nestedDocsPageTreePluginCustomKey]\n\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null\n }\n\n const config = value as Partial<NestedDocsPageTreePluginCollectionCustom>\n\n if (\n typeof config.breadcrumbsFieldSlug !== 'string' ||\n typeof config.defaultLimit !== 'number' ||\n typeof config.hideBreadcrumbs !== 'boolean' ||\n !config.homeIndicator ||\n typeof config.homeIndicator !== 'object' ||\n Array.isArray(config.homeIndicator) ||\n typeof config.homeIndicator.enabled !== 'boolean' ||\n typeof config.parentFieldSlug !== 'string'\n ) {\n return null\n }\n\n return {\n badges: normalizeNestedDocsPageTreePluginBadgeConfig(config.badges),\n breadcrumbsFieldSlug: config.breadcrumbsFieldSlug,\n defaultLimit: config.defaultLimit,\n hideBreadcrumbs: config.hideBreadcrumbs,\n homeIndicator: {\n enabled: config.homeIndicator.enabled,\n },\n parentFieldSlug: config.parentFieldSlug,\n }\n}\n"],"names":["nestedDocsPageTreePluginCustomKey","normalizeNestedDocsPageTreePluginBadgeConfig","getCollectionPageTreeConfig","collection","value","custom","Array","isArray","config","breadcrumbsFieldSlug","defaultLimit","hideBreadcrumbs","homeIndicator","enabled","parentFieldSlug","badges"],"mappings":"AAGA,SAASA,iCAAiC,QAAQ,cAAa;AAC/D,SAASC,4CAA4C,QAAQ,mBAAkB;AAE/E,OAAO,SAASC,4BACdC,UAA4C;IAE5C,MAAMC,QAAQD,WAAWE,MAAM,EAAE,CAACL,kCAAkC;IAEpE,IAAI,CAACI,SAAS,OAAOA,UAAU,YAAYE,MAAMC,OAAO,CAACH,QAAQ;QAC/D,OAAO;IACT;IAEA,MAAMI,SAASJ;IAEf,IACE,OAAOI,OAAOC,oBAAoB,KAAK,YACvC,OAAOD,OAAOE,YAAY,KAAK,YAC/B,OAAOF,OAAOG,eAAe,KAAK,aAClC,CAACH,OAAOI,aAAa,IACrB,OAAOJ,OAAOI,aAAa,KAAK,YAChCN,MAAMC,OAAO,CAACC,OAAOI,aAAa,KAClC,OAAOJ,OAAOI,aAAa,CAACC,OAAO,KAAK,aACxC,OAAOL,OAAOM,eAAe,KAAK,UAClC;QACA,OAAO;IACT;IAEA,OAAO;QACLC,QAAQd,6CAA6CO,OAAOO,MAAM;
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/pageTreeConfig.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\n\nimport type { NestedDocsPageTreePluginCollectionCustom } from '../types.js'\nimport { nestedDocsPageTreePluginCustomKey } from '../types.js'\nimport { normalizeNestedDocsPageTreePluginBadgeConfig } from './badgeConfig.js'\n\nexport function getCollectionPageTreeConfig(\n collection: Pick<CollectionConfig, 'custom'>,\n): null | NestedDocsPageTreePluginCollectionCustom {\n const value = collection.custom?.[nestedDocsPageTreePluginCustomKey]\n\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null\n }\n\n const config = value as Partial<NestedDocsPageTreePluginCollectionCustom>\n\n if (\n typeof config.breadcrumbsFieldSlug !== 'string' ||\n typeof config.defaultLimit !== 'number' ||\n typeof config.hideBreadcrumbs !== 'boolean' ||\n !config.homeIndicator ||\n typeof config.homeIndicator !== 'object' ||\n Array.isArray(config.homeIndicator) ||\n typeof config.homeIndicator.enabled !== 'boolean' ||\n typeof config.parentFieldSlug !== 'string'\n ) {\n return null\n }\n\n return {\n badges: normalizeNestedDocsPageTreePluginBadgeConfig(config.badges),\n badgesLinks: config.badgesLinks,\n breadcrumbsFieldSlug: config.breadcrumbsFieldSlug,\n defaultLimit: config.defaultLimit,\n hideBreadcrumbs: config.hideBreadcrumbs,\n homeIndicator: {\n enabled: config.homeIndicator.enabled,\n },\n parentFieldSlug: config.parentFieldSlug,\n }\n}\n"],"names":["nestedDocsPageTreePluginCustomKey","normalizeNestedDocsPageTreePluginBadgeConfig","getCollectionPageTreeConfig","collection","value","custom","Array","isArray","config","breadcrumbsFieldSlug","defaultLimit","hideBreadcrumbs","homeIndicator","enabled","parentFieldSlug","badges","badgesLinks"],"mappings":"AAGA,SAASA,iCAAiC,QAAQ,cAAa;AAC/D,SAASC,4CAA4C,QAAQ,mBAAkB;AAE/E,OAAO,SAASC,4BACdC,UAA4C;IAE5C,MAAMC,QAAQD,WAAWE,MAAM,EAAE,CAACL,kCAAkC;IAEpE,IAAI,CAACI,SAAS,OAAOA,UAAU,YAAYE,MAAMC,OAAO,CAACH,QAAQ;QAC/D,OAAO;IACT;IAEA,MAAMI,SAASJ;IAEf,IACE,OAAOI,OAAOC,oBAAoB,KAAK,YACvC,OAAOD,OAAOE,YAAY,KAAK,YAC/B,OAAOF,OAAOG,eAAe,KAAK,aAClC,CAACH,OAAOI,aAAa,IACrB,OAAOJ,OAAOI,aAAa,KAAK,YAChCN,MAAMC,OAAO,CAACC,OAAOI,aAAa,KAClC,OAAOJ,OAAOI,aAAa,CAACC,OAAO,KAAK,aACxC,OAAOL,OAAOM,eAAe,KAAK,UAClC;QACA,OAAO;IACT;IAEA,OAAO;QACLC,QAAQd,6CAA6CO,OAAOO,MAAM;QAClEC,aAAaR,OAAOQ,WAAW;QAC/BP,sBAAsBD,OAAOC,oBAAoB;QACjDC,cAAcF,OAAOE,YAAY;QACjCC,iBAAiBH,OAAOG,eAAe;QACvCC,eAAe;YACbC,SAASL,OAAOI,aAAa,CAACC,OAAO;QACvC;QACAC,iBAAiBN,OAAOM,eAAe;IACzC;AACF"}
|