n8n-nodes-base 2.11.0 → 2.11.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.
- package/dist/node-definitions/.nodes-hash +1 -1
- package/dist/node-definitions/nodes/n8n-nodes-base/googleAnalytics/v2/resource_report/operation_get.ts +2 -2
- package/dist/node-definitions/nodes/n8n-nodes-base/microsoftOutlook/v2/resource_event/operation_create.ts +2 -2
- package/dist/nodes/Merge/v3/actions/mode/combineBySql.d.ts +0 -27
- package/dist/nodes/Merge/v3/actions/mode/combineBySql.d.ts.map +1 -1
- package/dist/nodes/Merge/v3/actions/mode/combineBySql.js +36 -233
- package/dist/nodes/Merge/v3/actions/mode/combineBySql.js.map +1 -1
- package/dist/nodes/Merge/v3/helpers/sandbox-utils.d.ts +12 -0
- package/dist/nodes/Merge/v3/helpers/sandbox-utils.d.ts.map +1 -0
- package/dist/nodes/Merge/v3/helpers/sandbox-utils.js +69 -0
- package/dist/nodes/Merge/v3/helpers/sandbox-utils.js.map +1 -0
- package/dist/typecheck.tsbuildinfo +1 -1
- package/dist/types/nodes.json +2 -2
- package/package.json +6 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
03cf15c093d33e14fc4896b007928d377526830197a82c88d56f1137aa74270d
|
|
@@ -33,13 +33,13 @@ export type GoogleAnalyticsV2ReportGetParams = {
|
|
|
33
33
|
/**
|
|
34
34
|
* Start
|
|
35
35
|
* @displayOptions.show { dateRange: ["custom"], propertyType: ["ga4"] }
|
|
36
|
-
* @default 2026-02-
|
|
36
|
+
* @default 2026-02-24T00:00:00.000+00:00
|
|
37
37
|
*/
|
|
38
38
|
startDate?: string | Expression<string>;
|
|
39
39
|
/**
|
|
40
40
|
* End
|
|
41
41
|
* @displayOptions.show { dateRange: ["custom"], propertyType: ["ga4"] }
|
|
42
|
-
* @default 2026-03-
|
|
42
|
+
* @default 2026-03-03T00:00:00.000+00:00
|
|
43
43
|
*/
|
|
44
44
|
endDate?: string | Expression<string>;
|
|
45
45
|
/**
|
|
@@ -23,12 +23,12 @@ export type MicrosoftOutlookV2EventCreateParams = {
|
|
|
23
23
|
subject?: string | Expression<string> | PlaceholderValue;
|
|
24
24
|
/**
|
|
25
25
|
* Start
|
|
26
|
-
* @default 2026-03-
|
|
26
|
+
* @default 2026-03-04T07:08:51.741+00:00
|
|
27
27
|
*/
|
|
28
28
|
startDateTime?: string | Expression<string>;
|
|
29
29
|
/**
|
|
30
30
|
* End
|
|
31
|
-
* @default 2026-03-
|
|
31
|
+
* @default 2026-03-04T07:38:51.741+00:00
|
|
32
32
|
*/
|
|
33
33
|
endDateTime?: string | Expression<string>;
|
|
34
34
|
/**
|
|
@@ -1,30 +1,4 @@
|
|
|
1
1
|
import type { IExecuteFunctions, INodeExecutionData, INodeProperties } from 'n8n-workflow';
|
|
2
|
-
import type AlasqlType from 'alasql';
|
|
3
|
-
type AlaSQLBase = typeof AlasqlType;
|
|
4
|
-
export type AlaSQLExtended = AlaSQLBase & {
|
|
5
|
-
engines?: Record<string, unknown>;
|
|
6
|
-
into?: Record<string, unknown>;
|
|
7
|
-
utils?: Record<string, unknown>;
|
|
8
|
-
yy?: {
|
|
9
|
-
Require?: {
|
|
10
|
-
prototype?: {
|
|
11
|
-
execute?: (...args: unknown[]) => unknown;
|
|
12
|
-
};
|
|
13
|
-
};
|
|
14
|
-
[key: string]: unknown;
|
|
15
|
-
};
|
|
16
|
-
Database: AlaSQLBase['Database'] & {
|
|
17
|
-
new (databaseId: string): AlaSQLBase['Database'];
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
|
-
export declare function resetAlaSqlCache(): void;
|
|
21
|
-
export declare function disableUnsafeAccess(alasql: AlaSQLExtended): void;
|
|
22
|
-
export declare function freezeAlasql(alasql: AlaSQLExtended): void;
|
|
23
|
-
/**
|
|
24
|
-
* Lazy loads AlaSQL, disables file access, and freezes it in one go.
|
|
25
|
-
* This ensures AlaSQL is only loaded when needed and is immediately secured.
|
|
26
|
-
*/
|
|
27
|
-
export declare function loadAlaSql(): Promise<AlaSQLExtended>;
|
|
28
2
|
export declare const properties: INodeProperties[];
|
|
29
3
|
export declare const description: {
|
|
30
4
|
displayOptions: import("n8n-workflow").IDisplayOptions;
|
|
@@ -54,5 +28,4 @@ export declare const description: {
|
|
|
54
28
|
resolvableField?: boolean;
|
|
55
29
|
}[];
|
|
56
30
|
export declare function execute(this: IExecuteFunctions, inputsData: INodeExecutionData[][]): Promise<INodeExecutionData[][]>;
|
|
57
|
-
export {};
|
|
58
31
|
//# sourceMappingURL=combineBySql.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combineBySql.d.ts","sourceRoot":"","sources":["../../../../../../nodes/Merge/v3/actions/mode/combineBySql.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEX,iBAAiB,EAEjB,kBAAkB,EAClB,eAAe,EAEf,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"combineBySql.d.ts","sourceRoot":"","sources":["../../../../../../nodes/Merge/v3/actions/mode/combineBySql.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAEX,iBAAiB,EAEjB,kBAAkB,EAClB,eAAe,EAEf,MAAM,cAAc,CAAC;AAYtB,eAAO,MAAM,UAAU,EAAE,eAAe,EA+CvC,CAAC;AAQF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;GAAmD,CAAC;AAsD5E,wBAAsB,OAAO,CAC5B,IAAI,EAAE,iBAAiB,EACvB,UAAU,EAAE,kBAAkB,EAAE,EAAE,GAChC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAuGjC"}
|
|
@@ -1,43 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.description = exports.properties = void 0;
|
|
37
|
-
exports.resetAlaSqlCache = resetAlaSqlCache;
|
|
38
|
-
exports.disableUnsafeAccess = disableUnsafeAccess;
|
|
39
|
-
exports.freezeAlasql = freezeAlasql;
|
|
40
|
-
exports.loadAlaSql = loadAlaSql;
|
|
41
4
|
exports.execute = execute;
|
|
42
5
|
const di_1 = require("@n8n/di");
|
|
43
6
|
const n8n_core_1 = require("n8n-core");
|
|
@@ -45,133 +8,7 @@ const n8n_workflow_1 = require("n8n-workflow");
|
|
|
45
8
|
const utilities_1 = require("../../../../../utils/utilities");
|
|
46
9
|
const descriptions_1 = require("../../helpers/descriptions");
|
|
47
10
|
const utils_1 = require("../../helpers/utils");
|
|
48
|
-
|
|
49
|
-
let cachedAlaSql = null;
|
|
50
|
-
// Export for testing - allows resetting the cache
|
|
51
|
-
function resetAlaSqlCache() {
|
|
52
|
-
cachedAlaSql = null;
|
|
53
|
-
}
|
|
54
|
-
const disabledFunction = () => {
|
|
55
|
-
throw new Error('File access operations are disabled for security reasons');
|
|
56
|
-
};
|
|
57
|
-
function disableUnsafeAccess(alasql) {
|
|
58
|
-
// Block ALL FROM handlers that can read files or external resources
|
|
59
|
-
if (alasql.from) {
|
|
60
|
-
const fromHandlers = [
|
|
61
|
-
'FILE',
|
|
62
|
-
'JSON',
|
|
63
|
-
'JSONL',
|
|
64
|
-
'NDJSON',
|
|
65
|
-
'TXT',
|
|
66
|
-
'CSV',
|
|
67
|
-
'TAB',
|
|
68
|
-
'TSV',
|
|
69
|
-
'XLS',
|
|
70
|
-
'XLSX',
|
|
71
|
-
'ODS',
|
|
72
|
-
'XML',
|
|
73
|
-
'GEXF',
|
|
74
|
-
'HTML',
|
|
75
|
-
'TABLETOP',
|
|
76
|
-
'METEOR',
|
|
77
|
-
];
|
|
78
|
-
fromHandlers.forEach((handler) => {
|
|
79
|
-
alasql.from[handler] = disabledFunction;
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
// Block ALL INTO handlers that can write files
|
|
83
|
-
if (alasql.into) {
|
|
84
|
-
const intoHandlers = [
|
|
85
|
-
'FILE',
|
|
86
|
-
'JSON',
|
|
87
|
-
'TXT',
|
|
88
|
-
'CSV',
|
|
89
|
-
'TAB',
|
|
90
|
-
'TSV',
|
|
91
|
-
'SQL',
|
|
92
|
-
'XLS',
|
|
93
|
-
'XLSXML',
|
|
94
|
-
'XLSX',
|
|
95
|
-
'HTML',
|
|
96
|
-
];
|
|
97
|
-
const intoObj = alasql.into;
|
|
98
|
-
intoHandlers.forEach((handler) => {
|
|
99
|
-
intoObj[handler] = disabledFunction;
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
// Block ALL file-based database engines
|
|
103
|
-
if (alasql.engines) {
|
|
104
|
-
const engines = [
|
|
105
|
-
'FILE',
|
|
106
|
-
'FILESTORAGE',
|
|
107
|
-
'LOCALSTORAGE',
|
|
108
|
-
'INDEXEDDB',
|
|
109
|
-
'SQLITE',
|
|
110
|
-
'JSON',
|
|
111
|
-
'TXT',
|
|
112
|
-
'CSV',
|
|
113
|
-
'XLSX',
|
|
114
|
-
'XLS',
|
|
115
|
-
];
|
|
116
|
-
const enginesObj = alasql.engines;
|
|
117
|
-
engines.forEach((engine) => {
|
|
118
|
-
enginesObj[engine] = disabledFunction;
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
// Block file system utility functions
|
|
122
|
-
if (alasql.utils) {
|
|
123
|
-
alasql.utils.loadFile = disabledFunction;
|
|
124
|
-
alasql.utils.loadBinaryFile = disabledFunction;
|
|
125
|
-
alasql.utils.saveFile = disabledFunction;
|
|
126
|
-
alasql.utils.removeFile = disabledFunction;
|
|
127
|
-
alasql.utils.deleteFile = disabledFunction;
|
|
128
|
-
alasql.utils.fileExists = disabledFunction;
|
|
129
|
-
alasql.utils.require = disabledFunction;
|
|
130
|
-
}
|
|
131
|
-
// Block fn handlers if present
|
|
132
|
-
if (alasql.fn) {
|
|
133
|
-
const fnHandlers = ['FILE', 'JSON', 'TXT', 'CSV', 'XLSX', 'XLS', 'LOAD', 'SAVE', 'REQUIRE'];
|
|
134
|
-
fnHandlers.forEach((handler) => {
|
|
135
|
-
alasql.fn[handler] = disabledFunction;
|
|
136
|
-
});
|
|
137
|
-
alasql.fn = Object.freeze(alasql.fn);
|
|
138
|
-
}
|
|
139
|
-
if (alasql.yy) {
|
|
140
|
-
alasql.yy.JavaScript = disabledFunction;
|
|
141
|
-
}
|
|
142
|
-
// Block REQUIRE statement execution
|
|
143
|
-
// REQUIRE is a statement type (like SELECT, INSERT) that can load and execute arbitrary code
|
|
144
|
-
// We need to override yy.Require.prototype.execute before freezing
|
|
145
|
-
// The yy object contains statement constructors and is accessible via alasql.yy
|
|
146
|
-
if (alasql.yy?.Require?.prototype) {
|
|
147
|
-
alasql.yy.Require.prototype.execute = disabledFunction;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
function freezeAlasql(alasql) {
|
|
151
|
-
/*
|
|
152
|
-
* we freeze these elements of alasql to avoid users being able to create new functions as part of an execution
|
|
153
|
-
* by creating and immediately executing functions with CREATE FUNCTION or with AGGREGATE manipulation.
|
|
154
|
-
*/
|
|
155
|
-
alasql.fn = Object.freeze(alasql.fn);
|
|
156
|
-
if (alasql.yy) {
|
|
157
|
-
alasql.yy = Object.freeze(alasql.yy);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Lazy loads AlaSQL, disables file access, and freezes it in one go.
|
|
162
|
-
* This ensures AlaSQL is only loaded when needed and is immediately secured.
|
|
163
|
-
*/
|
|
164
|
-
async function loadAlaSql() {
|
|
165
|
-
if (cachedAlaSql) {
|
|
166
|
-
return cachedAlaSql;
|
|
167
|
-
}
|
|
168
|
-
const alasqlImport = await Promise.resolve().then(() => __importStar(require('alasql')));
|
|
169
|
-
const alasql = (alasqlImport.default || alasqlImport);
|
|
170
|
-
disableUnsafeAccess(alasql);
|
|
171
|
-
freezeAlasql(alasql);
|
|
172
|
-
cachedAlaSql = alasql;
|
|
173
|
-
return alasql;
|
|
174
|
-
}
|
|
11
|
+
const sandbox_utils_1 = require("../../helpers/sandbox-utils");
|
|
175
12
|
exports.properties = [
|
|
176
13
|
descriptions_1.numberInputsProperty,
|
|
177
14
|
{
|
|
@@ -240,28 +77,11 @@ const prepareError = (node, error) => {
|
|
|
240
77
|
itemIndex: 0,
|
|
241
78
|
});
|
|
242
79
|
};
|
|
243
|
-
async function executeSelectWithMappedPairedItems(node, inputsData, query, returnSuccessItemIfEmpty,
|
|
80
|
+
async function executeSelectWithMappedPairedItems(node, inputsData, query, returnSuccessItemIfEmpty, context) {
|
|
244
81
|
const returnData = [];
|
|
245
|
-
const
|
|
82
|
+
const tableData = inputsData.map((inputData) => inputData.map((entry) => ({ ...entry.json, pairedItem: entry.pairedItem })));
|
|
246
83
|
try {
|
|
247
|
-
|
|
248
|
-
const inputData = inputsData[i];
|
|
249
|
-
db.exec(`CREATE TABLE input${i + 1}`);
|
|
250
|
-
db.tables[`input${i + 1}`].data = inputData.map((entry) => ({
|
|
251
|
-
...entry.json,
|
|
252
|
-
pairedItem: entry.pairedItem,
|
|
253
|
-
}));
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
catch (error) {
|
|
257
|
-
throw new n8n_workflow_1.NodeOperationError(node, error, {
|
|
258
|
-
message: 'Issue while creating table from',
|
|
259
|
-
description: error.message,
|
|
260
|
-
itemIndex: 0,
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
try {
|
|
264
|
-
const result = db.exec((0, utils_1.modifySelectQuery)(query, inputsData.length));
|
|
84
|
+
const result = await (0, sandbox_utils_1.runAlaSqlInSandbox)(context, tableData, (0, utils_1.modifySelectQuery)(query, inputsData.length));
|
|
265
85
|
for (const item of result) {
|
|
266
86
|
if (Array.isArray(item)) {
|
|
267
87
|
returnData.push.apply(returnData, item.map(utils_1.rowToExecutionData));
|
|
@@ -277,27 +97,24 @@ async function executeSelectWithMappedPairedItems(node, inputsData, query, retur
|
|
|
277
97
|
catch (error) {
|
|
278
98
|
prepareError(node, error);
|
|
279
99
|
}
|
|
280
|
-
finally {
|
|
281
|
-
delete alasql.databases[node.id];
|
|
282
|
-
}
|
|
283
100
|
return [returnData];
|
|
284
101
|
}
|
|
285
102
|
async function execute(inputsData) {
|
|
286
|
-
// Lazy load AlaSQL, disable file access, and freeze it
|
|
287
|
-
const alasql = await loadAlaSql();
|
|
288
103
|
const node = this.getNode();
|
|
289
104
|
const returnData = [];
|
|
290
105
|
const pairedItem = [];
|
|
291
106
|
const options = this.getNodeParameter('options', 0, {});
|
|
107
|
+
const workflowId = this.getWorkflow().id;
|
|
292
108
|
let query = this.getNodeParameter('query', 0);
|
|
293
109
|
for (const resolvable of (0, utilities_1.getResolvables)(query)) {
|
|
294
110
|
query = query.replace(resolvable, this.evaluateExpression(resolvable, 0));
|
|
295
111
|
}
|
|
112
|
+
const context = await (0, sandbox_utils_1.loadAlaSqlSandbox)();
|
|
296
113
|
const isSelectQuery = node.typeVersion >= 3.1 ? query.toLowerCase().startsWith('select') : false;
|
|
297
114
|
const returnSuccessItemIfEmpty = node.typeVersion <= 3.1 ? true : options.emptyQueryResult === 'success';
|
|
298
115
|
if (isSelectQuery) {
|
|
299
116
|
try {
|
|
300
|
-
return await executeSelectWithMappedPairedItems(node, inputsData, query, returnSuccessItemIfEmpty,
|
|
117
|
+
return await executeSelectWithMappedPairedItems(node, inputsData, query, returnSuccessItemIfEmpty, context);
|
|
301
118
|
}
|
|
302
119
|
catch (error) {
|
|
303
120
|
di_1.Container.get(n8n_core_1.ErrorReporter).error(error, {
|
|
@@ -305,57 +122,46 @@ async function execute(inputsData) {
|
|
|
305
122
|
nodeName: node.name,
|
|
306
123
|
nodeType: node.type,
|
|
307
124
|
nodeVersion: node.typeVersion,
|
|
308
|
-
workflowId
|
|
125
|
+
workflowId,
|
|
309
126
|
},
|
|
310
127
|
});
|
|
311
128
|
}
|
|
312
129
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
321
|
-
if (typeof item.pairedItem === 'number') {
|
|
322
|
-
pairedItem.push({
|
|
323
|
-
item: item.pairedItem,
|
|
324
|
-
input: i,
|
|
325
|
-
});
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
if (Array.isArray(item.pairedItem)) {
|
|
329
|
-
const pairedItems = item.pairedItem
|
|
330
|
-
.filter((p) => p !== undefined)
|
|
331
|
-
.map((p) => (typeof p === 'number' ? { item: p } : p))
|
|
332
|
-
.map((p) => {
|
|
333
|
-
return {
|
|
334
|
-
item: p.item,
|
|
335
|
-
input: i,
|
|
336
|
-
};
|
|
337
|
-
});
|
|
338
|
-
pairedItem.push.apply(pairedItem, pairedItems);
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
130
|
+
for (let i = 0; i < inputsData.length; i++) {
|
|
131
|
+
const inputData = inputsData[i];
|
|
132
|
+
inputData.forEach((item, index) => {
|
|
133
|
+
if (item.pairedItem === undefined) {
|
|
134
|
+
item.pairedItem = index;
|
|
135
|
+
}
|
|
136
|
+
if (typeof item.pairedItem === 'number') {
|
|
341
137
|
pairedItem.push({
|
|
342
|
-
item: item.pairedItem
|
|
138
|
+
item: item.pairedItem,
|
|
343
139
|
input: i,
|
|
344
140
|
});
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (Array.isArray(item.pairedItem)) {
|
|
144
|
+
const pairedItems = item.pairedItem
|
|
145
|
+
.filter((p) => p !== undefined)
|
|
146
|
+
.map((p) => (typeof p === 'number' ? { item: p } : p))
|
|
147
|
+
.map((p) => {
|
|
148
|
+
return {
|
|
149
|
+
item: p.item,
|
|
150
|
+
input: i,
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
pairedItem.push.apply(pairedItem, pairedItems);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
pairedItem.push({
|
|
157
|
+
item: item.pairedItem.item,
|
|
158
|
+
input: i,
|
|
345
159
|
});
|
|
346
|
-
db.exec(`CREATE TABLE input${i + 1}`);
|
|
347
|
-
db.tables[`input${i + 1}`].data = inputData.map((entry) => entry.json);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
catch (error) {
|
|
351
|
-
throw new n8n_workflow_1.NodeOperationError(node, error, {
|
|
352
|
-
message: 'Issue while creating table from',
|
|
353
|
-
description: error.message,
|
|
354
|
-
itemIndex: 0,
|
|
355
160
|
});
|
|
356
161
|
}
|
|
162
|
+
const tableData = inputsData.map((inputData) => inputData.map((entry) => entry.json));
|
|
357
163
|
try {
|
|
358
|
-
const result =
|
|
164
|
+
const result = await (0, sandbox_utils_1.runAlaSqlInSandbox)(context, tableData, query);
|
|
359
165
|
for (const item of result) {
|
|
360
166
|
if (Array.isArray(item)) {
|
|
361
167
|
returnData.push.apply(returnData, item.map((json) => ({ json, pairedItem })));
|
|
@@ -371,9 +177,6 @@ async function execute(inputsData) {
|
|
|
371
177
|
catch (error) {
|
|
372
178
|
prepareError(node, error);
|
|
373
179
|
}
|
|
374
|
-
finally {
|
|
375
|
-
delete alasql.databases[node.id];
|
|
376
|
-
}
|
|
377
180
|
return [returnData];
|
|
378
181
|
}
|
|
379
182
|
//# sourceMappingURL=combineBySql.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combineBySql.js","sourceRoot":"","sources":["../../../../../../nodes/Merge/v3/actions/mode/combineBySql.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"combineBySql.js","sourceRoot":"","sources":["../../../../../../nodes/Merge/v3/actions/mode/combineBySql.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import ivm from 'isolated-vm';
|
|
2
|
+
import type { IDataObject } from 'n8n-workflow';
|
|
3
|
+
/** Disposes the cached isolate. Exposed for tests only. */
|
|
4
|
+
export declare function resetSandboxCache(): void;
|
|
5
|
+
/** Returns a cached isolated-vm context with alasql pre-loaded. Creates it on first call. */
|
|
6
|
+
export declare function loadAlaSqlSandbox(): Promise<ivm.Context>;
|
|
7
|
+
/**
|
|
8
|
+
* Runs a SQL query against plain-object table data inside the isolated-vm sandbox.
|
|
9
|
+
* Only JSON-serialisable values cross the isolate boundary.
|
|
10
|
+
*/
|
|
11
|
+
export declare function runAlaSqlInSandbox(context: ivm.Context, tableData: unknown[][], query: string): Promise<IDataObject[]>;
|
|
12
|
+
//# sourceMappingURL=sandbox-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-utils.d.ts","sourceRoot":"","sources":["../../../../../nodes/Merge/v3/helpers/sandbox-utils.ts"],"names":[],"mappings":"AAGA,OAAO,GAAG,MAAM,aAAa,CAAC;AAE9B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAMhD,2DAA2D;AAC3D,wBAAgB,iBAAiB,IAAI,IAAI,CAMxC;AAED,6FAA6F;AAC7F,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAe9D;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACvC,OAAO,EAAE,GAAG,CAAC,OAAO,EACpB,SAAS,EAAE,OAAO,EAAE,EAAE,EACtB,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,WAAW,EAAE,CAAC,CA4BxB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resetSandboxCache = resetSandboxCache;
|
|
7
|
+
exports.loadAlaSqlSandbox = loadAlaSqlSandbox;
|
|
8
|
+
exports.runAlaSqlInSandbox = runAlaSqlInSandbox;
|
|
9
|
+
const promises_1 = require("node:fs/promises");
|
|
10
|
+
const node_crypto_1 = require("node:crypto");
|
|
11
|
+
const isolated_vm_1 = __importDefault(require("isolated-vm"));
|
|
12
|
+
// Singleton – recreated only after resetSandboxCache() (tests) or isolate disposal.
|
|
13
|
+
let sandboxIsolate = null;
|
|
14
|
+
let sandboxContext = null;
|
|
15
|
+
/** Disposes the cached isolate. Exposed for tests only. */
|
|
16
|
+
function resetSandboxCache() {
|
|
17
|
+
sandboxContext = null;
|
|
18
|
+
if (sandboxIsolate && !sandboxIsolate.isDisposed) {
|
|
19
|
+
sandboxIsolate.dispose();
|
|
20
|
+
}
|
|
21
|
+
sandboxIsolate = null;
|
|
22
|
+
}
|
|
23
|
+
/** Returns a cached isolated-vm context with alasql pre-loaded. Creates it on first call. */
|
|
24
|
+
async function loadAlaSqlSandbox() {
|
|
25
|
+
if (sandboxContext && sandboxIsolate && !sandboxIsolate.isDisposed) {
|
|
26
|
+
return sandboxContext;
|
|
27
|
+
}
|
|
28
|
+
sandboxIsolate = new isolated_vm_1.default.Isolate({ memoryLimit: 64 }); // 64 MB hard limit
|
|
29
|
+
sandboxContext = await sandboxIsolate.createContext();
|
|
30
|
+
// Browser bundle only – no Node.js fs/require handlers inside the isolate.
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
32
|
+
const alasqlBundlePath = require.resolve('alasql/dist/alasql.min.js');
|
|
33
|
+
await sandboxContext.eval(await (0, promises_1.readFile)(alasqlBundlePath, 'utf-8'));
|
|
34
|
+
await sandboxContext.eval('Object.freeze(alasql.fn)');
|
|
35
|
+
return sandboxContext;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Runs a SQL query against plain-object table data inside the isolated-vm sandbox.
|
|
39
|
+
* Only JSON-serialisable values cross the isolate boundary.
|
|
40
|
+
*/
|
|
41
|
+
async function runAlaSqlInSandbox(context, tableData, query) {
|
|
42
|
+
// UUID per invocation so concurrent calls sharing the singleton context
|
|
43
|
+
// don't collide on alasql.databases.
|
|
44
|
+
const dbId = (0, node_crypto_1.randomUUID)();
|
|
45
|
+
// Double-serialization: outer JSON.stringify produces a JSON string, inner produces a JSON literal
|
|
46
|
+
// embedded in the script source. Inside the isolate, JSON.parse reconstructs the plain array.
|
|
47
|
+
// This ensures data enters the isolate as a parsed JSON literal, never as live objects.
|
|
48
|
+
const script = `(function() {
|
|
49
|
+
const __rows = JSON.parse(${JSON.stringify(JSON.stringify(tableData))});
|
|
50
|
+
const __db = new alasql.Database(${JSON.stringify(dbId)});
|
|
51
|
+
try {
|
|
52
|
+
for (let i = 0; i < __rows.length; i++) {
|
|
53
|
+
__db.exec('CREATE TABLE input' + (i + 1));
|
|
54
|
+
__db.tables['input' + (i + 1)].data = __rows[i];
|
|
55
|
+
}
|
|
56
|
+
return JSON.stringify(__db.exec(${JSON.stringify(query)}));
|
|
57
|
+
} finally {
|
|
58
|
+
delete alasql.databases[${JSON.stringify(dbId)}];
|
|
59
|
+
}
|
|
60
|
+
})()`;
|
|
61
|
+
const resultJson = (await context.eval(script, { timeout: 5000, copy: true }));
|
|
62
|
+
try {
|
|
63
|
+
return JSON.parse(resultJson);
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
throw new Error(`Failed to parse SQL result: ${e.message}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=sandbox-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-utils.js","sourceRoot":"","sources":["../../../../../nodes/Merge/v3/helpers/sandbox-utils.ts"],"names":[],"mappings":";;;;;AAYA,8CAMC;AAGD,8CAeC;AAMD,gDAgCC;AA1ED,+CAA4C;AAC5C,6CAAyC;AAEzC,8DAA8B;AAI9B,oFAAoF;AACpF,IAAI,cAAc,GAAuB,IAAI,CAAC;AAC9C,IAAI,cAAc,GAAuB,IAAI,CAAC;AAE9C,2DAA2D;AAC3D,SAAgB,iBAAiB;IAChC,cAAc,GAAG,IAAI,CAAC;IACtB,IAAI,cAAc,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC;QAClD,cAAc,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;IACD,cAAc,GAAG,IAAI,CAAC;AACvB,CAAC;AAED,6FAA6F;AACtF,KAAK,UAAU,iBAAiB;IACtC,IAAI,cAAc,IAAI,cAAc,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC;QACpE,OAAO,cAAc,CAAC;IACvB,CAAC;IAED,cAAc,GAAG,IAAI,qBAAG,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,mBAAmB;IAC1E,cAAc,GAAG,MAAM,cAAc,CAAC,aAAa,EAAE,CAAC;IAEtD,2EAA2E;IAC3E,iEAAiE;IACjE,MAAM,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACtE,MAAM,cAAc,CAAC,IAAI,CAAC,MAAM,IAAA,mBAAQ,EAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC;IACrE,MAAM,cAAc,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAEtD,OAAO,cAAc,CAAC;AACvB,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,kBAAkB,CACvC,OAAoB,EACpB,SAAsB,EACtB,KAAa;IAEb,wEAAwE;IACxE,qCAAqC;IACrC,MAAM,IAAI,GAAG,IAAA,wBAAU,GAAE,CAAC;IAE1B,mGAAmG;IACnG,8FAA8F;IAC9F,wFAAwF;IACxF,MAAM,MAAM,GAAG;8BACc,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;qCAClC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;;;;;;qCAMpB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;;6BAE7B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;;MAE3C,CAAC;IAEN,MAAM,UAAU,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAW,CAAC;IACzF,IAAI,CAAC;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAkB,CAAC;IAChD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,+BAAgC,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IACxE,CAAC;AACF,CAAC"}
|