@nitrogenbuilder/connector-payload 0.1.36 → 0.1.38

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.
@@ -65,10 +65,29 @@ export declare function buildMediaItemResponse(doc: MediaDoc): {
65
65
  medium?: import("../types").MediaSize;
66
66
  large?: import("../types").MediaSize;
67
67
  };
68
+ thumbnailURL: string;
68
69
  name: string;
69
70
  mime: string;
70
71
  ext: string;
71
72
  size: number;
73
+ post_date: string;
74
+ formats: {
75
+ thumbnail: {
76
+ url: string;
77
+ width: number;
78
+ height: number;
79
+ } | null;
80
+ medium: {
81
+ url: string;
82
+ width: number;
83
+ height: number;
84
+ } | null;
85
+ large: {
86
+ url: string;
87
+ width: number;
88
+ height: number;
89
+ } | null;
90
+ };
72
91
  };
73
92
  export declare function getNitrogenSettings(payload: Payload): Promise<NitrogenSettingsGlobal>;
74
93
  /**
@@ -96,6 +96,29 @@ export function buildListItemResponse(doc, settings, collectionSlug = 'pages') {
96
96
  export function buildMediaItemResponse(doc) {
97
97
  const filename = doc.filename || '';
98
98
  const ext = filename.includes('.') ? `.${filename.split('.').pop()}` : '';
99
+ const formats = {
100
+ thumbnail: doc.sizes?.thumbnail
101
+ ? {
102
+ url: doc.sizes.thumbnail.url || '',
103
+ width: doc.sizes.thumbnail.width || 0,
104
+ height: doc.sizes.thumbnail.height || 0,
105
+ }
106
+ : null,
107
+ medium: doc.sizes?.medium
108
+ ? {
109
+ url: doc.sizes.medium.url || '',
110
+ width: doc.sizes.medium.width || 0,
111
+ height: doc.sizes.medium.height || 0,
112
+ }
113
+ : null,
114
+ large: doc.sizes?.large
115
+ ? {
116
+ url: doc.sizes.large.url || '',
117
+ width: doc.sizes.large.width || 0,
118
+ height: doc.sizes.large.height || 0,
119
+ }
120
+ : null,
121
+ };
99
122
  return {
100
123
  // Payload-native fields (used by provider renderFiles/renderSelectedFile)
101
124
  id: doc.id,
@@ -108,13 +131,29 @@ export function buildMediaItemResponse(doc) {
108
131
  height: doc.height || 0,
109
132
  createdAt: doc.createdAt,
110
133
  sizes: doc.sizes || {},
134
+ thumbnailURL: formats.thumbnail?.url || doc.url || '',
111
135
  // CtrlFile-compatible aliases
112
136
  name: filename,
113
137
  mime: doc.mimeType || '',
114
138
  ext,
115
139
  size: doc.filesize ? Math.round((doc.filesize / 1024) * 10) / 10 : 0,
140
+ post_date: formatDateForWordPress(doc.createdAt),
141
+ formats,
116
142
  };
117
143
  }
144
+ function formatDateForWordPress(value) {
145
+ if (!value)
146
+ return '';
147
+ const date = new Date(value);
148
+ if (Number.isNaN(date.getTime()))
149
+ return value;
150
+ const pad = (part) => String(part).padStart(2, '0');
151
+ return [
152
+ date.getFullYear(),
153
+ pad(date.getMonth() + 1),
154
+ pad(date.getDate()),
155
+ ].join('-') + ` ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
156
+ }
118
157
  export async function getNitrogenSettings(payload) {
119
158
  return payload.findGlobal({ slug: 'nitrogen-settings' });
120
159
  }
@@ -1,4 +1,38 @@
1
1
  import { buildMediaItemResponse, requireAuth } from './helpers';
2
+ const MIME_TYPES_BY_EXTENSION = {
3
+ '.jpg': ['image/jpeg'],
4
+ '.jpeg': ['image/jpeg'],
5
+ '.png': ['image/png'],
6
+ '.gif': ['image/gif'],
7
+ '.svg': ['image/svg+xml'],
8
+ '.apng': ['image/apng'],
9
+ '.avif': ['image/avif'],
10
+ '.webp': ['image/webp'],
11
+ '.ico': ['image/x-icon', 'image/vnd.microsoft.icon'],
12
+ '.bmp': ['image/bmp'],
13
+ '.tiff': ['image/tiff'],
14
+ '.tif': ['image/tiff'],
15
+ '.mp4': ['video/mp4', 'audio/mp4'],
16
+ '.webm': ['video/webm', 'audio/webm'],
17
+ '.ogg': ['video/ogg', 'audio/ogg'],
18
+ '.ogv': ['video/ogg'],
19
+ '.mp3': ['audio/mpeg'],
20
+ '.wav': ['audio/wav', 'audio/x-wav'],
21
+ '.m4a': ['audio/mp4', 'audio/x-m4a'],
22
+ '.aac': ['audio/aac'],
23
+ '.oga': ['audio/ogg'],
24
+ '.flac': ['audio/flac'],
25
+ };
26
+ function normalizeExtension(value) {
27
+ const trimmed = value.trim().toLowerCase();
28
+ if (!trimmed)
29
+ return '';
30
+ return trimmed.startsWith('.') ? trimmed : `.${trimmed}`;
31
+ }
32
+ function parsePositiveInteger(value, fallback) {
33
+ const parsed = Number.parseInt(value || '', 10);
34
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
35
+ }
2
36
  export const mediaEndpoints = [
3
37
  // GET /api/nitrogen/v1/media — List media items
4
38
  {
@@ -9,33 +43,61 @@ export const mediaEndpoints = [
9
43
  const url = new URL(req.url || '', 'http://localhost');
10
44
  // Parse Payload-style query params: where[mimeType][in][0]=image/jpg
11
45
  const mimeTypes = [];
46
+ const extensions = [];
12
47
  for (const [key, value] of url.searchParams.entries()) {
13
48
  if (/^where\[mimeType\]\[in\]\[\d+\]$/.test(key)) {
14
49
  mimeTypes.push(value);
15
50
  }
51
+ if (key === 'filters[ext]' || /^filters\[ext\](\[(\d*)\])?$/.test(key)) {
52
+ const extension = normalizeExtension(value);
53
+ if (extension) {
54
+ extensions.push(extension);
55
+ mimeTypes.push(...(MIME_TYPES_BY_EXTENSION[extension] || []));
56
+ }
57
+ }
16
58
  }
17
- // Parse search: where[filename][contains]=search
18
- const search = url.searchParams.get('where[filename][contains]') || '';
19
- // Parse page number
20
- const page = parseInt(url.searchParams.get('page') || '1', 10);
21
- const where = {};
59
+ // Parse search from either Payload-style or WordPress-compatible params.
60
+ const search = url.searchParams.get('where[filename][contains]') ||
61
+ url.searchParams.get('filters[search]') ||
62
+ '';
63
+ const page = parsePositiveInteger(url.searchParams.get('page') || url.searchParams.get('paged'), 1);
64
+ const limit = Math.min(parsePositiveInteger(url.searchParams.get('limit') || url.searchParams.get('per_page'), 100), 100);
65
+ const and = [];
22
66
  if (mimeTypes.length > 0) {
23
- where.mimeType = { in: mimeTypes };
67
+ and.push({ mimeType: { in: Array.from(new Set(mimeTypes)) } });
68
+ }
69
+ else if (extensions.length > 0) {
70
+ and.push({
71
+ or: Array.from(new Set(extensions)).map((extension) => ({
72
+ filename: { contains: extension },
73
+ })),
74
+ });
24
75
  }
25
76
  if (search) {
26
- where.filename = { contains: search };
77
+ and.push({
78
+ or: [
79
+ { filename: { contains: search } },
80
+ { alt: { contains: search } },
81
+ ],
82
+ });
27
83
  }
84
+ const where = and.length > 1 ? { and } : and[0] || {};
28
85
  const result = await payload.find({
29
86
  collection: 'media',
30
87
  where,
31
88
  page,
32
- limit: 20,
89
+ limit,
33
90
  sort: '-createdAt',
34
91
  });
35
92
  const docs = result.docs.map((doc) => buildMediaItemResponse(doc));
36
93
  return Response.json({
37
94
  docs,
95
+ images: docs,
96
+ pages: result.totalPages,
38
97
  totalPages: result.totalPages,
98
+ totalDocs: result.totalDocs,
99
+ page: result.page,
100
+ limit: result.limit,
39
101
  });
40
102
  },
41
103
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nitrogenbuilder/connector-payload",
3
- "version": "0.1.36",
3
+ "version": "0.1.38",
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",
@@ -38,9 +38,9 @@
38
38
  "next": "^15.0.0 || ^16.0.0",
39
39
  "react": "^19.0.0",
40
40
  "@payloadcms/ui": "^3.0.0",
41
- "@nitrogenbuilder/client-react": ">=0.3.0",
42
- "@nitrogenbuilder/client-core": ">=0.3.0",
43
- "@nitrogenbuilder/types": ">=0.3.0"
41
+ "@nitrogenbuilder/client-react": ">=1.0.0",
42
+ "@nitrogenbuilder/client-core": ">=1.0.0",
43
+ "@nitrogenbuilder/types": ">=1.0.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@payloadcms/ui": "3.83.0",