@warleon/n8n-nodes-payload-cms 1.4.1 → 1.4.3
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/dist/nodes/PayloadCms/PayloadCms.node.d.ts +3 -1
- package/dist/nodes/PayloadCms/PayloadCms.node.js +40 -6
- package/dist/nodes/PayloadCms/payload.types.d.ts +71 -6
- package/dist/nodes/PayloadCms/utils.d.ts +3 -0
- package/dist/nodes/PayloadCms/utils.js +37 -0
- package/dist/nodes/PayloadCms/utls.d.ts +2 -0
- package/dist/nodes/PayloadCms/utls.js +71 -0
- package/package.json +3 -2
|
@@ -2,12 +2,14 @@ import { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodeProp
|
|
|
2
2
|
import { AxiosRequestConfig } from "axios";
|
|
3
3
|
import { SanitizedCollectionConfig, SanitizedGlobalConfig } from "./payload.types";
|
|
4
4
|
export declare class PayloadCms implements INodeType {
|
|
5
|
-
private static
|
|
5
|
+
private static collectionsCache;
|
|
6
|
+
private static globalsCache;
|
|
6
7
|
description: INodeTypeDescription;
|
|
7
8
|
methods: {
|
|
8
9
|
loadOptions: {
|
|
9
10
|
getCollections(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
10
11
|
getGlobals(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
12
|
+
getPayloadFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
|
|
11
13
|
};
|
|
12
14
|
};
|
|
13
15
|
discoverCollections(this: ILoadOptionsFunctions): Promise<SanitizedCollectionConfig[]>;
|
|
@@ -40,9 +40,11 @@ exports.PayloadCms = void 0;
|
|
|
40
40
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
41
41
|
const axios_1 = __importStar(require("axios"));
|
|
42
42
|
const form_data_1 = __importDefault(require("form-data"));
|
|
43
|
+
const qs_esm_1 = require("qs-esm");
|
|
44
|
+
const utils_1 = require("./utils");
|
|
43
45
|
class PayloadCms {
|
|
44
|
-
|
|
45
|
-
static
|
|
46
|
+
static collectionsCache = new Map();
|
|
47
|
+
static globalsCache = new Map();
|
|
46
48
|
description = {
|
|
47
49
|
displayName: "Payload CMS",
|
|
48
50
|
name: "payloadCms",
|
|
@@ -214,9 +216,12 @@ class PayloadCms {
|
|
|
214
216
|
{
|
|
215
217
|
displayName: "Data",
|
|
216
218
|
name: "data",
|
|
217
|
-
type: "
|
|
219
|
+
type: "multiOptions",
|
|
218
220
|
required: true,
|
|
219
|
-
default: "
|
|
221
|
+
default: "",
|
|
222
|
+
typeOptions: {
|
|
223
|
+
loadOptionsMethod: "getPayloadFields",
|
|
224
|
+
},
|
|
220
225
|
displayOptions: {
|
|
221
226
|
show: {
|
|
222
227
|
resource: ["collection"],
|
|
@@ -312,6 +317,7 @@ class PayloadCms {
|
|
|
312
317
|
async getCollections() {
|
|
313
318
|
try {
|
|
314
319
|
const collections = await PayloadCms.prototype.discoverCollections.call(this);
|
|
320
|
+
PayloadCms.collectionsCache.set(this.getInstanceId(), collections);
|
|
315
321
|
return collections.map((collection) => ({
|
|
316
322
|
name: collection.labels?.plural || collection.slug,
|
|
317
323
|
value: collection.slug,
|
|
@@ -324,6 +330,7 @@ class PayloadCms {
|
|
|
324
330
|
async getGlobals() {
|
|
325
331
|
try {
|
|
326
332
|
const globals = await PayloadCms.prototype.discoverGlobals.call(this);
|
|
333
|
+
PayloadCms.globalsCache.set(this.getInstanceId(), globals);
|
|
327
334
|
return globals.map((global) => ({
|
|
328
335
|
name: global.label || global.slug,
|
|
329
336
|
value: global.slug,
|
|
@@ -333,6 +340,33 @@ class PayloadCms {
|
|
|
333
340
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to load globals: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
334
341
|
}
|
|
335
342
|
},
|
|
343
|
+
async getPayloadFields() {
|
|
344
|
+
const resource = this.getCurrentNodeParameter("resource");
|
|
345
|
+
switch (resource) {
|
|
346
|
+
case "collection":
|
|
347
|
+
const collectionSlug = this.getCurrentNodeParameter("collection");
|
|
348
|
+
const collection = PayloadCms.collectionsCache
|
|
349
|
+
.get(this.getInstanceId())
|
|
350
|
+
?.find((c) => c.slug === collectionSlug);
|
|
351
|
+
if (!collection) {
|
|
352
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to load fields for collection ${collectionSlug}: collection not found`);
|
|
353
|
+
}
|
|
354
|
+
return collection.fields.flatMap((f) => (0, utils_1.payloadField2N8nOption)(f));
|
|
355
|
+
break;
|
|
356
|
+
case "global":
|
|
357
|
+
const globalSlug = this.getCurrentNodeParameter("collection");
|
|
358
|
+
const global = PayloadCms.globalsCache
|
|
359
|
+
.get(this.getInstanceId())
|
|
360
|
+
?.find((g) => g.slug === globalSlug);
|
|
361
|
+
if (!global) {
|
|
362
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to load fields for global ${globalSlug}: global not found`);
|
|
363
|
+
}
|
|
364
|
+
return global.fields.flatMap((f) => (0, utils_1.payloadField2N8nOption)(f));
|
|
365
|
+
break;
|
|
366
|
+
default:
|
|
367
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed to load fields for resource ${resource}: resource not supported`);
|
|
368
|
+
}
|
|
369
|
+
},
|
|
336
370
|
},
|
|
337
371
|
};
|
|
338
372
|
async discoverCollections() {
|
|
@@ -422,7 +456,7 @@ class PayloadCms {
|
|
|
422
456
|
const whereClause = typeof additionalOptions.where === "string"
|
|
423
457
|
? JSON.parse(additionalOptions.where)
|
|
424
458
|
: additionalOptions.where;
|
|
425
|
-
params.where =
|
|
459
|
+
params.where = (0, qs_esm_1.stringify)(whereClause);
|
|
426
460
|
}
|
|
427
461
|
if (additionalOptions.select)
|
|
428
462
|
params.select = additionalOptions.select;
|
|
@@ -512,7 +546,7 @@ class PayloadCms {
|
|
|
512
546
|
else {
|
|
513
547
|
data = {};
|
|
514
548
|
}
|
|
515
|
-
const sanitizeData = { ...
|
|
549
|
+
const sanitizeData = { ...metadata, ...data };
|
|
516
550
|
formData.append("_payload", JSON.stringify(sanitizeData));
|
|
517
551
|
requestConfig = {
|
|
518
552
|
method: method,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { DeepRequired } from "ts-essentials";
|
|
2
|
-
export interface SanitizedGlobalConfig extends
|
|
3
|
-
fields:
|
|
2
|
+
export interface SanitizedGlobalConfig extends GlobalConfig {
|
|
3
|
+
fields: PayloadField[];
|
|
4
4
|
slug: GlobalSlug;
|
|
5
5
|
}
|
|
6
6
|
export interface SanitizedCollectionConfig extends DeepRequired<CollectionConfig> {
|
|
7
7
|
auth: Auth;
|
|
8
|
-
fields:
|
|
8
|
+
fields: PayloadField[];
|
|
9
9
|
slug: CollectionSlug;
|
|
10
10
|
}
|
|
11
11
|
export type CollectionConfig<TSlug extends object = any> = {
|
|
@@ -118,11 +118,76 @@ export interface IncomingAuthType {
|
|
|
118
118
|
*/
|
|
119
119
|
useSessions?: boolean;
|
|
120
120
|
}
|
|
121
|
-
export type Field = any;
|
|
122
121
|
export type CollectionSlug = string;
|
|
123
122
|
export type GlobalSlug = string;
|
|
124
|
-
export type GlobalConfig
|
|
123
|
+
export type GlobalConfig = {
|
|
125
124
|
custom?: Record<string, any>;
|
|
126
|
-
fields:
|
|
125
|
+
fields: PayloadField[];
|
|
127
126
|
label?: StaticLabel;
|
|
128
127
|
};
|
|
128
|
+
export declare const validOperators: readonly [
|
|
129
|
+
"equals",
|
|
130
|
+
"contains",
|
|
131
|
+
"not_equals",
|
|
132
|
+
"in",
|
|
133
|
+
"all",
|
|
134
|
+
"not_in",
|
|
135
|
+
"exists",
|
|
136
|
+
"greater_than",
|
|
137
|
+
"greater_than_equal",
|
|
138
|
+
"less_than",
|
|
139
|
+
"less_than_equal",
|
|
140
|
+
"like",
|
|
141
|
+
"not_like",
|
|
142
|
+
"within",
|
|
143
|
+
"intersects",
|
|
144
|
+
"near"
|
|
145
|
+
];
|
|
146
|
+
export type Operator = (typeof validOperators)[number];
|
|
147
|
+
export type JsonValue = JsonArray | JsonObject | unknown;
|
|
148
|
+
export type JsonArray = Array<JsonValue>;
|
|
149
|
+
export interface JsonObject {
|
|
150
|
+
[key: string]: any;
|
|
151
|
+
}
|
|
152
|
+
export type WhereField = {
|
|
153
|
+
[key in Operator]?: JsonValue;
|
|
154
|
+
};
|
|
155
|
+
export type Where = {
|
|
156
|
+
and?: Where[];
|
|
157
|
+
or?: Where[];
|
|
158
|
+
[key: string]: Where[] | WhereField | undefined;
|
|
159
|
+
};
|
|
160
|
+
export type PayloadFieldType = "array" | "blocks" | "checkbox" | "code" | "collapsible" | "date" | "email" | "group" | "join" | "json" | "number" | "point" | "radio" | "relationship" | "richText" | "row" | "select" | "tabs" | "text" | "textarea" | "ui" | "upload";
|
|
161
|
+
export interface PayloadAdminConfig {
|
|
162
|
+
disableBulkEdit?: boolean;
|
|
163
|
+
hidden?: boolean;
|
|
164
|
+
disabled?: boolean;
|
|
165
|
+
components?: {
|
|
166
|
+
Field?: boolean;
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
export interface PayloadHooksConfig {
|
|
170
|
+
beforeValidate?: (null | unknown)[];
|
|
171
|
+
beforeChange?: (null | unknown)[];
|
|
172
|
+
afterRead?: (null | unknown)[];
|
|
173
|
+
}
|
|
174
|
+
export interface PayloadAccessConfig {
|
|
175
|
+
[key: string]: unknown;
|
|
176
|
+
}
|
|
177
|
+
export interface PayloadField {
|
|
178
|
+
name: string;
|
|
179
|
+
type: PayloadFieldType;
|
|
180
|
+
required?: boolean;
|
|
181
|
+
unique?: boolean;
|
|
182
|
+
hidden?: boolean;
|
|
183
|
+
index?: boolean;
|
|
184
|
+
defaultValue?: unknown;
|
|
185
|
+
access?: PayloadAccessConfig;
|
|
186
|
+
admin?: PayloadAdminConfig;
|
|
187
|
+
hooks?: PayloadHooksConfig;
|
|
188
|
+
fields?: PayloadField[];
|
|
189
|
+
options?: Array<string | {
|
|
190
|
+
label: string;
|
|
191
|
+
value: string | number;
|
|
192
|
+
}>;
|
|
193
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.payloadField2N8nOption = payloadField2N8nOption;
|
|
4
|
+
function payloadField2N8nOption(field, parentName = "") {
|
|
5
|
+
const prefix = parentName ? `${parentName}.` : "";
|
|
6
|
+
switch (field.type) {
|
|
7
|
+
case "select":
|
|
8
|
+
case "radio":
|
|
9
|
+
return (field.options?.map((opt) => ({
|
|
10
|
+
name: `${prefix}${field.name}: ${typeof opt === "string" ? opt : opt.label ?? String(opt.value)}`,
|
|
11
|
+
value: typeof opt === "string" ? opt : opt.value,
|
|
12
|
+
})) || []);
|
|
13
|
+
case "checkbox":
|
|
14
|
+
return [
|
|
15
|
+
{ name: `${prefix}${field.name}: True`, value: true },
|
|
16
|
+
{ name: `${prefix}${field.name}: False`, value: false },
|
|
17
|
+
];
|
|
18
|
+
case "point":
|
|
19
|
+
return [
|
|
20
|
+
{ name: `${prefix}${field.name}.lat`, value: "lat" },
|
|
21
|
+
{ name: `${prefix}${field.name}.lng`, value: "lng" },
|
|
22
|
+
];
|
|
23
|
+
case "array":
|
|
24
|
+
case "group":
|
|
25
|
+
case "row":
|
|
26
|
+
case "tabs":
|
|
27
|
+
case "blocks":
|
|
28
|
+
return (field.fields || []).flatMap((subField) => payloadField2N8nOption(subField, `${prefix}${field.name}`));
|
|
29
|
+
default:
|
|
30
|
+
return [
|
|
31
|
+
{
|
|
32
|
+
name: `${prefix}${field.name}`,
|
|
33
|
+
value: field.name,
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertPayloadSchemaToN8n = void 0;
|
|
4
|
+
function mapPayloadFieldToN8n(field) {
|
|
5
|
+
const base = {
|
|
6
|
+
displayName: field.name,
|
|
7
|
+
name: field.name,
|
|
8
|
+
required: field.required || false,
|
|
9
|
+
default: field.defaultValue ?? "",
|
|
10
|
+
};
|
|
11
|
+
switch (field.type) {
|
|
12
|
+
case "text":
|
|
13
|
+
case "email":
|
|
14
|
+
return { ...base, type: "string" };
|
|
15
|
+
case "textarea":
|
|
16
|
+
case "code":
|
|
17
|
+
case "json":
|
|
18
|
+
case "richText":
|
|
19
|
+
return { ...base, type: "string", typeOptions: { rows: 5 } };
|
|
20
|
+
case "number":
|
|
21
|
+
return { ...base, type: "number" };
|
|
22
|
+
case "checkbox":
|
|
23
|
+
return { ...base, type: "boolean" };
|
|
24
|
+
case "date":
|
|
25
|
+
return { ...base, type: "dateTime" };
|
|
26
|
+
case "select":
|
|
27
|
+
case "radio":
|
|
28
|
+
return {
|
|
29
|
+
...base,
|
|
30
|
+
type: "options",
|
|
31
|
+
options: field.options?.map((opt) => ({
|
|
32
|
+
name: opt.label ?? opt,
|
|
33
|
+
value: opt.value ?? opt,
|
|
34
|
+
})) || [],
|
|
35
|
+
};
|
|
36
|
+
case "relationship":
|
|
37
|
+
case "upload":
|
|
38
|
+
return { ...base, type: "string" };
|
|
39
|
+
case "point":
|
|
40
|
+
return {
|
|
41
|
+
...base,
|
|
42
|
+
type: "fixedCollection",
|
|
43
|
+
options: [
|
|
44
|
+
{
|
|
45
|
+
name: "point",
|
|
46
|
+
displayName: "Point",
|
|
47
|
+
values: [
|
|
48
|
+
{ displayName: "Latitude", name: "lat", type: "number" },
|
|
49
|
+
{ displayName: "Longitude", name: "lng", type: "number" },
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
case "array":
|
|
55
|
+
case "group":
|
|
56
|
+
case "row":
|
|
57
|
+
case "tabs":
|
|
58
|
+
case "blocks":
|
|
59
|
+
return {
|
|
60
|
+
...base,
|
|
61
|
+
type: "collection",
|
|
62
|
+
options: (field.fields || []).map(mapPayloadFieldToN8n),
|
|
63
|
+
};
|
|
64
|
+
default:
|
|
65
|
+
return { ...base, type: "string" };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function convertPayloadSchemaToN8n(schema) {
|
|
69
|
+
return schema.map(mapPayloadFieldToN8n);
|
|
70
|
+
}
|
|
71
|
+
exports.convertPayloadSchemaToN8n = convertPayloadSchemaToN8n;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@warleon/n8n-nodes-payload-cms",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
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",
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"typescript": "^5.0.0"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"axios": "^1.10.0"
|
|
62
|
+
"axios": "^1.10.0",
|
|
63
|
+
"qs-esm": "^7.0.2"
|
|
63
64
|
}
|
|
64
65
|
}
|