@warleon/n8n-nodes-payload-cms 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.
@@ -1,19 +1,31 @@
1
1
  import { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription } from "n8n-workflow";
2
2
  import { AxiosRequestConfig } from "axios";
3
3
  import { SanitizedCollectionConfig, SanitizedGlobalConfig } from "./payload.types";
4
+ interface PayloadDiscoveryResponse {
5
+ collections: SanitizedCollectionConfig[];
6
+ globals: SanitizedGlobalConfig[];
7
+ endpoints: {
8
+ path: string;
9
+ method: "connect" | "delete" | "get" | "head" | "options" | "patch" | "post" | "put";
10
+ }[];
11
+ }
4
12
  export declare class PayloadCms implements INodeType {
5
13
  private static collectionsCache;
6
14
  private static globalsCache;
15
+ private static endpointsCache;
7
16
  description: INodeTypeDescription;
8
17
  methods: {
9
18
  loadOptions: {
10
19
  getCollections(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
11
20
  getGlobals(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
21
+ getEndpoints(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
12
22
  getPayloadFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
13
23
  };
14
24
  };
15
25
  discoverCollections(this: ILoadOptionsFunctions): Promise<SanitizedCollectionConfig[]>;
16
26
  discoverGlobals(this: ILoadOptionsFunctions): Promise<SanitizedGlobalConfig[]>;
27
+ discoverEndpoints(this: ILoadOptionsFunctions): Promise<PayloadDiscoveryResponse["endpoints"]>;
17
28
  makeAuthenticatedRequest(this: IExecuteFunctions | ILoadOptionsFunctions, config: AxiosRequestConfig): Promise<any>;
18
29
  execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
19
30
  }
31
+ export {};
@@ -45,6 +45,7 @@ const utils_1 = require("./utils");
45
45
  class PayloadCms {
46
46
  static collectionsCache = new Map();
47
47
  static globalsCache = new Map();
48
+ static endpointsCache = new Map();
48
49
  description = {
49
50
  displayName: "Payload CMS",
50
51
  name: "payloadCms",
@@ -81,6 +82,10 @@ class PayloadCms {
81
82
  name: "Global",
82
83
  value: "global",
83
84
  },
85
+ {
86
+ name: "Endpoint",
87
+ value: "endpoint",
88
+ },
84
89
  ],
85
90
  },
86
91
  // Collection operations
@@ -197,6 +202,58 @@ class PayloadCms {
197
202
  },
198
203
  ],
199
204
  },
205
+ // Endpoints operations
206
+ {
207
+ displayName: "Endpoint",
208
+ name: "endpoint",
209
+ type: "options",
210
+ typeOptions: {
211
+ loadOptionsMethod: "getEndpoints",
212
+ },
213
+ required: true,
214
+ default: "",
215
+ displayOptions: {
216
+ show: {
217
+ resource: ["endpoint"],
218
+ },
219
+ },
220
+ description: "Choose the endpoint to operate on",
221
+ },
222
+ {
223
+ displayName: "Operation",
224
+ name: "operation",
225
+ type: "options",
226
+ noDataExpression: true,
227
+ required: true,
228
+ default: "get",
229
+ displayOptions: {
230
+ show: {
231
+ resource: ["endpoint"],
232
+ },
233
+ },
234
+ options: [
235
+ {
236
+ name: "Get",
237
+ value: "get",
238
+ description: "Get request",
239
+ },
240
+ {
241
+ name: "Post",
242
+ value: "post",
243
+ description: "Post request",
244
+ },
245
+ {
246
+ name: "Put",
247
+ value: "put",
248
+ description: "Put request",
249
+ },
250
+ {
251
+ name: "Delete",
252
+ value: "delete",
253
+ description: "delete request",
254
+ },
255
+ ],
256
+ },
200
257
  // ID field for operations that need it
201
258
  {
202
259
  displayName: "Document ID",
@@ -241,6 +298,20 @@ class PayloadCms {
241
298
  },
242
299
  description: "The data to send (JSON format)",
243
300
  },
301
+ {
302
+ displayName: "Data",
303
+ name: "data",
304
+ type: "json",
305
+ required: true,
306
+ default: "{}",
307
+ displayOptions: {
308
+ show: {
309
+ resource: ["endpoint"],
310
+ operation: ["post", "put", "delete"],
311
+ },
312
+ },
313
+ description: "The data to send (JSON format)",
314
+ },
244
315
  // Query parameters
245
316
  {
246
317
  displayName: "Additional Options",
@@ -305,6 +376,13 @@ class PayloadCms {
305
376
  default: "data",
306
377
  description: "Name of the binary property that contains the file to upload",
307
378
  },
379
+ {
380
+ displayName: "Query Parameters",
381
+ name: "query",
382
+ type: "json",
383
+ default: "{}",
384
+ description: "Query parameters to add to the request url",
385
+ },
308
386
  ],
309
387
  },
310
388
  ],
@@ -337,6 +415,19 @@ class PayloadCms {
337
415
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to load globals: ${error instanceof Error ? error.message : "Unknown error"}`);
338
416
  }
339
417
  },
418
+ async getEndpoints() {
419
+ try {
420
+ const endpoints = await PayloadCms.prototype.discoverEndpoints.call(this);
421
+ PayloadCms.endpointsCache.set(this.getInstanceId(), endpoints);
422
+ return endpoints.map((endpoint) => ({
423
+ name: endpoint.path,
424
+ value: endpoint.path,
425
+ }));
426
+ }
427
+ catch (error) {
428
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to load endpoints: ${error instanceof Error ? error.message : "Unknown error"}`);
429
+ }
430
+ },
340
431
  async getPayloadFields() {
341
432
  const resource = this.getCurrentNodeParameter("resource");
342
433
  switch (resource) {
@@ -400,6 +491,22 @@ class PayloadCms {
400
491
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to load globals ensure that ${baseUrl}${reflectionEndpoint} exists. check https://github.com/warleon/n8n-payload-dynamic?tab=readme-ov-file#payload`);
401
492
  }
402
493
  }
494
+ async discoverEndpoints() {
495
+ const credentials = await this.getCredentials("payloadCmsApi");
496
+ const baseUrl = credentials.baseUrl;
497
+ const reflectionEndpoint = credentials.endpoint;
498
+ try {
499
+ // Try to get globals from a potential admin endpoint
500
+ const response = await PayloadCms.prototype.makeAuthenticatedRequest.call(this, {
501
+ method: "GET",
502
+ url: `${baseUrl}${reflectionEndpoint}`,
503
+ });
504
+ return response.data.endpoints;
505
+ }
506
+ catch (error) {
507
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to load endpoints ensure that ${baseUrl}${reflectionEndpoint} exists. check https://github.com/warleon/n8n-payload-dynamic?tab=readme-ov-file#payload`);
508
+ }
509
+ }
403
510
  // Helper method to make authenticated requests
404
511
  async makeAuthenticatedRequest(config) {
405
512
  const credentials = await this.getCredentials("payloadCmsApi");
@@ -416,6 +523,9 @@ class PayloadCms {
416
523
  config.validateStatus = (status) => {
417
524
  return status < 500;
418
525
  };
526
+ config.paramsSerializer = {
527
+ serialize: (params) => (0, qs_esm_1.stringify)(params, { arrayFormat: "brackets" }),
528
+ };
419
529
  return (0, axios_1.default)(config);
420
530
  }
421
531
  async execute() {
@@ -438,7 +548,7 @@ class PayloadCms {
438
548
  let url = "";
439
549
  let method = "GET";
440
550
  let data = undefined;
441
- const params = {};
551
+ const params = additionalOptions.query ?? {};
442
552
  // Add query parameters
443
553
  if (additionalOptions.depth !== undefined)
444
554
  params.depth = additionalOptions.depth;
@@ -453,7 +563,7 @@ class PayloadCms {
453
563
  const whereClause = typeof additionalOptions.where === "string"
454
564
  ? JSON.parse(additionalOptions.where)
455
565
  : additionalOptions.where;
456
- params.where = (0, qs_esm_1.stringify)(whereClause);
566
+ params.where = whereClause;
457
567
  }
458
568
  if (additionalOptions.select)
459
569
  params.select = additionalOptions.select;
@@ -524,6 +634,12 @@ class PayloadCms {
524
634
  break;
525
635
  }
526
636
  }
637
+ else if (resource === "endpoint") {
638
+ const endpoint = this.getNodeParameter("endpoint", i);
639
+ url = `${baseUrl}${apiPrefix}${endpoint}`;
640
+ method = operation.toUpperCase();
641
+ data = this.getNodeParameter("data", i);
642
+ }
527
643
  let requestConfig = {};
528
644
  // handle binary inputs
529
645
  const binaryPropertyName = additionalOptions.upload;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warleon/n8n-nodes-payload-cms",
3
- "version": "1.4.5",
3
+ "version": "1.5.0",
4
4
  "description": "Dynamic n8n node for Payload CMS that auto-discovers collections and operations forked and extended from https://github.com/leadership-institute/n8n-payload-dynamic",
5
5
  "main": "dist/index.js",
6
6
  "author": "warleon",