@comandosai/n8n-nodes-lsi-keys 0.1.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.
package/LsiKeys.png ADDED
Binary file
package/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # Commandos LSI Keys (кастомная нода n8n)
2
+
3
+ Кастомная нода для генерации LSI-ключей через Comandos API.
4
+
5
+ ## Где находится
6
+
7
+ - Код ноды: `/root/sandbox/nodes/lsi-keys`
8
+ - Пакет: `@comandosai/n8n-nodes-lsi-keys`
9
+
10
+ ## Требования
11
+
12
+ - n8n (dev окружение)
13
+ - Node.js 18+
14
+ - Доступ к Commandos API
15
+
16
+ ## Подключение в n8n-dev
17
+
18
+ В `docker-compose` нужно:
19
+ - смонтировать `/root/sandbox/nodes` в `/custom/commandos`
20
+ - добавить путь `N8N_CUSTOM_EXTENSIONS=/custom/commandos`
21
+
22
+ ## Credentials
23
+
24
+ Тип: `Commandos API` (лицензионный ключ)
25
+
26
+ ## Параметры
27
+
28
+ - **Topic**: Основная тема для сбора LSI
29
+ - **Country**: Страна (RU, US и т.д.)
30
+ - **City**: Город
31
+
32
+ ## Сборка
33
+
34
+ ```bash
35
+ npm install
36
+ npm run build
37
+ ```
@@ -0,0 +1,19 @@
1
+ import type { ICredentialType, INodeProperties } from 'n8n-workflow';
2
+
3
+ export class ComandosApi implements ICredentialType {
4
+ name = 'comandosApi';
5
+ displayName = 'Comandos API';
6
+ documentationUrl = 'https://api.comandos.ai';
7
+ properties: INodeProperties[] = [
8
+ {
9
+ displayName: 'License Key',
10
+ name: 'licenseKey',
11
+ type: 'string',
12
+ default: '',
13
+ required: true,
14
+ typeOptions: {
15
+ password: true,
16
+ },
17
+ },
18
+ ];
19
+ }
@@ -0,0 +1,7 @@
1
+ import type { ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class ComandosApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ComandosApi = void 0;
4
+ class ComandosApi {
5
+ name = 'comandosApi';
6
+ displayName = 'Comandos API';
7
+ documentationUrl = 'https://api.comandos.ai';
8
+ properties = [
9
+ {
10
+ displayName: 'License Key',
11
+ name: 'licenseKey',
12
+ type: 'string',
13
+ default: '',
14
+ required: true,
15
+ typeOptions: {
16
+ password: true,
17
+ },
18
+ },
19
+ ];
20
+ }
21
+ exports.ComandosApi = ComandosApi;
22
+ //# sourceMappingURL=ComandosApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComandosApi.credentials.js","sourceRoot":"","sources":["../../credentials/ComandosApi.credentials.ts"],"names":[],"mappings":";;;AAEA,MAAa,WAAW;IACtB,IAAI,GAAG,aAAa,CAAC;IACrB,WAAW,GAAG,cAAc,CAAC;IAC7B,gBAAgB,GAAG,yBAAyB,CAAC;IAC7C,UAAU,GAAsB;QAC9B;YACE,WAAW,EAAE,aAAa;YAC1B,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE;gBACX,QAAQ,EAAE,IAAI;aACf;SACF;KACF,CAAC;CACH;AAhBD,kCAgBC"}
@@ -0,0 +1,7 @@
1
+ import type { ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class ComandosWordpressApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ComandosWordpressApi = void 0;
4
+ class ComandosWordpressApi {
5
+ name = 'comandosWordpressApi';
6
+ displayName = 'Comandos WordPress';
7
+ documentationUrl = 'https://api.comandos.ai';
8
+ properties = [
9
+ {
10
+ displayName: 'Лицензионный ключ',
11
+ name: 'licenseKey',
12
+ type: 'string',
13
+ default: '',
14
+ required: true,
15
+ typeOptions: {
16
+ password: true,
17
+ },
18
+ },
19
+ {
20
+ displayName: 'URL WordPress',
21
+ name: 'wpUrl',
22
+ type: 'string',
23
+ default: '',
24
+ required: true,
25
+ },
26
+ {
27
+ displayName: 'Имя пользователя WordPress',
28
+ name: 'wpUsername',
29
+ type: 'string',
30
+ default: '',
31
+ required: true,
32
+ },
33
+ {
34
+ displayName: 'Пароль приложения WordPress',
35
+ name: 'wpAppPassword',
36
+ type: 'string',
37
+ default: '',
38
+ required: true,
39
+ typeOptions: {
40
+ password: true,
41
+ },
42
+ },
43
+ ];
44
+ }
45
+ exports.ComandosWordpressApi = ComandosWordpressApi;
46
+ //# sourceMappingURL=ComandosWordpressApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComandosWordpressApi.credentials.js","sourceRoot":"","sources":["../../credentials/ComandosWordpressApi.credentials.ts"],"names":[],"mappings":";;;AAEA,MAAa,oBAAoB;IAC/B,IAAI,GAAG,sBAAsB,CAAC;IAC9B,WAAW,GAAG,oBAAoB,CAAC;IACnC,gBAAgB,GAAG,yBAAyB,CAAC;IAC7C,UAAU,GAAsB;QAC9B;YACE,WAAW,EAAE,mBAAmB;YAChC,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE;gBACX,QAAQ,EAAE,IAAI;aACf;SACF;QACD;YACE,WAAW,EAAE,eAAe;YAC5B,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI;SACf;QACD;YACE,WAAW,EAAE,4BAA4B;YACzC,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI;SACf;QACD;YACE,WAAW,EAAE,6BAA6B;YAC1C,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE;gBACX,QAAQ,EAAE,IAAI;aACf;SACF;KACF,CAAC;CACH;AAxCD,oDAwCC"}
@@ -0,0 +1,3 @@
1
+ import { ComandosLsiKeys } from './nodes/ComandosLsiKeys.node';
2
+ import { ComandosApi } from './credentials/ComandosApi.credentials';
3
+ export { ComandosLsiKeys, ComandosApi };
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ComandosApi = exports.ComandosLsiKeys = void 0;
4
+ const ComandosLsiKeys_node_1 = require("./nodes/ComandosLsiKeys.node");
5
+ Object.defineProperty(exports, "ComandosLsiKeys", { enumerable: true, get: function () { return ComandosLsiKeys_node_1.ComandosLsiKeys; } });
6
+ const ComandosApi_credentials_1 = require("./credentials/ComandosApi.credentials");
7
+ Object.defineProperty(exports, "ComandosApi", { enumerable: true, get: function () { return ComandosApi_credentials_1.ComandosApi; } });
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;AAAA,uEAA+D;AAGtD,gGAHA,sCAAe,OAGA;AAFxB,mFAAoE;AAE1C,4FAFjB,qCAAW,OAEiB"}
@@ -0,0 +1,5 @@
1
+ import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ export declare class ComandosLsiKeys implements INodeType {
3
+ description: INodeTypeDescription;
4
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
+ }
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ComandosLsiKeys = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ const COMANDOS_API_URL = String(process.env.COMANDOS_API_BASE_URL || process.env.COMMANDOS_API_BASE_URL || "https://api.comandos.ai").trim();
6
+ class ComandosLsiKeys {
7
+ description = {
8
+ displayName: 'Comandos LSI Keys',
9
+ name: 'comandosLsiKeys',
10
+ group: ['transform'],
11
+ version: 1,
12
+ description: 'Генерация LSI ключей через Comandos API',
13
+ defaults: {
14
+ name: 'Comandos LSI Keys',
15
+ },
16
+ icon: 'file:LsiKeys.png',
17
+ inputs: ['main'],
18
+ outputs: ['main'],
19
+ credentials: [
20
+ {
21
+ name: 'comandosApi',
22
+ required: true,
23
+ },
24
+ ],
25
+ properties: [
26
+ {
27
+ displayName: 'Операция',
28
+ name: 'operation',
29
+ type: 'options',
30
+ noDataExpression: true,
31
+ options: [
32
+ {
33
+ name: 'LSI Ключи',
34
+ value: 'getLsiKeys',
35
+ description: 'Сгенерировать облако семантически связанных слов (LSI) для вашей темы',
36
+ },
37
+ ],
38
+ default: 'getLsiKeys',
39
+ },
40
+ {
41
+ displayName: 'Тема (Topic)',
42
+ name: 'topic',
43
+ type: 'string',
44
+ default: '',
45
+ required: true,
46
+ displayOptions: {
47
+ show: {
48
+ operation: ['getLsiKeys'],
49
+ },
50
+ },
51
+ description: 'Введите тему или запрос, для которого нужно подобрать ключи',
52
+ },
53
+ {
54
+ displayName: 'Страна',
55
+ name: 'country',
56
+ type: 'string',
57
+ default: '',
58
+ displayOptions: {
59
+ show: {
60
+ operation: ['getLsiKeys'],
61
+ },
62
+ },
63
+ description: 'Укажите страну для уточнения семантики (например: Россия)',
64
+ },
65
+ {
66
+ displayName: 'Город',
67
+ name: 'city',
68
+ type: 'string',
69
+ default: '',
70
+ displayOptions: {
71
+ show: {
72
+ operation: ['getLsiKeys'],
73
+ },
74
+ },
75
+ description: 'Укажите город для уточнения семантики (например: Москва)',
76
+ },
77
+ ],
78
+ };
79
+ async execute() {
80
+ const items = this.getInputData();
81
+ const operation = this.getNodeParameter('operation', 0);
82
+ const credentials = await this.getCredentials('comandosApi');
83
+ const licenseKey = String(credentials.licenseKey || '').trim();
84
+ if (!licenseKey) {
85
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Лицензионный ключ обязателен');
86
+ }
87
+ const results = [];
88
+ for (let i = 0; i < items.length; i += 1) {
89
+ try {
90
+ if (operation === 'getLsiKeys') {
91
+ const topic = String(this.getNodeParameter('topic', i) || '').trim();
92
+ const country = String(this.getNodeParameter('country', i) || '').trim();
93
+ const city = String(this.getNodeParameter('city', i) || '').trim();
94
+ if (!topic) {
95
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Тема обязательна для получения LSI ключей', {
96
+ itemIndex: i,
97
+ });
98
+ }
99
+ const response = await this.helpers.request({
100
+ method: 'POST',
101
+ url: `${COMANDOS_API_URL}/tasks`,
102
+ headers: {
103
+ 'Content-Type': 'application/json',
104
+ 'X-License-Key': licenseKey,
105
+ },
106
+ body: {
107
+ process_type: 'WP_PUBLICATION',
108
+ payload: {
109
+ action: 'get_lsi_keys',
110
+ topic,
111
+ country,
112
+ city,
113
+ },
114
+ },
115
+ json: true,
116
+ });
117
+ results.push({ json: response });
118
+ continue;
119
+ }
120
+ }
121
+ catch (error) {
122
+ if (error instanceof n8n_workflow_1.NodeOperationError)
123
+ throw error;
124
+ const message = error instanceof Error ? error.message : 'Ошибка при выполнении запроса';
125
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), message, { itemIndex: i });
126
+ }
127
+ }
128
+ return [results];
129
+ }
130
+ }
131
+ exports.ComandosLsiKeys = ComandosLsiKeys;
132
+ //# sourceMappingURL=ComandosLsiKeys.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ComandosLsiKeys.node.js","sourceRoot":"","sources":["../../nodes/ComandosLsiKeys.node.ts"],"names":[],"mappings":";;;AAOA,+CAAkD;AAElD,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,yBAAyB,CAAC,CAAC,IAAI,EAAE,CAAC;AAE7I,MAAa,eAAe;IACxB,WAAW,GAAyB;QAChC,WAAW,EAAE,mBAAmB;QAChC,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE,CAAC,WAAW,CAAC;QACpB,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,yCAAyC;QACtD,QAAQ,EAAE;YACN,IAAI,EAAE,mBAAmB;SAC5B;QACD,IAAI,EAAE,kBAAkB;QACxB,MAAM,EAAE,CAAC,MAAM,CAAC;QAChB,OAAO,EAAE,CAAC,MAAM,CAAC;QACjB,WAAW,EAAE;YACT;gBACI,IAAI,EAAE,aAAa;gBACnB,QAAQ,EAAE,IAAI;aACjB;SACJ;QACD,UAAU,EAAE;YACR;gBACI,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,SAAS;gBACf,gBAAgB,EAAE,IAAI;gBACtB,OAAO,EAAE;oBACL;wBACI,IAAI,EAAE,WAAW;wBACjB,KAAK,EAAE,YAAY;wBACnB,WAAW,EAAE,uEAAuE;qBACvF;iBACJ;gBACD,OAAO,EAAE,YAAY;aACxB;YACD;gBACI,WAAW,EAAE,cAAc;gBAC3B,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,cAAc,EAAE;oBACZ,IAAI,EAAE;wBACF,SAAS,EAAE,CAAC,YAAY,CAAC;qBAC5B;iBACJ;gBACD,WAAW,EAAE,6DAA6D;aAC7E;YACD;gBACI,WAAW,EAAE,QAAQ;gBACrB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,cAAc,EAAE;oBACZ,IAAI,EAAE;wBACF,SAAS,EAAE,CAAC,YAAY,CAAC;qBAC5B;iBACJ;gBACD,WAAW,EAAE,2DAA2D;aAC3E;YACD;gBACI,WAAW,EAAE,OAAO;gBACpB,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,cAAc,EAAE;oBACZ,IAAI,EAAE;wBACF,SAAS,EAAE,CAAC,YAAY,CAAC;qBAC5B;iBACJ;gBACD,WAAW,EAAE,0DAA0D;aAC1E;SACJ;KACJ,CAAC;IAEF,KAAK,CAAC,OAAO;QACT,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAW,CAAC;QAClE,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;QAC7D,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAE/D,IAAI,CAAC,UAAU,EAAE,CAAC;YACd,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,8BAA8B,CAAC,CAAC;QACjF,CAAC;QAED,MAAM,OAAO,GAAyB,EAAE,CAAC;QAEzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC;gBACD,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;oBAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;oBACrE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;oBACzE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;oBAEnE,IAAI,CAAC,KAAK,EAAE,CAAC;wBACT,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,2CAA2C,EAAE;4BACtF,SAAS,EAAE,CAAC;yBACf,CAAC,CAAC;oBACP,CAAC;oBAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;wBACxC,MAAM,EAAE,MAAM;wBACd,GAAG,EAAE,GAAG,gBAAgB,QAAQ;wBAChC,OAAO,EAAE;4BACL,cAAc,EAAE,kBAAkB;4BAClC,eAAe,EAAE,UAAU;yBAC9B;wBACD,IAAI,EAAE;4BACF,YAAY,EAAE,gBAAgB;4BAC9B,OAAO,EAAE;gCACL,MAAM,EAAE,cAAc;gCACtB,KAAK;gCACL,OAAO;gCACP,IAAI;6BACP;yBACJ;wBACD,IAAI,EAAE,IAAI;qBACb,CAAC,CAAC;oBAEH,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAuB,EAAE,CAAC,CAAC;oBAChD,SAAS;gBACb,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,IAAI,KAAK,YAAY,iCAAkB;oBAAE,MAAM,KAAK,CAAC;gBACrD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,+BAA+B,CAAC;gBACzF,MAAM,IAAI,iCAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;YAC5E,CAAC;QACL,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;CACJ;AAlID,0CAkIC"}
Binary file
package/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { ComandosLsiKeys } from './nodes/ComandosLsiKeys.node';
2
+ import { ComandosApi } from './credentials/ComandosApi.credentials';
3
+
4
+ export { ComandosLsiKeys, ComandosApi };
@@ -0,0 +1,142 @@
1
+ import type {
2
+ IDataObject,
3
+ IExecuteFunctions,
4
+ INodeExecutionData,
5
+ INodeType,
6
+ INodeTypeDescription,
7
+ } from 'n8n-workflow';
8
+ import { NodeOperationError } from 'n8n-workflow';
9
+
10
+ const COMANDOS_API_URL = String(process.env.COMANDOS_API_BASE_URL || process.env.COMMANDOS_API_BASE_URL || "https://api.comandos.ai").trim();
11
+
12
+ export class ComandosLsiKeys implements INodeType {
13
+ description: INodeTypeDescription = {
14
+ displayName: 'Comandos LSI Keys',
15
+ name: 'comandosLsiKeys',
16
+ group: ['transform'],
17
+ version: 1,
18
+ description: 'Генерация LSI ключей через Comandos API',
19
+ defaults: {
20
+ name: 'Comandos LSI Keys',
21
+ },
22
+ icon: 'file:LsiKeys.png',
23
+ inputs: ['main'],
24
+ outputs: ['main'],
25
+ credentials: [
26
+ {
27
+ name: 'comandosApi',
28
+ required: true,
29
+ },
30
+ ],
31
+ properties: [
32
+ {
33
+ displayName: 'Операция',
34
+ name: 'operation',
35
+ type: 'options',
36
+ noDataExpression: true,
37
+ options: [
38
+ {
39
+ name: 'LSI Ключи',
40
+ value: 'getLsiKeys',
41
+ description: 'Сгенерировать облако семантически связанных слов (LSI) для вашей темы',
42
+ },
43
+ ],
44
+ default: 'getLsiKeys',
45
+ },
46
+ {
47
+ displayName: 'Тема (Topic)',
48
+ name: 'topic',
49
+ type: 'string',
50
+ default: '',
51
+ required: true,
52
+ displayOptions: {
53
+ show: {
54
+ operation: ['getLsiKeys'],
55
+ },
56
+ },
57
+ description: 'Введите тему или запрос, для которого нужно подобрать ключи',
58
+ },
59
+ {
60
+ displayName: 'Страна',
61
+ name: 'country',
62
+ type: 'string',
63
+ default: '',
64
+ displayOptions: {
65
+ show: {
66
+ operation: ['getLsiKeys'],
67
+ },
68
+ },
69
+ description: 'Укажите страну для уточнения семантики (например: Россия)',
70
+ },
71
+ {
72
+ displayName: 'Город',
73
+ name: 'city',
74
+ type: 'string',
75
+ default: '',
76
+ displayOptions: {
77
+ show: {
78
+ operation: ['getLsiKeys'],
79
+ },
80
+ },
81
+ description: 'Укажите город для уточнения семантики (например: Москва)',
82
+ },
83
+ ],
84
+ };
85
+
86
+ async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
87
+ const items = this.getInputData();
88
+ const operation = this.getNodeParameter('operation', 0) as string;
89
+ const credentials = await this.getCredentials('comandosApi');
90
+ const licenseKey = String(credentials.licenseKey || '').trim();
91
+
92
+ if (!licenseKey) {
93
+ throw new NodeOperationError(this.getNode(), 'Лицензионный ключ обязателен');
94
+ }
95
+
96
+ const results: INodeExecutionData[] = [];
97
+
98
+ for (let i = 0; i < items.length; i += 1) {
99
+ try {
100
+ if (operation === 'getLsiKeys') {
101
+ const topic = String(this.getNodeParameter('topic', i) || '').trim();
102
+ const country = String(this.getNodeParameter('country', i) || '').trim();
103
+ const city = String(this.getNodeParameter('city', i) || '').trim();
104
+
105
+ if (!topic) {
106
+ throw new NodeOperationError(this.getNode(), 'Тема обязательна для получения LSI ключей', {
107
+ itemIndex: i,
108
+ });
109
+ }
110
+
111
+ const response = await this.helpers.request({
112
+ method: 'POST',
113
+ url: `${COMANDOS_API_URL}/tasks`,
114
+ headers: {
115
+ 'Content-Type': 'application/json',
116
+ 'X-License-Key': licenseKey,
117
+ },
118
+ body: {
119
+ process_type: 'WP_PUBLICATION',
120
+ payload: {
121
+ action: 'get_lsi_keys',
122
+ topic,
123
+ country,
124
+ city,
125
+ },
126
+ },
127
+ json: true,
128
+ });
129
+
130
+ results.push({ json: response as IDataObject });
131
+ continue;
132
+ }
133
+ } catch (error) {
134
+ if (error instanceof NodeOperationError) throw error;
135
+ const message = error instanceof Error ? error.message : 'Ошибка при выполнении запроса';
136
+ throw new NodeOperationError(this.getNode(), message, { itemIndex: i });
137
+ }
138
+ }
139
+
140
+ return [results];
141
+ }
142
+ }
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@comandosai/n8n-nodes-lsi-keys",
3
+ "version": "0.1.0",
4
+ "description": "Comandos LSI Keys custom node",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc -p tsconfig.json && mkdir -p dist/nodes && cp -f LsiKeys.png dist/nodes/"
9
+ },
10
+ "dependencies": {
11
+ "n8n-workflow": "^1.0.0"
12
+ },
13
+ "devDependencies": {
14
+ "@types/node": "^18.19.0",
15
+ "typescript": "^5.4.5"
16
+ },
17
+ "n8n": {
18
+ "nodes": [
19
+ "dist/nodes/ComandosLsiKeys.node.js"
20
+ ],
21
+ "credentials": [
22
+ "dist/credentials/ComandosApi.credentials.js"
23
+ ]
24
+ }
25
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "CommonJS",
5
+ "lib": [
6
+ "ESNext"
7
+ ],
8
+ "declaration": true,
9
+ "sourceMap": true,
10
+ "outDir": "dist",
11
+ "rootDir": ".",
12
+ "strict": true,
13
+ "esModuleInterop": true,
14
+ "skipLibCheck": true,
15
+ "forceConsistentCasingInFileNames": true,
16
+ "moduleResolution": "node"
17
+ },
18
+ "include": [
19
+ "**/*.ts"
20
+ ],
21
+ "exclude": [
22
+ "node_modules",
23
+ "dist"
24
+ ]
25
+ }