@nitrogenbuilder/connector-payload 0.1.25 → 0.1.26

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.
@@ -47,13 +47,6 @@ export const NitrogenTemplates = {
47
47
  position: 'sidebar',
48
48
  },
49
49
  },
50
- {
51
- name: 'templateType',
52
- type: 'text',
53
- admin: {
54
- description: 'Template type identifier for filtering',
55
- },
56
- },
57
50
  {
58
51
  name: 'associatedCollection',
59
52
  type: 'text',
@@ -62,18 +55,33 @@ export const NitrogenTemplates = {
62
55
  },
63
56
  },
64
57
  {
65
- name: 'nitrogenData',
66
- type: 'json',
67
- admin: {
68
- description: 'Nitrogen page builder JSON module tree',
69
- },
70
- },
71
- {
72
- name: 'templateSettings',
73
- type: 'json',
58
+ label: 'Nitrogen',
59
+ type: 'group',
74
60
  admin: {
75
- description: 'Template-level Nitrogen settings',
61
+ hideGutter: true,
76
62
  },
63
+ fields: [
64
+ {
65
+ name: 'nitrogenData',
66
+ type: 'json',
67
+ admin: {
68
+ description: 'Nitrogen page builder JSON module tree',
69
+ components: {
70
+ Field: '@nitrogenbuilder/connector-payload/components/NitrogenDataViewer',
71
+ },
72
+ },
73
+ },
74
+ {
75
+ name: 'templateSettings',
76
+ type: 'json',
77
+ admin: {
78
+ description: 'Template-level Nitrogen settings',
79
+ components: {
80
+ Field: '@nitrogenbuilder/connector-payload/components/NitrogenDataViewer',
81
+ },
82
+ },
83
+ },
84
+ ],
77
85
  },
78
86
  ],
79
87
  };
@@ -68,16 +68,19 @@ export const NitrogenEditButtonRuntime = ({ collection }) => {
68
68
  }, [collection]);
69
69
  if (!id || !token || !authorId)
70
70
  return null;
71
- const param = collection === 'nitrogen-templates' ? 'templateId' : 'pageId';
71
+ const param = collection === 'nitrogen-templates' ? 'id' : 'pageId';
72
72
  const editorBase = instanceUrl ?? '';
73
73
  const isDevelopmentMode = isLocalAdminHost();
74
74
  const editHref = `${editorBase}/nitrogen-editor?token=${encodeURIComponent(token)}&collection=${encodeURIComponent(collection)}&${param}=${id}&authorId=${encodeURIComponent(authorId)}${isDevelopmentMode ? '&development=true' : ''}`;
75
+ const viewHref = collection === 'nitrogen-templates'
76
+ ? `${frontendUrl}/nitrogen-templates/${slug}`
77
+ : `${frontendUrl}/${slug}`;
75
78
  const editButtonVars = isDevelopmentMode
76
79
  ? nitrogenEditDevButtonVars
77
80
  : nitrogenEditLiveButtonVars;
78
- return (_jsxs("div", { style: nitrogenButtonGroupStyle, children: [slug && frontendUrl && (_jsx(Button, { buttonStyle: "primary", el: "anchor", margin: false, newTab: true, url: `${frontendUrl}/${slug}`, extraButtonProps: {
81
+ return (_jsxs("div", { style: nitrogenButtonGroupStyle, children: [slug && frontendUrl && (_jsx(Button, { buttonStyle: "primary", el: "anchor", margin: false, newTab: true, url: viewHref, extraButtonProps: {
79
82
  style: nitrogenViewButtonVars,
80
- }, children: "View Page" })), _jsx(Button, { buttonStyle: "primary", el: "anchor", margin: false, newTab: true, url: editHref, extraButtonProps: {
83
+ }, children: collection === 'nitrogen-templates' ? 'View Template' : 'View Page' })), _jsx(Button, { buttonStyle: "primary", el: "anchor", margin: false, newTab: true, url: editHref, extraButtonProps: {
81
84
  style: editButtonVars,
82
85
  }, children: "Edit with Nitrogen" })] }));
83
86
  };
@@ -24,22 +24,22 @@ export const nitrogenButtonGroupStyle = {
24
24
  alignItems: "center",
25
25
  };
26
26
  export const nitrogenViewButtonVars = createFilledButtonVars({
27
- background: monogenPalette.hasVal,
28
- hoverBackground: "#5F97CF",
27
+ background: monogenPalette.inheritVal,
28
+ hoverBackground: "#CC7B2B",
29
29
  text: monogenPalette.gray900,
30
30
  border: "rgba(22, 25, 29, 0.12)",
31
31
  });
32
32
  export const nitrogenEditLiveButtonVars = createFilledButtonVars({
33
- background: monogenPalette.inheritVal,
34
- hoverBackground: "#CC7B2B",
33
+ background: monogenPalette.hasVal,
34
+ hoverBackground: "#5F97CF",
35
35
  text: monogenPalette.gray900,
36
36
  border: "rgba(22, 25, 29, 0.12)",
37
37
  });
38
38
  export const nitrogenEditDevButtonVars = createFilledButtonVars({
39
- background: monogenPalette.gray700,
40
- hoverBackground: monogenPalette.gray600,
41
- text: monogenPalette.gray200,
42
- border: "rgba(226, 229, 233, 0.08)",
39
+ background: monogenPalette.hasVal,
40
+ hoverBackground: "#5F97CF",
41
+ text: monogenPalette.gray900,
42
+ border: "rgba(22, 25, 29, 0.12)",
43
43
  });
44
44
  export const nitrogenSecondaryButtonVars = {
45
45
  "--color": monogenPalette.gray400,
@@ -1,5 +1,6 @@
1
1
  import type { SanitizedConfig } from "payload";
2
2
  interface NitrogenEditorSearchParams {
3
+ id?: string;
3
4
  pageId?: string;
4
5
  templateId?: string;
5
6
  collection?: string;
@@ -14,7 +15,7 @@ interface NitrogenEditorSearchParams {
14
15
  * import configPromise from '@payload-config'
15
16
  * export default createNitrogenEditorPage(configPromise)
16
17
  *
17
- * Accessible at `/nitrogen-editor?pageId=xxx` or `/nitrogen-editor?templateId=xxx`.
18
+ * Accessible at `/nitrogen-editor?pageId=xxx` or `/nitrogen-editor?id=xxx&collection=nitrogen-templates`.
18
19
  */
19
20
  export declare function createNitrogenEditorPage(config: Promise<SanitizedConfig>): ({ searchParams, }: {
20
21
  searchParams: Promise<NitrogenEditorSearchParams>;
@@ -26,6 +26,26 @@ function getSiteUrl(settings, isDevelopment) {
26
26
  const fallbackUrl = isDevelopment
27
27
  ? settings.frontendUrl
28
28
  : settings.developmentUrl;
29
+ const normalizeOrigin = (value) => {
30
+ if (!value)
31
+ return "";
32
+ try {
33
+ return new URL(value).origin;
34
+ }
35
+ catch {
36
+ return "";
37
+ }
38
+ };
39
+ const preferredOrigin = normalizeOrigin(preferredUrl);
40
+ const fallbackOrigin = normalizeOrigin(fallbackUrl);
41
+ const instanceOrigin = normalizeOrigin(settings.instanceUrl);
42
+ if (preferredUrl &&
43
+ instanceOrigin &&
44
+ preferredOrigin === instanceOrigin &&
45
+ fallbackUrl &&
46
+ fallbackOrigin !== instanceOrigin) {
47
+ return fallbackUrl;
48
+ }
29
49
  return preferredUrl || fallbackUrl || "";
30
50
  }
31
51
  /**
@@ -37,7 +57,7 @@ function getSiteUrl(settings, isDevelopment) {
37
57
  * import configPromise from '@payload-config'
38
58
  * export default createNitrogenEditorPage(configPromise)
39
59
  *
40
- * Accessible at `/nitrogen-editor?pageId=xxx` or `/nitrogen-editor?templateId=xxx`.
60
+ * Accessible at `/nitrogen-editor?pageId=xxx` or `/nitrogen-editor?id=xxx&collection=nitrogen-templates`.
41
61
  */
42
62
  export function createNitrogenEditorPage(config) {
43
63
  return async function NitrogenEditorPage({ searchParams, }) {
@@ -61,7 +81,7 @@ export function createNitrogenEditorPage(config) {
61
81
  if (params.collection) {
62
82
  postType = params.collection;
63
83
  }
64
- else if (params.templateId) {
84
+ else if (params.id || params.templateId) {
65
85
  postType = "nitrogen-templates";
66
86
  }
67
87
  else {
@@ -80,7 +100,7 @@ export function createNitrogenEditorPage(config) {
80
100
  wysiwygColors: nitrogenConfig.wysiwygColors || {},
81
101
  cssInjection: nitrogenConfig.cssInjection || "",
82
102
  };
83
- const editId = params.templateId || params.pageId || "";
103
+ const editId = params.id || params.templateId || params.pageId || "";
84
104
  const isEditorDev = isDevelopment && !!settings.instanceUrl;
85
105
  const editorOrigin = settings.instanceUrl?.replace(/\/$/, "") || "";
86
106
  const editorAssetsBase = isEditorDev
@@ -4,11 +4,22 @@ export function formatDate(date) {
4
4
  return `${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())} ${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())}`;
5
5
  }
6
6
  export function buildDynamicData(doc, globalSettings) {
7
+ const rawDoc = doc;
8
+ const docData = Object.fromEntries(Object.entries(rawDoc).filter(([key]) => key !== 'nitrogenData' &&
9
+ key !== 'pageSettings' &&
10
+ key !== 'templateSettings'));
11
+ const rawContent = typeof rawDoc.content === 'string'
12
+ ? rawDoc.content
13
+ : '';
14
+ const rawExcerpt = typeof rawDoc.excerpt === 'string'
15
+ ? rawDoc.excerpt
16
+ : '';
7
17
  const dynamicData = {
8
18
  Post: {
19
+ ...docData,
9
20
  post_title: doc.title || '',
10
- post_content: '',
11
- post_excerpt: '',
21
+ post_content: rawContent,
22
+ post_excerpt: rawExcerpt,
12
23
  post_date: formatDate(doc.createdAt),
13
24
  post_date_gmt: formatDate(doc.createdAt),
14
25
  post_modified: formatDate(doc.updatedAt),
@@ -112,9 +123,13 @@ export async function getTemplateForType(payload, type) {
112
123
  try {
113
124
  const result = await payload.find({
114
125
  collection: 'nitrogen-templates',
115
- where: { associatedCollection: { equals: type } },
126
+ where: {
127
+ associatedCollection: { equals: type },
128
+ status: { equals: 'published' },
129
+ },
116
130
  limit: 1,
117
131
  depth: 0,
132
+ sort: '-updatedAt',
118
133
  });
119
134
  const doc = result.docs[0];
120
135
  if (!doc)
@@ -1,5 +1,58 @@
1
1
  import { getNitrogenSettings, buildDynamicData, buildPageResponse, buildListItemResponse, requireAuth, } from './helpers';
2
2
  export const templatesEndpoints = [
3
+ // GET /api/nitrogen/v1/nitrogen-templates/slug/:slug — Get a single template by slug
4
+ {
5
+ path: '/nitrogen/v1/nitrogen-templates/slug/:slug',
6
+ method: 'get',
7
+ handler: async (req) => {
8
+ const { payload, routeParams } = req;
9
+ const slug = routeParams?.slug;
10
+ try {
11
+ const result = await payload.find({
12
+ collection: 'nitrogen-templates',
13
+ where: { slug: { equals: slug } },
14
+ limit: 1,
15
+ depth: 1,
16
+ });
17
+ const doc = result.docs[0];
18
+ if (!doc) {
19
+ return Response.json({ error: 'Not found' }, { status: 404 });
20
+ }
21
+ const settings = await getNitrogenSettings(payload);
22
+ let dynamicData = buildDynamicData(doc, settings);
23
+ const associatedCollection = doc.associatedCollection;
24
+ if (associatedCollection &&
25
+ associatedCollection !== 'header' &&
26
+ associatedCollection !== 'footer') {
27
+ try {
28
+ const associated = await payload.find({
29
+ collection: associatedCollection,
30
+ limit: 1,
31
+ depth: 1,
32
+ });
33
+ if (associated.docs.length) {
34
+ dynamicData = buildDynamicData(associated.docs[0], settings);
35
+ }
36
+ }
37
+ catch {
38
+ // Collection may not exist — use template's own data
39
+ }
40
+ }
41
+ const response = buildPageResponse(doc, settings, dynamicData);
42
+ const relativePermalink = `/nitrogen-templates/${doc.slug}`;
43
+ const frontendBase = (settings.frontendUrl || '').replace(/\/$/, '');
44
+ return Response.json({
45
+ ...response,
46
+ permalink: frontendBase ? `${frontendBase}${relativePermalink}` : relativePermalink,
47
+ relative_permalink: relativePermalink,
48
+ postType: associatedCollection || '',
49
+ });
50
+ }
51
+ catch {
52
+ return Response.json({ error: 'Not found' }, { status: 404 });
53
+ }
54
+ },
55
+ },
3
56
  // GET /api/nitrogen/v1/templates — List templates
4
57
  {
5
58
  path: '/nitrogen/v1/nitrogen-templates',
@@ -23,6 +76,8 @@ export const templatesEndpoints = [
23
76
  });
24
77
  const items = result.docs.map((doc) => ({
25
78
  ...buildListItemResponse(doc, settings),
79
+ permalink: `${(settings.frontendUrl || '').replace(/\/$/, '')}/nitrogen-templates/${doc.slug}`,
80
+ relative_permalink: `/nitrogen-templates/${doc.slug}`,
26
81
  postType: doc.associatedCollection || '',
27
82
  }));
28
83
  return Response.json(items);
@@ -64,8 +119,12 @@ export const templatesEndpoints = [
64
119
  }
65
120
  }
66
121
  const response = buildPageResponse(doc, settings, dynamicData);
122
+ const relativePermalink = `/nitrogen-templates/${doc.slug}`;
123
+ const frontendBase = (settings.frontendUrl || '').replace(/\/$/, '');
67
124
  return Response.json({
68
125
  ...response,
126
+ permalink: frontendBase ? `${frontendBase}${relativePermalink}` : relativePermalink,
127
+ relative_permalink: relativePermalink,
69
128
  postType: associatedCollection || '',
70
129
  });
71
130
  }
@@ -85,7 +144,7 @@ export const templatesEndpoints = [
85
144
  const { payload, routeParams } = req;
86
145
  const id = routeParams?.id;
87
146
  const body = (await req.json?.());
88
- const data = body?.data || body;
147
+ const data = (body?.data && typeof body.data === 'object') ? body.data : body;
89
148
  if (!data?.title) {
90
149
  return Response.json({ error: 'Title is required' }, { status: 400 });
91
150
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nitrogenbuilder/connector-payload",
3
- "version": "0.1.25",
3
+ "version": "0.1.26",
4
4
  "description": "Nitrogen page builder connector plugin for Payload CMS 3.x",
5
5
  "author": "Leonardo Dentzien <leo@torchmedia.ca>",
6
6
  "type": "module",