@learningsuite/n8n-nodes-learningsuite 1.2.6 → 1.3.4
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/README.md +41 -12
- package/dist/nodes/LearningSuite/LearningSuite.node.d.ts +7 -1
- package/dist/nodes/LearningSuite/LearningSuite.node.js +2 -0
- package/dist/nodes/LearningSuite/LearningSuiteTrigger.node.d.ts +7 -1
- package/dist/nodes/LearningSuite/LearningSuiteTrigger.node.js +14 -0
- package/dist/nodes/LearningSuite/descriptions/ai.properties.js +86 -0
- package/dist/nodes/LearningSuite/descriptions/customFields.properties.js +138 -17
- package/dist/nodes/LearningSuite/descriptions/trigger.instant.properties.js +32 -0
- package/dist/nodes/LearningSuite/descriptions/webhook.properties.js +35 -0
- package/dist/nodes/LearningSuite/descriptions/webhook.sampleData.properties.js +26 -0
- package/dist/nodes/LearningSuite/execute/ai.handlers.d.ts +3 -0
- package/dist/nodes/LearningSuite/execute/ai.handlers.js +44 -0
- package/dist/nodes/LearningSuite/execute/customFields.handlers.d.ts +1 -0
- package/dist/nodes/LearningSuite/execute/customFields.handlers.js +273 -22
- package/dist/nodes/LearningSuite/execute/webhook.handlers.js +16 -0
- package/dist/nodes/LearningSuite/methods/loadOptions/ai.loadOptions.d.ts +3 -0
- package/dist/nodes/LearningSuite/methods/loadOptions/ai.loadOptions.js +11 -0
- package/dist/nodes/LearningSuite/methods/loadOptions/common.d.ts +1 -0
- package/dist/nodes/LearningSuite/methods/loadOptions/common.js +5 -0
- package/dist/nodes/LearningSuite/methods/loadOptions/customFields.loadOptions.d.ts +8 -4
- package/dist/nodes/LearningSuite/methods/loadOptions/customFields.loadOptions.js +76 -3
- package/dist/nodes/LearningSuite/shared/customFields.helpers.js +1 -4
- package/dist/nodes/LearningSuite/shared/customFields.shared.d.ts +1 -0
- package/dist/nodes/LearningSuite/shared/customFields.upload.d.ts +1 -1
- package/dist/nodes/LearningSuite/shared/customFields.upload.js +11 -10
- package/dist/nodes/LearningSuite/shared/request.d.ts +3 -0
- package/dist/nodes/LearningSuite/shared/request.js +18 -0
- package/package.json +1 -1
|
@@ -2,23 +2,96 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.customFields_getCards = customFields_getCards;
|
|
4
4
|
exports.customFields_getDefinitions = customFields_getDefinitions;
|
|
5
|
+
exports.customFields_getMediaDefinitions = customFields_getMediaDefinitions;
|
|
5
6
|
exports.customFields_getCategories = customFields_getCategories;
|
|
6
7
|
exports.customFields_getFieldType = customFields_getFieldType;
|
|
7
8
|
exports.customFields_getFieldOptions = customFields_getFieldOptions;
|
|
8
9
|
const common_1 = require("./common");
|
|
10
|
+
const shared_1 = require("../../shared");
|
|
9
11
|
const customFields_helpers_1 = require("../../shared/customFields.helpers");
|
|
12
|
+
const MEDIA_FIELD_TYPES = new Set(['files', 'images', 'videos', 'audios']);
|
|
13
|
+
function getMediaFieldMaxInfo(fieldType, typeDefinition) {
|
|
14
|
+
const maxByType = {
|
|
15
|
+
files: typeDefinition === null || typeDefinition === void 0 ? void 0 : typeDefinition.maxFiles,
|
|
16
|
+
images: typeDefinition === null || typeDefinition === void 0 ? void 0 : typeDefinition.maxImages,
|
|
17
|
+
videos: typeDefinition === null || typeDefinition === void 0 ? void 0 : typeDefinition.maxVideos,
|
|
18
|
+
audios: typeDefinition === null || typeDefinition === void 0 ? void 0 : typeDefinition.maxAudios,
|
|
19
|
+
};
|
|
20
|
+
const max = maxByType[fieldType];
|
|
21
|
+
if (typeof max === 'number' && Number.isFinite(max)) {
|
|
22
|
+
return `max. ${max}`;
|
|
23
|
+
}
|
|
24
|
+
if (typeof max === 'string' && max.trim() !== '') {
|
|
25
|
+
return `max. ${max.trim()}`;
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
function getMediaFieldDetails(fieldType, typeDefinition, cardName) {
|
|
30
|
+
const typeLabel = fieldType.charAt(0).toUpperCase() + fieldType.slice(1);
|
|
31
|
+
return [typeLabel, getMediaFieldMaxInfo(fieldType, typeDefinition), cardName].filter(Boolean).join(', ');
|
|
32
|
+
}
|
|
10
33
|
async function customFields_getCards() {
|
|
11
|
-
return common_1.
|
|
34
|
+
return common_1.fetchOptionsAll.call(this, '/custom-fields/cards', undefined, ['name', 'title'], ['id']);
|
|
12
35
|
}
|
|
13
36
|
async function customFields_getDefinitions() {
|
|
14
37
|
const cardId = this.getCurrentNodeParameter('cardId');
|
|
15
38
|
const customFieldCardId = this.getCurrentNodeParameter('customFieldCardId');
|
|
16
39
|
const filterCardId = cardId || customFieldCardId;
|
|
17
|
-
|
|
40
|
+
const definitions = await shared_1.lsRequestAll.call(this, '/custom-fields/definitions', {
|
|
41
|
+
qs: filterCardId ? { customFieldCardId: filterCardId } : undefined,
|
|
42
|
+
});
|
|
43
|
+
return definitions
|
|
44
|
+
.filter((definition) => typeof definition === 'object' && definition !== null)
|
|
45
|
+
.map((definition) => {
|
|
46
|
+
var _a, _b, _c, _d;
|
|
47
|
+
const definitionRecord = definition;
|
|
48
|
+
const key = definitionRecord.key;
|
|
49
|
+
const typeDefinition = definitionRecord.typeDefinition;
|
|
50
|
+
const fieldType = String((_a = typeDefinition === null || typeDefinition === void 0 ? void 0 : typeDefinition.type) !== null && _a !== void 0 ? _a : '').toLowerCase();
|
|
51
|
+
const fieldName = String((_d = (_c = (_b = definitionRecord.label) !== null && _b !== void 0 ? _b : definitionRecord.name) !== null && _c !== void 0 ? _c : key) !== null && _d !== void 0 ? _d : 'Unknown');
|
|
52
|
+
const value = String(key !== null && key !== void 0 ? key : fieldName);
|
|
53
|
+
if (!MEDIA_FIELD_TYPES.has(fieldType)) {
|
|
54
|
+
return { name: fieldName, value };
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
name: `${fieldName} (${getMediaFieldDetails(fieldType, typeDefinition)})`,
|
|
58
|
+
value,
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
async function customFields_getMediaDefinitions() {
|
|
63
|
+
var _a, _b, _c, _d, _e;
|
|
64
|
+
const cards = await shared_1.lsRequestAll.call(this, '/custom-fields/cards/expanded');
|
|
65
|
+
const options = [];
|
|
66
|
+
for (const card of cards) {
|
|
67
|
+
if (typeof card !== 'object' || card === null)
|
|
68
|
+
continue;
|
|
69
|
+
const cardRecord = card;
|
|
70
|
+
const definitions = cardRecord.definitions;
|
|
71
|
+
if (!Array.isArray(definitions))
|
|
72
|
+
continue;
|
|
73
|
+
const cardName = String((_b = (_a = cardRecord.name) !== null && _a !== void 0 ? _a : cardRecord.title) !== null && _b !== void 0 ? _b : '').trim();
|
|
74
|
+
for (const definition of definitions) {
|
|
75
|
+
if (typeof definition !== 'object' || definition === null)
|
|
76
|
+
continue;
|
|
77
|
+
const definitionRecord = definition;
|
|
78
|
+
const key = definitionRecord.key;
|
|
79
|
+
const typeDefinition = definitionRecord.typeDefinition;
|
|
80
|
+
const fieldType = String((_c = typeDefinition === null || typeDefinition === void 0 ? void 0 : typeDefinition.type) !== null && _c !== void 0 ? _c : '').toLowerCase();
|
|
81
|
+
if (typeof key !== 'string' || !MEDIA_FIELD_TYPES.has(fieldType)) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const fieldName = String((_e = (_d = definitionRecord.label) !== null && _d !== void 0 ? _d : definitionRecord.name) !== null && _e !== void 0 ? _e : key);
|
|
85
|
+
const details = getMediaFieldDetails(fieldType, typeDefinition, cardName);
|
|
86
|
+
const name = `${fieldName} (${details})`;
|
|
87
|
+
options.push({ name, value: key });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return options.sort((a, b) => String(a.name).localeCompare(String(b.name)));
|
|
18
91
|
}
|
|
19
92
|
async function customFields_getCategories() {
|
|
20
93
|
const customFieldCardId = this.getCurrentNodeParameter('customFieldCardId');
|
|
21
|
-
return common_1.
|
|
94
|
+
return common_1.fetchOptionsAll.call(this, '/custom-fields/categories', customFieldCardId ? { customFieldCardId } : undefined, ['name', 'title'], ['id']);
|
|
22
95
|
}
|
|
23
96
|
async function customFields_getFieldType() {
|
|
24
97
|
const fieldKey = this.getCurrentNodeParameter('fieldKey');
|
|
@@ -6,10 +6,7 @@ exports.getLsSimpleType = getLsSimpleType;
|
|
|
6
6
|
const request_1 = require("./request");
|
|
7
7
|
const customFields_shared_1 = require("./customFields.shared");
|
|
8
8
|
async function fetchFieldDefinition(ctx, fieldKey) {
|
|
9
|
-
const cards = await request_1.
|
|
10
|
-
if (!Array.isArray(cards)) {
|
|
11
|
-
return undefined;
|
|
12
|
-
}
|
|
9
|
+
const cards = await request_1.lsRequestAll.call(ctx, '/custom-fields/cards/expanded');
|
|
13
10
|
for (const card of cards) {
|
|
14
11
|
if (!(0, customFields_shared_1.isLsCard)(card) || !Array.isArray(card.definitions)) {
|
|
15
12
|
continue;
|
|
@@ -9,5 +9,5 @@ interface UploadedFileValue {
|
|
|
9
9
|
* Uploads one or more binary properties and returns the array of file value objects.
|
|
10
10
|
* The binaryPropertyNames parameter can be a comma-separated list (e.g. "data,file1,file2").
|
|
11
11
|
*/
|
|
12
|
-
export declare function uploadFilesFromBinaryProperties(ctx: IExecuteFunctions, itemIndex: number, userId: string, binaryPropertyNames: string, fieldType: string, fileNameOverride?: string): Promise<UploadedFileValue[]>;
|
|
12
|
+
export declare function uploadFilesFromBinaryProperties(ctx: IExecuteFunctions, itemIndex: number, userId: string, customFieldKey: string, binaryPropertyNames: string, fieldType: string, fileNameOverride?: string): Promise<UploadedFileValue[]>;
|
|
13
13
|
export {};
|
|
@@ -10,9 +10,13 @@ function resolveFileType(fieldType) {
|
|
|
10
10
|
* Creates a file slot in the LearningSuite custom-field store for a given user.
|
|
11
11
|
* Returns the fileId and the uploadSpec describing how/where to upload.
|
|
12
12
|
*/
|
|
13
|
-
async function createFileSlot(ctx, userId,
|
|
13
|
+
async function createFileSlot(ctx, userId, customFieldKey, fileName) {
|
|
14
|
+
const body = { customFieldKey };
|
|
15
|
+
if (fileName) {
|
|
16
|
+
body.fileName = fileName;
|
|
17
|
+
}
|
|
14
18
|
const response = (await request_1.lsRequest.call(ctx, 'POST', `/custom-fields/store/${userId}/files`, {
|
|
15
|
-
body
|
|
19
|
+
body,
|
|
16
20
|
}));
|
|
17
21
|
const fileId = response.fileId;
|
|
18
22
|
const uploadSpec = response.uploadSpec;
|
|
@@ -68,9 +72,7 @@ async function uploadViaTus(ctx, uploadSpec, buffer, fileName, contentType) {
|
|
|
68
72
|
if (!location) {
|
|
69
73
|
throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'tus creation response missing Location header');
|
|
70
74
|
}
|
|
71
|
-
const uploadUrl = location.startsWith('http')
|
|
72
|
-
? location
|
|
73
|
-
: new URL(location, uploadSpec.uploadUrl).toString();
|
|
75
|
+
const uploadUrl = location.startsWith('http') ? location : new URL(location, uploadSpec.uploadUrl).toString();
|
|
74
76
|
let offset = 0;
|
|
75
77
|
while (offset < buffer.length) {
|
|
76
78
|
const chunk = buffer.subarray(offset, Math.min(offset + TUS_CHUNK_SIZE, buffer.length));
|
|
@@ -157,14 +159,13 @@ function createUploadedFileValue(fileType, fileId, file) {
|
|
|
157
159
|
* 2. Upload the binary data via HTTP PUT
|
|
158
160
|
* 3. Return the file value object to store on the custom field
|
|
159
161
|
*/
|
|
160
|
-
async function uploadSingleFile(ctx, itemIndex, userId, binaryPropertyName, fieldType, fileNameOverride) {
|
|
162
|
+
async function uploadSingleFile(ctx, itemIndex, userId, customFieldKey, binaryPropertyName, fieldType, fileNameOverride) {
|
|
161
163
|
const binaryData = ctx.helpers.assertBinaryData(itemIndex, binaryPropertyName);
|
|
162
164
|
const buffer = await ctx.helpers.getBinaryDataBuffer(itemIndex, binaryPropertyName);
|
|
163
165
|
const fileType = resolveFileType(fieldType);
|
|
164
|
-
const isVideo = fileType === 'videos';
|
|
165
166
|
const mimeType = binaryData.mimeType || 'application/octet-stream';
|
|
166
167
|
const fileName = fileNameOverride || binaryData.fileName || 'upload';
|
|
167
|
-
const { fileId, uploadSpec } = await createFileSlot(ctx, userId,
|
|
168
|
+
const { fileId, uploadSpec } = await createFileSlot(ctx, userId, customFieldKey, fileName);
|
|
168
169
|
if (uploadSpec.type === 'storage') {
|
|
169
170
|
await uploadViaStorage(ctx, uploadSpec, buffer, mimeType);
|
|
170
171
|
}
|
|
@@ -181,7 +182,7 @@ async function uploadSingleFile(ctx, itemIndex, userId, binaryPropertyName, fiel
|
|
|
181
182
|
* Uploads one or more binary properties and returns the array of file value objects.
|
|
182
183
|
* The binaryPropertyNames parameter can be a comma-separated list (e.g. "data,file1,file2").
|
|
183
184
|
*/
|
|
184
|
-
async function uploadFilesFromBinaryProperties(ctx, itemIndex, userId, binaryPropertyNames, fieldType, fileNameOverride) {
|
|
185
|
+
async function uploadFilesFromBinaryProperties(ctx, itemIndex, userId, customFieldKey, binaryPropertyNames, fieldType, fileNameOverride) {
|
|
185
186
|
const names = binaryPropertyNames
|
|
186
187
|
.split(',')
|
|
187
188
|
.map((n) => n.trim())
|
|
@@ -191,7 +192,7 @@ async function uploadFilesFromBinaryProperties(ctx, itemIndex, userId, binaryPro
|
|
|
191
192
|
}
|
|
192
193
|
const results = [];
|
|
193
194
|
for (const name of names) {
|
|
194
|
-
const value = await uploadSingleFile(ctx, itemIndex, userId, name, fieldType, fileNameOverride);
|
|
195
|
+
const value = await uploadSingleFile(ctx, itemIndex, userId, customFieldKey, name, fieldType, fileNameOverride);
|
|
195
196
|
results.push(value);
|
|
196
197
|
}
|
|
197
198
|
return results;
|
|
@@ -11,3 +11,6 @@ export declare function apiRequest(this: ApiThis, { method, path, qs, body, }: {
|
|
|
11
11
|
qs?: IDataObject;
|
|
12
12
|
body?: IDataObject;
|
|
13
13
|
}): Promise<IDataObject | IDataObject[]>;
|
|
14
|
+
export declare function lsRequestAll(this: ApiThis, endpoint: string, { qs }?: {
|
|
15
|
+
qs?: IDataObject;
|
|
16
|
+
}): Promise<IDataObject[]>;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.normalizeEndpoint = normalizeEndpoint;
|
|
4
4
|
exports.lsRequest = lsRequest;
|
|
5
5
|
exports.apiRequest = apiRequest;
|
|
6
|
+
exports.lsRequestAll = lsRequestAll;
|
|
6
7
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
7
8
|
function hasRequestWithAuthentication(value) {
|
|
8
9
|
var _a;
|
|
@@ -51,3 +52,20 @@ async function lsRequest(method, endpoint, { qs, body } = {}) {
|
|
|
51
52
|
async function apiRequest({ method, path, qs, body, }) {
|
|
52
53
|
return requestCore.call(this, { method, endpoint: path, qs, body });
|
|
53
54
|
}
|
|
55
|
+
async function lsRequestAll(endpoint, { qs } = {}) {
|
|
56
|
+
const pageSize = 100;
|
|
57
|
+
const maxPages = 500;
|
|
58
|
+
const all = [];
|
|
59
|
+
let offset = 0;
|
|
60
|
+
for (let page = 0; page < maxPages; page++) {
|
|
61
|
+
const res = await lsRequest.call(this, 'GET', endpoint, {
|
|
62
|
+
qs: { ...(qs !== null && qs !== void 0 ? qs : {}), limit: pageSize, offset },
|
|
63
|
+
});
|
|
64
|
+
const rows = Array.isArray(res) ? res : res ? [res] : [];
|
|
65
|
+
all.push(...rows);
|
|
66
|
+
if (rows.length < pageSize)
|
|
67
|
+
break;
|
|
68
|
+
offset += pageSize;
|
|
69
|
+
}
|
|
70
|
+
return all;
|
|
71
|
+
}
|