@warleon/n8n-nodes-payload-cms 1.4.6 → 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");
@@ -441,7 +548,7 @@ class PayloadCms {
441
548
  let url = "";
442
549
  let method = "GET";
443
550
  let data = undefined;
444
- const params = {};
551
+ const params = additionalOptions.query ?? {};
445
552
  // Add query parameters
446
553
  if (additionalOptions.depth !== undefined)
447
554
  params.depth = additionalOptions.depth;
@@ -527,6 +634,12 @@ class PayloadCms {
527
634
  break;
528
635
  }
529
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
+ }
530
643
  let requestConfig = {};
531
644
  // handle binary inputs
532
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.6",
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",