n8n-nodes-nvk-call-api 0.0.1

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.
@@ -0,0 +1,5 @@
1
+ import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ export declare class NvkBrowserApi implements INodeType {
3
+ description: INodeTypeDescription;
4
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
+ }
@@ -0,0 +1,308 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NvkBrowserApi = void 0;
4
+ const NvkBrowserApi_description_1 = require("./NvkBrowserApi.description");
5
+ class NvkBrowserApi {
6
+ constructor() {
7
+ this.description = NvkBrowserApi_description_1.nvkBrowserApiDescription;
8
+ }
9
+ async execute() {
10
+ const items = this.getInputData();
11
+ const returnData = [];
12
+ for (let i = 0; i < items.length; i++) {
13
+ try {
14
+ const environment = this.getNodeParameter('environment', i);
15
+ const resource = this.getNodeParameter('resource', i);
16
+ const operation = this.getNodeParameter('operation', i);
17
+ const baseUrl = environment === 'docker'
18
+ ? 'http://host.docker.internal:3000'
19
+ : 'http://localhost:3000';
20
+ let endpoint = '';
21
+ let body = {};
22
+ if (resource === 'profileManagement') {
23
+ switch (operation) {
24
+ case 'createProfile': {
25
+ endpoint = '/api/profile/create';
26
+ body = {
27
+ profileName: this.getNodeParameter('profileName', i),
28
+ proxy: this.getNodeParameter('proxy', i, ''),
29
+ note: this.getNodeParameter('note', i, ''),
30
+ extensions: this.getNodeParameter('extensions', i, ''),
31
+ };
32
+ break;
33
+ }
34
+ case 'deleteProfile': {
35
+ endpoint = '/api/profile/delete';
36
+ body = {
37
+ profileId: this.getNodeParameter('profileId', i),
38
+ };
39
+ break;
40
+ }
41
+ case 'startProfile': {
42
+ endpoint = '/api/profile/start';
43
+ const winPosition = this.getNodeParameter('winPosition', i, {});
44
+ const winSize = this.getNodeParameter('winSize', i, {});
45
+ body = {
46
+ profileId: this.getNodeParameter('profileId', i),
47
+ winScale: this.getNodeParameter('winScale', i, 1),
48
+ headless: this.getNodeParameter('headless', i, false),
49
+ initialUrl: this.getNodeParameter('initialUrl', i, ''),
50
+ };
51
+ if (winPosition.positionValues) {
52
+ body.winPosition = winPosition.positionValues;
53
+ }
54
+ if (winSize.sizeValues) {
55
+ body.winSize = winSize.sizeValues;
56
+ }
57
+ break;
58
+ }
59
+ case 'stopProfile': {
60
+ endpoint = '/api/profile/stop';
61
+ body = {
62
+ profileId: this.getNodeParameter('profileId', i),
63
+ };
64
+ break;
65
+ }
66
+ case 'updateProfile': {
67
+ endpoint = '/api/profile/update';
68
+ body = {
69
+ profileId: this.getNodeParameter('profileId', i),
70
+ profileName: this.getNodeParameter('profileName', i, ''),
71
+ proxy: this.getNodeParameter('proxy', i, ''),
72
+ note: this.getNodeParameter('note', i, ''),
73
+ extensions: this.getNodeParameter('extensions', i, ''),
74
+ };
75
+ break;
76
+ }
77
+ case 'downloadBrowser': {
78
+ endpoint = '/api/browser/download';
79
+ break;
80
+ }
81
+ }
82
+ }
83
+ else if (resource === 'pageInteraction') {
84
+ switch (operation) {
85
+ case 'moveAndClick': {
86
+ endpoint = '/api/browser/action';
87
+ const useBinaryFile = this.getNodeParameter('useBinaryFile', i, false);
88
+ body = {
89
+ profileId: this.getNodeParameter('profileId', i),
90
+ selector: this.getNodeParameter('selector', i),
91
+ clickMethod: this.getNodeParameter('clickMethod', i, 'puppeteer'),
92
+ timeout: this.getNodeParameter('timeout', i, 30000),
93
+ tabIndex: this.getNodeParameter('tabIndex', i, 0),
94
+ autoStart: this.getNodeParameter('autoStart', i, false),
95
+ waitForClick: this.getNodeParameter('waitForClick', i, 500),
96
+ button: this.getNodeParameter('button', i, 'left'),
97
+ clickCount: this.getNodeParameter('clickCount', i, 1),
98
+ useBinaryFile,
99
+ };
100
+ if (useBinaryFile) {
101
+ const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
102
+ const itemBinaryData = this.helpers.assertBinaryData(i, binaryPropertyName);
103
+ let uploadData;
104
+ if (itemBinaryData.id) {
105
+ const binaryStream = await this.helpers.getBinaryStream(itemBinaryData.id);
106
+ const chunks = [];
107
+ for await (const chunk of binaryStream) {
108
+ chunks.push(chunk);
109
+ }
110
+ uploadData = Buffer.concat(chunks);
111
+ }
112
+ else {
113
+ uploadData = Buffer.from(itemBinaryData.data, 'base64');
114
+ }
115
+ const base64Data = uploadData.toString('base64');
116
+ body.binaryFile = {
117
+ data: base64Data,
118
+ fileName: itemBinaryData.fileName || 'file',
119
+ mimeType: itemBinaryData.mimeType || 'application/octet-stream',
120
+ };
121
+ }
122
+ break;
123
+ }
124
+ case 'runJavaScript': {
125
+ endpoint = '/api/browser/script';
126
+ body = {
127
+ profileId: this.getNodeParameter('profileId', i),
128
+ javascriptCode: this.getNodeParameter('javascriptCode', i),
129
+ tabIndex: this.getNodeParameter('tabIndex', i, 0),
130
+ autoStart: this.getNodeParameter('autoStart', i, false),
131
+ };
132
+ break;
133
+ }
134
+ case 'getNetworkResponse': {
135
+ endpoint = '/api/browser/network';
136
+ body = {
137
+ profileId: this.getNodeParameter('profileId', i),
138
+ requestFilter: this.getNodeParameter('requestFilter', i),
139
+ matchType: this.getNodeParameter('matchType', i, 'contains'),
140
+ timeout: this.getNodeParameter('timeout', i, 30000),
141
+ waitForRequest: this.getNodeParameter('waitForRequest', i, true),
142
+ tabIndex: this.getNodeParameter('tabIndex', i, 0),
143
+ autoStart: this.getNodeParameter('autoStart', i, false),
144
+ };
145
+ break;
146
+ }
147
+ case 'browserHttpRequest': {
148
+ endpoint = '/api/browser/request';
149
+ const method = this.getNodeParameter('method', i, 'GET');
150
+ body = {
151
+ profileId: this.getNodeParameter('profileId', i),
152
+ method,
153
+ url: this.getNodeParameter('url', i),
154
+ tabIndex: this.getNodeParameter('tabIndex', i, 0),
155
+ autoStart: this.getNodeParameter('autoStart', i, false),
156
+ };
157
+ // Handle Additional Headers
158
+ const additionalHeaders = this.getNodeParameter('additionalHeaders', i, {});
159
+ if (additionalHeaders.header && Array.isArray(additionalHeaders.header)) {
160
+ body.additionalHeaders = additionalHeaders.header;
161
+ }
162
+ // Handle Query Parameters
163
+ const queryParameters = this.getNodeParameter('queryParameters', i, {});
164
+ if (queryParameters.parameter && Array.isArray(queryParameters.parameter)) {
165
+ body.queryParameters = queryParameters.parameter;
166
+ }
167
+ // Handle POST Body
168
+ if (method === 'POST') {
169
+ const sendBody = this.getNodeParameter('sendBody', i, false);
170
+ body.sendBody = sendBody;
171
+ if (sendBody) {
172
+ const bodyContentType = this.getNodeParameter('bodyContentType', i, 'json');
173
+ // ============ SINGLE BINARY FILE AS ENTIRE BODY ============
174
+ if (bodyContentType === 'binaryFile') {
175
+ body.bodyContentType = 'binary';
176
+ const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
177
+ const itemBinaryData = this.helpers.assertBinaryData(i, binaryPropertyName);
178
+ let uploadData;
179
+ if (itemBinaryData.id) {
180
+ // Binary data is stored as stream/file
181
+ const binaryStream = await this.helpers.getBinaryStream(itemBinaryData.id);
182
+ const chunks = [];
183
+ for await (const chunk of binaryStream) {
184
+ chunks.push(chunk);
185
+ }
186
+ uploadData = Buffer.concat(chunks);
187
+ }
188
+ else {
189
+ // Binary data is in memory
190
+ uploadData = Buffer.from(itemBinaryData.data, 'base64');
191
+ }
192
+ // Convert binary to base64 for transfer to API
193
+ const base64Data = uploadData.toString('base64');
194
+ const mimeType = itemBinaryData.mimeType || 'application/octet-stream';
195
+ body.binaryFile = {
196
+ data: base64Data,
197
+ mimeType,
198
+ fileName: itemBinaryData.fileName || 'file',
199
+ };
200
+ }
201
+ // ============ JSON BODY ============
202
+ else if (bodyContentType === 'json') {
203
+ body.bodyContentType = 'json';
204
+ body.jsonBody = this.getNodeParameter('jsonBody', i, '');
205
+ }
206
+ // ============ RAW BODY ============
207
+ else if (bodyContentType === 'raw') {
208
+ body.bodyContentType = 'raw';
209
+ body.rawBody = this.getNodeParameter('rawBody', i, '');
210
+ }
211
+ // ============ FORM URLENCODED (TEXT ONLY) ============
212
+ else if (bodyContentType === 'formUrlencoded') {
213
+ body.bodyContentType = 'formData';
214
+ const formData = this.getNodeParameter('formData', i, {});
215
+ if (formData.parameter && Array.isArray(formData.parameter)) {
216
+ const textParams = [];
217
+ for (const param of formData.parameter) {
218
+ textParams.push({
219
+ name: param.name,
220
+ value: param.value,
221
+ type: 'text'
222
+ });
223
+ }
224
+ body.formData = textParams;
225
+ }
226
+ }
227
+ // ============ FORM DATA (MIXED TEXT + BINARY) ============
228
+ else if (bodyContentType === 'formData') {
229
+ body.bodyContentType = 'formData';
230
+ const bodyParameters = this.getNodeParameter('bodyParameters', i, {});
231
+ if (bodyParameters.parameter && Array.isArray(bodyParameters.parameter)) {
232
+ const allFormDataParams = [];
233
+ for (const param of bodyParameters.parameter) {
234
+ if (param.parameterType === 'formData') {
235
+ // Regular text parameter
236
+ allFormDataParams.push({
237
+ name: param.name,
238
+ value: param.value || '',
239
+ type: 'text'
240
+ });
241
+ }
242
+ else if (param.parameterType === 'binaryFile') {
243
+ // Binary file parameter
244
+ const binaryPropertyName = param.binaryProperty || 'data';
245
+ const itemBinaryData = this.helpers.assertBinaryData(i, binaryPropertyName);
246
+ let uploadData;
247
+ if (itemBinaryData.id) {
248
+ // Binary data is stored as stream/file
249
+ const binaryStream = await this.helpers.getBinaryStream(itemBinaryData.id);
250
+ const chunks = [];
251
+ for await (const chunk of binaryStream) {
252
+ chunks.push(chunk);
253
+ }
254
+ uploadData = Buffer.concat(chunks);
255
+ }
256
+ else {
257
+ // Binary data is in memory
258
+ uploadData = Buffer.from(itemBinaryData.data, 'base64');
259
+ }
260
+ const base64Data = uploadData.toString('base64');
261
+ allFormDataParams.push({
262
+ name: param.name,
263
+ type: 'binary',
264
+ binaryData: {
265
+ data: base64Data,
266
+ fileName: itemBinaryData.fileName || 'file',
267
+ mimeType: itemBinaryData.mimeType || 'application/octet-stream',
268
+ }
269
+ });
270
+ }
271
+ }
272
+ body.formData = allFormDataParams;
273
+ }
274
+ }
275
+ }
276
+ }
277
+ break;
278
+ }
279
+ }
280
+ }
281
+ const response = await this.helpers.request({
282
+ method: 'POST',
283
+ url: `${baseUrl}${endpoint}`,
284
+ body,
285
+ json: true,
286
+ });
287
+ returnData.push({
288
+ json: response,
289
+ pairedItem: { item: i },
290
+ });
291
+ }
292
+ catch (error) {
293
+ if (this.continueOnFail()) {
294
+ returnData.push({
295
+ json: {
296
+ error: error instanceof Error ? error.message : String(error),
297
+ },
298
+ pairedItem: { item: i },
299
+ });
300
+ continue;
301
+ }
302
+ throw error;
303
+ }
304
+ }
305
+ return [returnData];
306
+ }
307
+ }
308
+ exports.NvkBrowserApi = NvkBrowserApi;
@@ -0,0 +1,63 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 25.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve">
5
+ <style type="text/css">
6
+ .st0{display:none;fill:#493F42;}
7
+ .st1{fill:#FFFFFF;}
8
+ .st2{display:none;}
9
+ .st3{display:inline;}
10
+ .st4{display:none;opacity:0.9;fill:#FFFFFF;enable-background:new ;}
11
+ .st5{display:none;fill:none;stroke:#FFFFFF;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;}
12
+ .st6{display:none;opacity:0.7;fill:#FFFFFF;enable-background:new ;}
13
+ .st7{fill:url(#SVGID_1_);}
14
+ .st8{fill:url(#SVGID_2_);}
15
+ </style>
16
+ <rect class="st0" width="64" height="64"/>
17
+ <ellipse class="st1" cx="31.8" cy="31.9" rx="31.4" ry="31.8"/>
18
+ <g class="st2">
19
+ <path class="st3" d="M31.4,34.7c0.7,0,0.9,0.2,0.8,0.9c-0.1,0.8,0,1.5,0,2.4c3-1.8,5.9-3.5,8.9-5.4c-3-1.8-5.9-3.5-8.9-5.3
20
+ c0,1,0,1.8,0,2.6c0,0.6-0.2,0.8-0.8,0.7c-2.7,0-5.4,0-8.2,0c-0.6,0-0.8-0.2-0.8-0.8c0-2.5,0-5.1,0-7.6c0-0.4,0.1-0.6,0.2-0.8h3.1
21
+ c0.9,0,1.8,0,2.7,0h0.1h3.6c1,0,2,0,3,0h3.5c0.1,0.2,0.1,0.4,0.1,0.7c-0.1,0.8,0,1.6,0,2.5c3-1.8,5.9-3.6,8.9-5.4
22
+ c-3-1.8-5.9-3.5-8.9-5.3c0,0.9-0.1,1.6,0,2.3c0.1,0.8-0.2,1-1,1c-6,0-12,0-18,0c-1.5,0-1.5,0-1.5,1.4c0,11.9,0,23.7,0,35.6
23
+ c0,0.2,0,0.4,0,0.6c0,0.5-0.2,0.6-0.6,0.3c-0.5-0.4-1.1-0.7-1.6-1c-4.7-3.5-8.2-8-10-13.6c-1.3-3.8-1.7-7.7-1.2-11.7
24
+ C5.3,26,6,23.2,7.2,20.6c1.6-3.4,3.7-6.4,6.6-8.9c2.5-2.1,5.2-3.9,8.3-5c3.7-1.4,7.5-1.9,11.4-1.6c3.2,0.3,6.1,1,9,2.3
25
+ c3.9,1.8,7.2,4.4,9.8,7.9C55.1,19,57,23,57.6,27.6c0.2,1.7,0.2,1.7,2,1.7c0.4,0,0.7,0,1.1,0c1.6,0,1.6,0,1.4-1.6
26
+ c-0.3-3.1-1.2-6-2.5-8.8c-1.8-4-4.4-7.5-7.7-10.4c-3-2.7-6.3-4.8-10.2-6.1s-7.9-2-12-1.7c-1.6,0.1-3.2,0.3-4.8,0.6
27
+ c-5.1,1-9.6,3.3-13.5,6.7c-2.5,2.1-4.6,4.7-6.4,7.5c-3.1,5-4.6,10.4-4.8,16.2c-0.1,2.2,0.1,4.4,0.6,6.6c1.3,6,3.9,11.2,8.2,15.6
28
+ c2.3,2.4,4.8,4.3,7.7,6c1.8,1,3.6,1.9,5.7,2.3c0-0.5,0-0.8,0-1.2c0-8.4,0-16.8,0-25.2c0-0.7,0.1-1,0.9-1
29
+ C26,34.7,28.7,34.7,31.4,34.7z"/>
30
+ <path class="st3" d="M61.4,34.6c-0.9,0.1-1.9,0-2.8,0c-0.5,0-0.7,0.2-0.8,0.7c-0.1,1.5-0.4,3-0.9,4.4c-1.5,4.8-4.1,9-7.9,12.4
31
+ c-1.7,1.5-3.6,2.9-5.6,3.9c-3,1.5-6.1,2.5-9.5,2.8c-2.3,0.2-4.5,0.1-6.8-0.2c0,1.2,0.1,2.4,0,3.6c0,0.7,0.3,1,0.9,1
32
+ c1,0,1.9,0.2,2.9,0.2c1.6,0,3.2-0.2,4.8-0.4c3.2-0.3,6.2-1.3,9.1-2.7c3.6-1.8,6.9-4.2,9.6-7.2c2.9-3.2,5-6.7,6.4-10.8
33
+ c0.8-2.2,1.2-4.4,1.6-6.6C62.5,35.1,62.4,34.6,61.4,34.6z"/>
34
+ </g>
35
+ <path class="st4" d="M32,12l-12,6v12l12,6l12-6V18L32,12z"/>
36
+ <path class="st5" d="M20,30l12,6l12-6 M20,30l12-6l12,6 M20,30v12l12,6l12-6V30"/>
37
+ <circle class="st6" cx="32" cy="52" r="4"/>
38
+ <g>
39
+ <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="48.1139" y1="5.3277" x2="9.5254" y2="50.3907">
40
+ <stop offset="0" style="stop-color:#66449A"/>
41
+ <stop offset="0.7862" style="stop-color:#F05822"/>
42
+ </linearGradient>
43
+ <path class="st7" d="M31.8,34.6c0.7,0,0.9,0.2,0.9,0.9c-0.1,0.8,0,1.6,0,2.5c3-1.8,5.9-3.6,9-5.4c-3-1.8-6-3.6-9-5.4
44
+ c0,1,0,1.8,0,2.6c0,0.6-0.2,0.8-0.8,0.8c-2.8,0-5.5,0-8.3,0c-0.6,0-0.8-0.2-0.8-0.8c0-2.6,0-5.1,0-7.7c0-0.4,0.1-0.6,0.2-0.8h3.2
45
+ c0.9,0,1.8,0,2.8,0c0,0,0.1,0,0.1,0h3.6c1,0,2,0,3.1,0h3.5c0.1,0.2,0.2,0.4,0.1,0.7c-0.1,0.8,0,1.6,0,2.5c3.1-1.9,6-3.6,9-5.5
46
+ c-3-1.8-5.9-3.5-9-5.4c0,0.9-0.1,1.6,0,2.4c0.1,0.8-0.2,1-1,1c-6.1,0-12.1,0-18.2,0c-1.5,0-1.5,0-1.5,1.5c0,12,0,24,0,36
47
+ c0,0.2,0,0.4,0,0.6c0,0.5-0.2,0.6-0.6,0.3c-0.5-0.4-1.1-0.7-1.6-1.1c-4.8-3.5-8.3-8-10.2-13.7C5,36.7,4.6,32.8,5.1,28.7
48
+ c0.4-2.9,1.1-5.7,2.3-8.3c1.6-3.5,3.8-6.5,6.7-9c2.5-2.2,5.2-4,8.4-5.1C26.2,4.9,30,4.4,34,4.7c3.2,0.3,6.2,1,9.1,2.3
49
+ c4,1.8,7.3,4.5,10,8c2.8,3.7,4.7,7.8,5.4,12.4c0.2,1.7,0.2,1.7,2,1.7c0.4,0,0.7,0,1.1,0c1.6,0,1.6,0,1.5-1.6
50
+ c-0.3-3.1-1.2-6.1-2.5-8.9c-1.8-4-4.4-7.6-7.8-10.5C49.6,5.4,46.3,3.3,42.4,2c-3.9-1.4-8-2-12.1-1.8c-1.6,0.1-3.3,0.3-4.9,0.6
51
+ c-5.2,1-9.7,3.4-13.7,6.7C9.1,9.7,7,12.3,5.2,15.1c-3.2,5-4.6,10.5-4.8,16.4C0.3,33.7,0.5,36,1,38.1c1.3,6,4,11.3,8.3,15.8
52
+ c2.3,2.4,4.9,4.4,7.8,6c1.8,1,3.7,1.9,5.8,2.3c0-0.5,0-0.8,0-1.2c0-8.5,0-17,0-25.5c0-0.7,0.1-1,0.9-1
53
+ C26.4,34.7,29.1,34.7,31.8,34.6z"/>
54
+ <linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="69.2924" y1="23.4633" x2="30.704" y2="68.5263">
55
+ <stop offset="0.1013" style="stop-color:#66449A"/>
56
+ <stop offset="0.7902" style="stop-color:#F05822"/>
57
+ </linearGradient>
58
+ <path class="st8" d="M62.3,34.6c-0.9,0.1-1.9,0-2.9,0c-0.5,0-0.7,0.2-0.8,0.7c-0.1,1.5-0.5,3-0.9,4.4c-1.6,4.9-4.1,9.1-8,12.5
59
+ c-1.8,1.6-3.6,2.9-5.7,3.9c-3,1.6-6.2,2.5-9.6,2.8c-2.3,0.2-4.5,0.1-6.9-0.2c0,1.2,0.1,2.4,0,3.6c0,0.7,0.3,1.1,0.9,1
60
+ c1,0,1.9,0.2,2.9,0.2c1.6,0,3.2-0.2,4.8-0.4c3.2-0.3,6.3-1.3,9.2-2.8c3.7-1.8,6.9-4.2,9.7-7.3c2.9-3.2,5-6.8,6.5-10.9
61
+ c0.8-2.2,1.2-4.4,1.6-6.7C63.3,35.1,63.2,34.5,62.3,34.6z"/>
62
+ </g>
63
+ </svg>
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "n8n-nodes-nvk-call-api",
3
+ "version": "0.0.1",
4
+ "description": "n8n node for NVK Browser automation API",
5
+ "keywords": [
6
+ "n8n-community-node-package",
7
+ "n8n",
8
+ "nvk",
9
+ "browser",
10
+ "automation"
11
+ ],
12
+ "license": "MIT",
13
+ "homepage": "https://github.com/yourusername/n8n-nodes-nvk-browser",
14
+ "author": {
15
+ "name": "Your Name",
16
+ "email": "your.email@example.com"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/yourusername/n8n-nodes-nvk-browser.git"
21
+ },
22
+ "main": "dist/index.js",
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "scripts": {
27
+ "build": "tsc && gulp build:icons",
28
+ "dev": "tsc --watch",
29
+ "lint": "eslint nodes --ext .ts",
30
+ "lintfix": "eslint nodes --ext .ts --fix",
31
+ "prepublishOnly": "npm run build && npm run lint"
32
+ },
33
+ "n8n": {
34
+ "n8nNodesApiVersion": 1,
35
+ "nodes": [
36
+ "dist/nodes/NvkBrowserApi/NvkBrowserApi.node.js"
37
+ ]
38
+ },
39
+ "devDependencies": {
40
+ "typescript": "~5.0.0",
41
+ "@types/node": "^18.16.0",
42
+ "@typescript-eslint/parser": "5.59.0",
43
+ "@typescript-eslint/eslint-plugin": "5.59.0",
44
+ "eslint": "^8.38.0",
45
+ "eslint-plugin-n8n-nodes-base": "^1.12.0",
46
+ "gulp": "^4.0.2",
47
+ "prettier": "^2.8.7",
48
+ "n8n-workflow": "*"
49
+ },
50
+ "peerDependencies": {
51
+ "n8n-workflow": "*"
52
+ }
53
+ }