@dartfx/n8n-nodes-qsv 0.26.0-staging.0 → 0.26.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.
Files changed (26) hide show
  1. package/README.md +4 -0
  2. package/package.json +3 -2
  3. package/dist/nodes/Qsv/actions/executeClean.d.ts +0 -2
  4. package/dist/nodes/Qsv/actions/executeClean.js +0 -147
  5. package/dist/nodes/Qsv/actions/executeClipboard.d.ts +0 -2
  6. package/dist/nodes/Qsv/actions/executeClipboard.js +0 -114
  7. package/dist/nodes/Qsv/actions/executeColor.d.ts +0 -2
  8. package/dist/nodes/Qsv/actions/executeColor.js +0 -126
  9. package/dist/nodes/Qsv/actions/executeLens.d.ts +0 -2
  10. package/dist/nodes/Qsv/actions/executeLens.js +0 -156
  11. package/dist/nodes/Qsv/actions/executeLog.d.ts +0 -2
  12. package/dist/nodes/Qsv/actions/executeLog.js +0 -111
  13. package/dist/nodes/Qsv/actions/executePrompt.d.ts +0 -2
  14. package/dist/nodes/Qsv/actions/executePrompt.js +0 -132
  15. package/dist/nodes/Qsv/descriptions/CleanDescription.d.ts +0 -2
  16. package/dist/nodes/Qsv/descriptions/CleanDescription.js +0 -140
  17. package/dist/nodes/Qsv/descriptions/ClipboardDescription.d.ts +0 -2
  18. package/dist/nodes/Qsv/descriptions/ClipboardDescription.js +0 -63
  19. package/dist/nodes/Qsv/descriptions/ColorDescription.d.ts +0 -2
  20. package/dist/nodes/Qsv/descriptions/ColorDescription.js +0 -91
  21. package/dist/nodes/Qsv/descriptions/LensDescription.d.ts +0 -2
  22. package/dist/nodes/Qsv/descriptions/LensDescription.js +0 -161
  23. package/dist/nodes/Qsv/descriptions/LogDescription.d.ts +0 -2
  24. package/dist/nodes/Qsv/descriptions/LogDescription.js +0 -55
  25. package/dist/nodes/Qsv/descriptions/PromptDescription.d.ts +0 -2
  26. package/dist/nodes/Qsv/descriptions/PromptDescription.js +0 -105
package/README.md CHANGED
@@ -201,6 +201,10 @@ pnpm install
201
201
  # Regenerate QSV node definitions from latest CLI help (if updating QSV commands)
202
202
  pnpm run generate:qsv
203
203
 
204
+ # Or synchronize, test, and release against new QSV builds (with optional --otp):
205
+ pnpm run sync:qsv --dry-run
206
+ pnpm run sync:qsv --staging --publish --otp 123456
207
+
204
208
  # Build package
205
209
  pnpm run build
206
210
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dartfx/n8n-nodes-qsv",
3
- "version": "0.26.0-staging.0",
3
+ "version": "0.26.0",
4
4
  "description": "n8n community node for datHere QSV ultra-fast tabular data wrangling, stats, and transformations (requires 'qsv' CLI on host)",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",
@@ -62,7 +62,8 @@
62
62
  "sync:qsv": "tsx scripts/sync-qsv-release.ts --local --align-minor",
63
63
  "sync:qsv:upstream": "tsx scripts/sync-qsv-release.ts --align-minor",
64
64
  "sync:qsv:check": "tsx scripts/sync-qsv-release.ts --check-only",
65
- "release:qsv": "tsx scripts/sync-qsv-release.ts --local --align-minor --publish",
65
+ "release:staging": "tsx scripts/sync-qsv-release.ts --local --align-minor --staging --publish",
66
+ "release:prod": "tsx scripts/sync-qsv-release.ts --local --align-minor --git-tag --push",
66
67
  "format": "prettier --write \"**/*.{ts,js,json,md}\"",
67
68
  "lint": "eslint \"**/*.ts\"",
68
69
  "test": "jest --passWithNoTests",
@@ -1,2 +0,0 @@
1
- import type { IExecuteFunctions, INodeExecutionData } from "n8n-workflow";
2
- export declare function executeClean(this: IExecuteFunctions, itemIndex: number): Promise<INodeExecutionData[]>;
@@ -1,147 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.executeClean = executeClean;
4
- const n8n_workflow_1 = require("n8n-workflow");
5
- const child_process_1 = require("child_process");
6
- const util_1 = require("util");
7
- const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
8
- async function executeClean(itemIndex) {
9
- const inputPath = this.getNodeParameter("inputPath", itemIndex);
10
- if (!inputPath || !inputPath.trim()) {
11
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), "Input CSV file path is required.", { itemIndex });
12
- }
13
- const outputPath = this.getNodeParameter("outputPath", itemIndex, "") || "";
14
- const additionalArgs = this.getNodeParameter("additionalArgs", itemIndex, "") || "";
15
- const options = this.getNodeParameter("options", itemIndex, {}) || {};
16
- const args = ["clean"];
17
- if (options.stale === true) {
18
- args.push("--stale");
19
- }
20
- if (options.recursive === true) {
21
- args.push("--recursive");
22
- }
23
- if (options.dryRun === true) {
24
- args.push("--dry-run");
25
- }
26
- if (options.force === true) {
27
- args.push("--force");
28
- }
29
- if (options.index === true) {
30
- args.push("--index");
31
- }
32
- if (options.stats === true) {
33
- args.push("--stats");
34
- }
35
- if (options.frequency === true) {
36
- args.push("--frequency");
37
- }
38
- if (options.schema === true) {
39
- args.push("--schema");
40
- }
41
- if (options.validate === true) {
42
- args.push("--validate");
43
- }
44
- if (options.moarstats === true) {
45
- args.push("--moarstats");
46
- }
47
- if (options.all === true) {
48
- args.push("--all");
49
- }
50
- if (options.quiet === true) {
51
- args.push("--quiet");
52
- }
53
- if (additionalArgs.trim()) {
54
- const rawMatches = additionalArgs.match(/[^\s"']+|"[^"]*"|'[^']*'/g) || [];
55
- const parsedArgs = rawMatches.map((arg) => {
56
- if ((arg.startsWith('"') && arg.endsWith('"')) ||
57
- (arg.startsWith("'") && arg.endsWith("'"))) {
58
- return arg.slice(1, -1);
59
- }
60
- return arg;
61
- });
62
- args.push(...parsedArgs);
63
- }
64
- if (outputPath.trim()) {
65
- args.push("--output", outputPath.trim());
66
- }
67
- args.push(inputPath);
68
- const qsvBin = process.env.DARTFX_QSV_BIN_PATH ||
69
- process.env.QSV_BIN_PATH ||
70
- process.env.QSV_PATH ||
71
- "qsv";
72
- try {
73
- const { stdout, stderr } = await execFileAsync(qsvBin, args, {
74
- maxBuffer: 50 * 1024 * 1024,
75
- encoding: "utf8",
76
- });
77
- let resultJson;
78
- try {
79
- resultJson = JSON.parse(stdout);
80
- }
81
- catch {
82
- resultJson = {
83
- command: "qsv clean",
84
- inputPath,
85
- rawOutput: stdout,
86
- };
87
- }
88
- const returnJson = {
89
- success: true,
90
- command: "clean",
91
- inputPath,
92
- result: resultJson,
93
- };
94
- if (outputPath.trim()) {
95
- returnJson.outputPath = outputPath.trim();
96
- }
97
- if (stderr && stderr.trim()) {
98
- returnJson.warnings = stderr.trim();
99
- }
100
- return [
101
- {
102
- json: returnJson,
103
- },
104
- ];
105
- }
106
- catch (error) {
107
- if (error.code === "ENOENT") {
108
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The QSV CLI binary ('${qsvBin}') was not found`, {
109
- itemIndex,
110
- description: `Please ensure 'qsv' is installed and available in the system PATH where n8n is running, or specify its absolute path via the DARTFX_QSV_BIN_PATH environment variable. (https://github.com/dathere/qsv)`,
111
- });
112
- }
113
- if (error.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER" ||
114
- (error.message && error.message.includes("maxBuffer"))) {
115
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `QSV execution exceeded maximum stdout buffer (50 MB)`, {
116
- itemIndex,
117
- description: `qsv clean returned more data than could fit into memory. Specify an 'Output File Path' to stream results directly to disk instead.`,
118
- });
119
- }
120
- const rawError = (error.stderr || error.message || "").trim();
121
- if (rawError.includes("is not a qsv command") ||
122
- rawError.includes("unrecognized subcommand") ||
123
- rawError.includes("not available in this")) {
124
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Operation 'clean' is not available in the installed QSV binary`, {
125
- itemIndex,
126
- description: `The installed QSV binary at '${qsvBin}' does not include the 'clean' feature. This feature may require a full feature build of QSV (e.g. qsv with all_features or a prebuilt binary with feature flags enabled). See https://github.com/dathere/qsv#feature-flags`,
127
- });
128
- }
129
- if (rawError.includes("No such file or directory") ||
130
- rawError.includes("os error 2")) {
131
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Input file not found: '${inputPath}'`, {
132
- itemIndex,
133
- description: `qsv clean could not find the file at '${inputPath}'. Check for typos, or if n8n is running in Docker, ensure the host directory is mounted into the container.`,
134
- });
135
- }
136
- if (rawError.includes("Operation not permitted") ||
137
- rawError.includes("os error 1") ||
138
- rawError.includes("Permission denied") ||
139
- rawError.includes("os error 13")) {
140
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Permission denied accessing file: '${inputPath}'`, {
141
- itemIndex,
142
- description: `qsv clean was denied read access to '${inputPath}'. On macOS, check Full Disk Access or Removable Volumes permissions for the application running n8n.`,
143
- });
144
- }
145
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed executing 'qsv clean': ${rawError}`, { itemIndex });
146
- }
147
- }
@@ -1,2 +0,0 @@
1
- import type { IExecuteFunctions, INodeExecutionData } from "n8n-workflow";
2
- export declare function executeClipboard(this: IExecuteFunctions, itemIndex: number): Promise<INodeExecutionData[]>;
@@ -1,114 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.executeClipboard = executeClipboard;
4
- const n8n_workflow_1 = require("n8n-workflow");
5
- const child_process_1 = require("child_process");
6
- const util_1 = require("util");
7
- const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
8
- async function executeClipboard(itemIndex) {
9
- const inputPath = this.getNodeParameter("inputPath", itemIndex);
10
- if (!inputPath || !inputPath.trim()) {
11
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), "Input CSV file path is required.", { itemIndex });
12
- }
13
- const outputPath = this.getNodeParameter("outputPath", itemIndex, "") || "";
14
- const additionalArgs = this.getNodeParameter("additionalArgs", itemIndex, "") || "";
15
- const options = this.getNodeParameter("options", itemIndex, {}) || {};
16
- const args = ["clipboard"];
17
- if (options.save === true) {
18
- args.push("--save");
19
- }
20
- if (additionalArgs.trim()) {
21
- const rawMatches = additionalArgs.match(/[^\s"']+|"[^"]*"|'[^']*'/g) || [];
22
- const parsedArgs = rawMatches.map((arg) => {
23
- if ((arg.startsWith('"') && arg.endsWith('"')) ||
24
- (arg.startsWith("'") && arg.endsWith("'"))) {
25
- return arg.slice(1, -1);
26
- }
27
- return arg;
28
- });
29
- args.push(...parsedArgs);
30
- }
31
- if (outputPath.trim()) {
32
- args.push("--output", outputPath.trim());
33
- }
34
- args.push(inputPath);
35
- const qsvBin = process.env.DARTFX_QSV_BIN_PATH ||
36
- process.env.QSV_BIN_PATH ||
37
- process.env.QSV_PATH ||
38
- "qsv";
39
- try {
40
- const { stdout, stderr } = await execFileAsync(qsvBin, args, {
41
- maxBuffer: 50 * 1024 * 1024,
42
- encoding: "utf8",
43
- });
44
- let resultJson;
45
- try {
46
- resultJson = JSON.parse(stdout);
47
- }
48
- catch {
49
- resultJson = {
50
- command: "qsv clipboard",
51
- inputPath,
52
- rawOutput: stdout,
53
- };
54
- }
55
- const returnJson = {
56
- success: true,
57
- command: "clipboard",
58
- inputPath,
59
- result: resultJson,
60
- };
61
- if (outputPath.trim()) {
62
- returnJson.outputPath = outputPath.trim();
63
- }
64
- if (stderr && stderr.trim()) {
65
- returnJson.warnings = stderr.trim();
66
- }
67
- return [
68
- {
69
- json: returnJson,
70
- },
71
- ];
72
- }
73
- catch (error) {
74
- if (error.code === "ENOENT") {
75
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The QSV CLI binary ('${qsvBin}') was not found`, {
76
- itemIndex,
77
- description: `Please ensure 'qsv' is installed and available in the system PATH where n8n is running, or specify its absolute path via the DARTFX_QSV_BIN_PATH environment variable. (https://github.com/dathere/qsv)`,
78
- });
79
- }
80
- if (error.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER" ||
81
- (error.message && error.message.includes("maxBuffer"))) {
82
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `QSV execution exceeded maximum stdout buffer (50 MB)`, {
83
- itemIndex,
84
- description: `qsv clipboard returned more data than could fit into memory. Specify an 'Output File Path' to stream results directly to disk instead.`,
85
- });
86
- }
87
- const rawError = (error.stderr || error.message || "").trim();
88
- if (rawError.includes("is not a qsv command") ||
89
- rawError.includes("unrecognized subcommand") ||
90
- rawError.includes("not available in this")) {
91
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Operation 'clipboard' is not available in the installed QSV binary`, {
92
- itemIndex,
93
- description: `The installed QSV binary at '${qsvBin}' does not include the 'clipboard' feature. This feature may require a full feature build of QSV (e.g. qsv with all_features or a prebuilt binary with feature flags enabled). See https://github.com/dathere/qsv#feature-flags`,
94
- });
95
- }
96
- if (rawError.includes("No such file or directory") ||
97
- rawError.includes("os error 2")) {
98
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Input file not found: '${inputPath}'`, {
99
- itemIndex,
100
- description: `qsv clipboard could not find the file at '${inputPath}'. Check for typos, or if n8n is running in Docker, ensure the host directory is mounted into the container.`,
101
- });
102
- }
103
- if (rawError.includes("Operation not permitted") ||
104
- rawError.includes("os error 1") ||
105
- rawError.includes("Permission denied") ||
106
- rawError.includes("os error 13")) {
107
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Permission denied accessing file: '${inputPath}'`, {
108
- itemIndex,
109
- description: `qsv clipboard was denied read access to '${inputPath}'. On macOS, check Full Disk Access or Removable Volumes permissions for the application running n8n.`,
110
- });
111
- }
112
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed executing 'qsv clipboard': ${rawError}`, { itemIndex });
113
- }
114
- }
@@ -1,2 +0,0 @@
1
- import type { IExecuteFunctions, INodeExecutionData } from "n8n-workflow";
2
- export declare function executeColor(this: IExecuteFunctions, itemIndex: number): Promise<INodeExecutionData[]>;
@@ -1,126 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.executeColor = executeColor;
4
- const n8n_workflow_1 = require("n8n-workflow");
5
- const child_process_1 = require("child_process");
6
- const util_1 = require("util");
7
- const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
8
- async function executeColor(itemIndex) {
9
- const inputPath = this.getNodeParameter("inputPath", itemIndex);
10
- if (!inputPath || !inputPath.trim()) {
11
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), "Input CSV file path is required.", { itemIndex });
12
- }
13
- const outputPath = this.getNodeParameter("outputPath", itemIndex, "") || "";
14
- const additionalArgs = this.getNodeParameter("additionalArgs", itemIndex, "") || "";
15
- const options = this.getNodeParameter("options", itemIndex, {}) || {};
16
- const args = ["color"];
17
- if (options.color === true) {
18
- args.push("--color");
19
- }
20
- if (options.rowNumbers === true) {
21
- args.push("--row-numbers");
22
- }
23
- if (options.title !== undefined && options.title !== "") {
24
- args.push("--title", String(options.title));
25
- }
26
- if (options.delimiter !== undefined && options.delimiter !== "") {
27
- args.push("--delimiter", String(options.delimiter));
28
- }
29
- if (options.memcheck === true) {
30
- args.push("--memcheck");
31
- }
32
- if (additionalArgs.trim()) {
33
- const rawMatches = additionalArgs.match(/[^\s"']+|"[^"]*"|'[^']*'/g) || [];
34
- const parsedArgs = rawMatches.map((arg) => {
35
- if ((arg.startsWith('"') && arg.endsWith('"')) ||
36
- (arg.startsWith("'") && arg.endsWith("'"))) {
37
- return arg.slice(1, -1);
38
- }
39
- return arg;
40
- });
41
- args.push(...parsedArgs);
42
- }
43
- if (outputPath.trim()) {
44
- args.push("--output", outputPath.trim());
45
- }
46
- args.push(inputPath);
47
- const qsvBin = process.env.DARTFX_QSV_BIN_PATH ||
48
- process.env.QSV_BIN_PATH ||
49
- process.env.QSV_PATH ||
50
- "qsv";
51
- try {
52
- const { stdout, stderr } = await execFileAsync(qsvBin, args, {
53
- maxBuffer: 50 * 1024 * 1024,
54
- encoding: "utf8",
55
- });
56
- let resultJson;
57
- try {
58
- resultJson = JSON.parse(stdout);
59
- }
60
- catch {
61
- resultJson = {
62
- command: "qsv color",
63
- inputPath,
64
- rawOutput: stdout,
65
- };
66
- }
67
- const returnJson = {
68
- success: true,
69
- command: "color",
70
- inputPath,
71
- result: resultJson,
72
- };
73
- if (outputPath.trim()) {
74
- returnJson.outputPath = outputPath.trim();
75
- }
76
- if (stderr && stderr.trim()) {
77
- returnJson.warnings = stderr.trim();
78
- }
79
- return [
80
- {
81
- json: returnJson,
82
- },
83
- ];
84
- }
85
- catch (error) {
86
- if (error.code === "ENOENT") {
87
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The QSV CLI binary ('${qsvBin}') was not found`, {
88
- itemIndex,
89
- description: `Please ensure 'qsv' is installed and available in the system PATH where n8n is running, or specify its absolute path via the DARTFX_QSV_BIN_PATH environment variable. (https://github.com/dathere/qsv)`,
90
- });
91
- }
92
- if (error.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER" ||
93
- (error.message && error.message.includes("maxBuffer"))) {
94
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `QSV execution exceeded maximum stdout buffer (50 MB)`, {
95
- itemIndex,
96
- description: `qsv color returned more data than could fit into memory. Specify an 'Output File Path' to stream results directly to disk instead.`,
97
- });
98
- }
99
- const rawError = (error.stderr || error.message || "").trim();
100
- if (rawError.includes("is not a qsv command") ||
101
- rawError.includes("unrecognized subcommand") ||
102
- rawError.includes("not available in this")) {
103
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Operation 'color' is not available in the installed QSV binary`, {
104
- itemIndex,
105
- description: `The installed QSV binary at '${qsvBin}' does not include the 'color' feature. This feature may require a full feature build of QSV (e.g. qsv with all_features or a prebuilt binary with feature flags enabled). See https://github.com/dathere/qsv#feature-flags`,
106
- });
107
- }
108
- if (rawError.includes("No such file or directory") ||
109
- rawError.includes("os error 2")) {
110
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Input file not found: '${inputPath}'`, {
111
- itemIndex,
112
- description: `qsv color could not find the file at '${inputPath}'. Check for typos, or if n8n is running in Docker, ensure the host directory is mounted into the container.`,
113
- });
114
- }
115
- if (rawError.includes("Operation not permitted") ||
116
- rawError.includes("os error 1") ||
117
- rawError.includes("Permission denied") ||
118
- rawError.includes("os error 13")) {
119
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Permission denied accessing file: '${inputPath}'`, {
120
- itemIndex,
121
- description: `qsv color was denied read access to '${inputPath}'. On macOS, check Full Disk Access or Removable Volumes permissions for the application running n8n.`,
122
- });
123
- }
124
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed executing 'qsv color': ${rawError}`, { itemIndex });
125
- }
126
- }
@@ -1,2 +0,0 @@
1
- import type { IExecuteFunctions, INodeExecutionData } from "n8n-workflow";
2
- export declare function executeLens(this: IExecuteFunctions, itemIndex: number): Promise<INodeExecutionData[]>;
@@ -1,156 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.executeLens = executeLens;
4
- const n8n_workflow_1 = require("n8n-workflow");
5
- const child_process_1 = require("child_process");
6
- const util_1 = require("util");
7
- const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
8
- async function executeLens(itemIndex) {
9
- const inputPath = this.getNodeParameter("inputPath", itemIndex);
10
- if (!inputPath || !inputPath.trim()) {
11
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), "Input CSV file path is required.", { itemIndex });
12
- }
13
- const outputPath = this.getNodeParameter("outputPath", itemIndex, "") || "";
14
- const additionalArgs = this.getNodeParameter("additionalArgs", itemIndex, "") || "";
15
- const options = this.getNodeParameter("options", itemIndex, {}) || {};
16
- const args = ["lens"];
17
- if (options.delimiter !== undefined && options.delimiter !== "") {
18
- args.push("--delimiter", String(options.delimiter));
19
- }
20
- if (options.tabSeparated === true) {
21
- args.push("--tab-separated");
22
- }
23
- if (options.noHeaders === true) {
24
- args.push("--no-headers");
25
- }
26
- if (options.columns !== undefined && options.columns !== "") {
27
- args.push("--columns", String(options.columns));
28
- }
29
- if (options.filter !== undefined && options.filter !== "") {
30
- args.push("--filter", String(options.filter));
31
- }
32
- if (options.find !== undefined && options.find !== "") {
33
- args.push("--find", String(options.find));
34
- }
35
- if (options.ignoreCase === true) {
36
- args.push("--ignore-case");
37
- }
38
- if (options.freezeColumns !== undefined && options.freezeColumns !== "") {
39
- args.push("--freeze-columns", String(options.freezeColumns));
40
- }
41
- if (options.monochrome === true) {
42
- args.push("--monochrome");
43
- }
44
- if (options.wrapMode !== undefined && options.wrapMode !== "") {
45
- args.push("--wrap-mode", String(options.wrapMode));
46
- }
47
- if (options.autoReload === true) {
48
- args.push("--auto-reload");
49
- }
50
- if (options.streamingStdin === true) {
51
- args.push("--streaming-stdin");
52
- }
53
- if (options.prompt !== undefined && options.prompt !== "") {
54
- args.push("--prompt", String(options.prompt));
55
- }
56
- if (options.echoColumn !== undefined && options.echoColumn !== "") {
57
- args.push("--echo-column", String(options.echoColumn));
58
- }
59
- if (options.debug === true) {
60
- args.push("--debug");
61
- }
62
- if (additionalArgs.trim()) {
63
- const rawMatches = additionalArgs.match(/[^\s"']+|"[^"]*"|'[^']*'/g) || [];
64
- const parsedArgs = rawMatches.map((arg) => {
65
- if ((arg.startsWith('"') && arg.endsWith('"')) ||
66
- (arg.startsWith("'") && arg.endsWith("'"))) {
67
- return arg.slice(1, -1);
68
- }
69
- return arg;
70
- });
71
- args.push(...parsedArgs);
72
- }
73
- if (outputPath.trim()) {
74
- args.push("--output", outputPath.trim());
75
- }
76
- args.push(inputPath);
77
- const qsvBin = process.env.DARTFX_QSV_BIN_PATH ||
78
- process.env.QSV_BIN_PATH ||
79
- process.env.QSV_PATH ||
80
- "qsv";
81
- try {
82
- const { stdout, stderr } = await execFileAsync(qsvBin, args, {
83
- maxBuffer: 50 * 1024 * 1024,
84
- encoding: "utf8",
85
- });
86
- let resultJson;
87
- try {
88
- resultJson = JSON.parse(stdout);
89
- }
90
- catch {
91
- resultJson = {
92
- command: "qsv lens",
93
- inputPath,
94
- rawOutput: stdout,
95
- };
96
- }
97
- const returnJson = {
98
- success: true,
99
- command: "lens",
100
- inputPath,
101
- result: resultJson,
102
- };
103
- if (outputPath.trim()) {
104
- returnJson.outputPath = outputPath.trim();
105
- }
106
- if (stderr && stderr.trim()) {
107
- returnJson.warnings = stderr.trim();
108
- }
109
- return [
110
- {
111
- json: returnJson,
112
- },
113
- ];
114
- }
115
- catch (error) {
116
- if (error.code === "ENOENT") {
117
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The QSV CLI binary ('${qsvBin}') was not found`, {
118
- itemIndex,
119
- description: `Please ensure 'qsv' is installed and available in the system PATH where n8n is running, or specify its absolute path via the DARTFX_QSV_BIN_PATH environment variable. (https://github.com/dathere/qsv)`,
120
- });
121
- }
122
- if (error.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER" ||
123
- (error.message && error.message.includes("maxBuffer"))) {
124
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `QSV execution exceeded maximum stdout buffer (50 MB)`, {
125
- itemIndex,
126
- description: `qsv lens returned more data than could fit into memory. Specify an 'Output File Path' to stream results directly to disk instead.`,
127
- });
128
- }
129
- const rawError = (error.stderr || error.message || "").trim();
130
- if (rawError.includes("is not a qsv command") ||
131
- rawError.includes("unrecognized subcommand") ||
132
- rawError.includes("not available in this")) {
133
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Operation 'lens' is not available in the installed QSV binary`, {
134
- itemIndex,
135
- description: `The installed QSV binary at '${qsvBin}' does not include the 'lens' feature. This feature may require a full feature build of QSV (e.g. qsv with all_features or a prebuilt binary with feature flags enabled). See https://github.com/dathere/qsv#feature-flags`,
136
- });
137
- }
138
- if (rawError.includes("No such file or directory") ||
139
- rawError.includes("os error 2")) {
140
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Input file not found: '${inputPath}'`, {
141
- itemIndex,
142
- description: `qsv lens could not find the file at '${inputPath}'. Check for typos, or if n8n is running in Docker, ensure the host directory is mounted into the container.`,
143
- });
144
- }
145
- if (rawError.includes("Operation not permitted") ||
146
- rawError.includes("os error 1") ||
147
- rawError.includes("Permission denied") ||
148
- rawError.includes("os error 13")) {
149
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Permission denied accessing file: '${inputPath}'`, {
150
- itemIndex,
151
- description: `qsv lens was denied read access to '${inputPath}'. On macOS, check Full Disk Access or Removable Volumes permissions for the application running n8n.`,
152
- });
153
- }
154
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Failed executing 'qsv lens': ${rawError}`, { itemIndex });
155
- }
156
- }
@@ -1,2 +0,0 @@
1
- import type { IExecuteFunctions, INodeExecutionData } from "n8n-workflow";
2
- export declare function executeLog(this: IExecuteFunctions, itemIndex: number): Promise<INodeExecutionData[]>;