n8n-nodes-daytona-tool 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/README.md +34 -0
- package/dist/credentials/DaytonaApi.credentials.d.ts +7 -0
- package/dist/credentials/DaytonaApi.credentials.js +30 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +17 -0
- package/dist/lib/daytonaClient.d.ts +19 -0
- package/dist/lib/daytonaClient.js +95 -0
- package/dist/nodes/Daytona/CreateSandbox.node.d.ts +5 -0
- package/dist/nodes/Daytona/CreateSandbox.node.js +81 -0
- package/dist/nodes/Daytona/DisposeSandbox.node.d.ts +5 -0
- package/dist/nodes/Daytona/DisposeSandbox.node.js +58 -0
- package/dist/nodes/Daytona/RunCode.node.d.ts +5 -0
- package/dist/nodes/Daytona/RunCode.node.js +82 -0
- package/dist/nodes/Daytona/StartSandbox.node.d.ts +5 -0
- package/dist/nodes/Daytona/StartSandbox.node.js +81 -0
- package/dist/nodes/Daytona/StopSandbox.node.d.ts +5 -0
- package/dist/nodes/Daytona/StopSandbox.node.js +81 -0
- package/dist/nodes/nodes/Daytona/Daytona.node.json +20 -0
- package/dist/nodes/nodes/Daytona/DisposeSandbox.node.json +20 -0
- package/dist/nodes/nodes/Daytona/RunCode.node.json +20 -0
- package/dist/nodes/nodes/Daytona/StartSandbox.node.json +20 -0
- package/dist/nodes/nodes/Daytona/StopSandbox.node.json +20 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# n8n Daytona Agent Nodes
|
|
2
|
+
|
|
3
|
+
Programmatic n8n community nodes for managing Daytona sandboxes and running Node.js code in them.
|
|
4
|
+
|
|
5
|
+
## Nodes
|
|
6
|
+
|
|
7
|
+
- Daytona Create Sandbox
|
|
8
|
+
- Daytona Run Code
|
|
9
|
+
- Daytona Dispose Sandbox
|
|
10
|
+
- Daytona Start Sandbox
|
|
11
|
+
- Daytona Stop Sandbox
|
|
12
|
+
|
|
13
|
+
## Credentials
|
|
14
|
+
|
|
15
|
+
Create a `Daytona API` credential with:
|
|
16
|
+
|
|
17
|
+
- Base URL (default `https://app.daytona.io`)
|
|
18
|
+
- Bearer Token
|
|
19
|
+
|
|
20
|
+
## Local build/test (optional)
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install
|
|
24
|
+
npm run build
|
|
25
|
+
npm link
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Then in your local n8n custom extensions directory:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm link n8n-nodes-daytona-tool
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Start n8n and search for "Daytona".
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DaytonaApi = void 0;
|
|
4
|
+
class DaytonaApi {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.name = 'daytonaApi';
|
|
7
|
+
this.displayName = 'Daytona API';
|
|
8
|
+
this.documentationUrl = 'https://www.daytona.io/docs/en/typescript-sdk/';
|
|
9
|
+
this.properties = [
|
|
10
|
+
{
|
|
11
|
+
displayName: 'Base URL',
|
|
12
|
+
name: 'baseUrl',
|
|
13
|
+
type: 'string',
|
|
14
|
+
default: 'https://app.daytona.io',
|
|
15
|
+
placeholder: 'https://app.daytona.io',
|
|
16
|
+
description: 'Daytona API base URL.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
displayName: 'Bearer Token',
|
|
20
|
+
name: 'token',
|
|
21
|
+
type: 'string',
|
|
22
|
+
default: '',
|
|
23
|
+
typeOptions: {
|
|
24
|
+
password: true,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.DaytonaApi = DaytonaApi;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.nodes = exports.credentials = void 0;
|
|
4
|
+
const DaytonaApi_credentials_1 = require("./credentials/DaytonaApi.credentials");
|
|
5
|
+
const CreateSandbox_node_1 = require("./nodes/Daytona/CreateSandbox.node");
|
|
6
|
+
const DisposeSandbox_node_1 = require("./nodes/Daytona/DisposeSandbox.node");
|
|
7
|
+
const RunCode_node_1 = require("./nodes/Daytona/RunCode.node");
|
|
8
|
+
const StartSandbox_node_1 = require("./nodes/Daytona/StartSandbox.node");
|
|
9
|
+
const StopSandbox_node_1 = require("./nodes/Daytona/StopSandbox.node");
|
|
10
|
+
exports.credentials = [new DaytonaApi_credentials_1.DaytonaApi()];
|
|
11
|
+
exports.nodes = [
|
|
12
|
+
new CreateSandbox_node_1.DaytonaCreateSandbox(),
|
|
13
|
+
new RunCode_node_1.DaytonaRunCode(),
|
|
14
|
+
new DisposeSandbox_node_1.DaytonaDisposeSandbox(),
|
|
15
|
+
new StartSandbox_node_1.DaytonaStartSandbox(),
|
|
16
|
+
new StopSandbox_node_1.DaytonaStopSandbox(),
|
|
17
|
+
];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Daytona } from '@daytonaio/sdk';
|
|
2
|
+
type DaytonaConfig = {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
token: string;
|
|
5
|
+
};
|
|
6
|
+
type SandboxCreateInput = {
|
|
7
|
+
name?: string;
|
|
8
|
+
sessionId?: string;
|
|
9
|
+
runtime?: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const createDaytonaClient: (config: DaytonaConfig) => Daytona;
|
|
12
|
+
export declare const createSandbox: (client: any, input: SandboxCreateInput) => Promise<any>;
|
|
13
|
+
export declare const getSandbox: (client: any, sandboxId: string) => Promise<any>;
|
|
14
|
+
export declare const getSandboxByName: (client: any, name: string) => Promise<any>;
|
|
15
|
+
export declare const runNodeCode: (sandbox: any, code: string, timeoutMs?: number) => Promise<any>;
|
|
16
|
+
export declare const disposeSandbox: (sandbox: any) => Promise<any>;
|
|
17
|
+
export declare const startSandbox: (sandbox: any) => Promise<any>;
|
|
18
|
+
export declare const stopSandbox: (sandbox: any) => Promise<any>;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.stopSandbox = exports.startSandbox = exports.disposeSandbox = exports.runNodeCode = exports.getSandboxByName = exports.getSandbox = exports.createSandbox = exports.createDaytonaClient = void 0;
|
|
4
|
+
const sdk_1 = require("@daytonaio/sdk");
|
|
5
|
+
const getCreateFn = (client) => { var _a, _b; return (_a = client === null || client === void 0 ? void 0 : client.create) !== null && _a !== void 0 ? _a : (_b = client === null || client === void 0 ? void 0 : client.sandbox) === null || _b === void 0 ? void 0 : _b.create; };
|
|
6
|
+
const getFetchFn = (client) => { var _a, _b, _c, _d; return (_c = (_a = client === null || client === void 0 ? void 0 : client.get) !== null && _a !== void 0 ? _a : (_b = client === null || client === void 0 ? void 0 : client.sandbox) === null || _b === void 0 ? void 0 : _b.get) !== null && _c !== void 0 ? _c : (_d = client === null || client === void 0 ? void 0 : client.sandbox) === null || _d === void 0 ? void 0 : _d.connect; };
|
|
7
|
+
const getDisposeFn = (sandbox) => { var _a, _b; return (_b = (_a = sandbox === null || sandbox === void 0 ? void 0 : sandbox.dispose) !== null && _a !== void 0 ? _a : sandbox === null || sandbox === void 0 ? void 0 : sandbox.destroy) !== null && _b !== void 0 ? _b : sandbox === null || sandbox === void 0 ? void 0 : sandbox.remove; };
|
|
8
|
+
const getListFn = (client) => { var _a, _b, _c, _d; return (_c = (_a = client === null || client === void 0 ? void 0 : client.list) !== null && _a !== void 0 ? _a : (_b = client === null || client === void 0 ? void 0 : client.sandbox) === null || _b === void 0 ? void 0 : _b.list) !== null && _c !== void 0 ? _c : (_d = client === null || client === void 0 ? void 0 : client.sandboxes) === null || _d === void 0 ? void 0 : _d.list; };
|
|
9
|
+
const getStartFn = (sandbox) => { var _a, _b; return (_b = (_a = sandbox === null || sandbox === void 0 ? void 0 : sandbox.start) !== null && _a !== void 0 ? _a : sandbox === null || sandbox === void 0 ? void 0 : sandbox.resume) !== null && _b !== void 0 ? _b : sandbox === null || sandbox === void 0 ? void 0 : sandbox.powerOn; };
|
|
10
|
+
const getStopFn = (sandbox) => { var _a, _b, _c; return (_c = (_b = (_a = sandbox === null || sandbox === void 0 ? void 0 : sandbox.stop) !== null && _a !== void 0 ? _a : sandbox === null || sandbox === void 0 ? void 0 : sandbox.suspend) !== null && _b !== void 0 ? _b : sandbox === null || sandbox === void 0 ? void 0 : sandbox.pause) !== null && _c !== void 0 ? _c : sandbox === null || sandbox === void 0 ? void 0 : sandbox.powerOff; };
|
|
11
|
+
const createDaytonaClient = (config) => {
|
|
12
|
+
const clientConfig = {
|
|
13
|
+
apiKey: config.token,
|
|
14
|
+
token: config.token,
|
|
15
|
+
baseUrl: config.baseUrl,
|
|
16
|
+
};
|
|
17
|
+
return new sdk_1.Daytona(clientConfig);
|
|
18
|
+
};
|
|
19
|
+
exports.createDaytonaClient = createDaytonaClient;
|
|
20
|
+
const createSandbox = async (client, input) => {
|
|
21
|
+
var _a;
|
|
22
|
+
const createFn = getCreateFn(client);
|
|
23
|
+
if (!createFn) {
|
|
24
|
+
throw new Error('Daytona SDK: create sandbox method not found.');
|
|
25
|
+
}
|
|
26
|
+
const createArgs = {
|
|
27
|
+
name: input.name,
|
|
28
|
+
language: input.runtime,
|
|
29
|
+
labels: input.sessionId ? { sessionId: input.sessionId } : undefined,
|
|
30
|
+
};
|
|
31
|
+
return createFn.call((_a = client === null || client === void 0 ? void 0 : client.sandbox) !== null && _a !== void 0 ? _a : client, createArgs);
|
|
32
|
+
};
|
|
33
|
+
exports.createSandbox = createSandbox;
|
|
34
|
+
const getSandbox = async (client, sandboxId) => {
|
|
35
|
+
var _a;
|
|
36
|
+
const fetchFn = getFetchFn(client);
|
|
37
|
+
if (!fetchFn) {
|
|
38
|
+
throw new Error('Daytona SDK: fetch sandbox method not found.');
|
|
39
|
+
}
|
|
40
|
+
return fetchFn.call((_a = client === null || client === void 0 ? void 0 : client.sandbox) !== null && _a !== void 0 ? _a : client, sandboxId);
|
|
41
|
+
};
|
|
42
|
+
exports.getSandbox = getSandbox;
|
|
43
|
+
const getSandboxByName = async (client, name) => {
|
|
44
|
+
var _a, _b, _c, _d;
|
|
45
|
+
const listFn = getListFn(client);
|
|
46
|
+
if (!listFn) {
|
|
47
|
+
throw new Error('Daytona SDK: list sandboxes method not found.');
|
|
48
|
+
}
|
|
49
|
+
const response = await listFn.call((_a = client === null || client === void 0 ? void 0 : client.sandbox) !== null && _a !== void 0 ? _a : client);
|
|
50
|
+
const sandboxes = Array.isArray(response)
|
|
51
|
+
? response
|
|
52
|
+
: (_d = (_c = (_b = response === null || response === void 0 ? void 0 : response.sandboxes) !== null && _b !== void 0 ? _b : response === null || response === void 0 ? void 0 : response.items) !== null && _c !== void 0 ? _c : response === null || response === void 0 ? void 0 : response.data) !== null && _d !== void 0 ? _d : [];
|
|
53
|
+
const match = sandboxes.find((sandbox) => { var _a; return (sandbox === null || sandbox === void 0 ? void 0 : sandbox.name) === name || ((_a = sandbox === null || sandbox === void 0 ? void 0 : sandbox.metadata) === null || _a === void 0 ? void 0 : _a.name) === name; });
|
|
54
|
+
if (!match) {
|
|
55
|
+
throw new Error(`Daytona SDK: sandbox named "${name}" not found.`);
|
|
56
|
+
}
|
|
57
|
+
return match;
|
|
58
|
+
};
|
|
59
|
+
exports.getSandboxByName = getSandboxByName;
|
|
60
|
+
const runNodeCode = async (sandbox, code, timeoutMs) => {
|
|
61
|
+
var _a, _b, _c;
|
|
62
|
+
const processApi = (_a = sandbox === null || sandbox === void 0 ? void 0 : sandbox.process) !== null && _a !== void 0 ? _a : sandbox;
|
|
63
|
+
const executeFn = (_c = (_b = processApi === null || processApi === void 0 ? void 0 : processApi.executeCommand) !== null && _b !== void 0 ? _b : processApi === null || processApi === void 0 ? void 0 : processApi.runCommand) !== null && _c !== void 0 ? _c : processApi === null || processApi === void 0 ? void 0 : processApi.run;
|
|
64
|
+
if (!executeFn) {
|
|
65
|
+
throw new Error('Daytona SDK: execute command method not found.');
|
|
66
|
+
}
|
|
67
|
+
const command = `node -e ${JSON.stringify(code)}`;
|
|
68
|
+
const options = timeoutMs ? { timeoutMs } : undefined;
|
|
69
|
+
return executeFn.call(processApi, command, options);
|
|
70
|
+
};
|
|
71
|
+
exports.runNodeCode = runNodeCode;
|
|
72
|
+
const disposeSandbox = async (sandbox) => {
|
|
73
|
+
const disposeFn = getDisposeFn(sandbox);
|
|
74
|
+
if (!disposeFn) {
|
|
75
|
+
throw new Error('Daytona SDK: dispose sandbox method not found.');
|
|
76
|
+
}
|
|
77
|
+
return disposeFn.call(sandbox);
|
|
78
|
+
};
|
|
79
|
+
exports.disposeSandbox = disposeSandbox;
|
|
80
|
+
const startSandbox = async (sandbox) => {
|
|
81
|
+
const startFn = getStartFn(sandbox);
|
|
82
|
+
if (!startFn) {
|
|
83
|
+
throw new Error('Daytona SDK: start sandbox method not found.');
|
|
84
|
+
}
|
|
85
|
+
return startFn.call(sandbox);
|
|
86
|
+
};
|
|
87
|
+
exports.startSandbox = startSandbox;
|
|
88
|
+
const stopSandbox = async (sandbox) => {
|
|
89
|
+
const stopFn = getStopFn(sandbox);
|
|
90
|
+
if (!stopFn) {
|
|
91
|
+
throw new Error('Daytona SDK: stop sandbox method not found.');
|
|
92
|
+
}
|
|
93
|
+
return stopFn.call(sandbox);
|
|
94
|
+
};
|
|
95
|
+
exports.stopSandbox = stopSandbox;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class DaytonaCreateSandbox implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DaytonaCreateSandbox = void 0;
|
|
4
|
+
const daytonaClient_1 = require("../../lib/daytonaClient");
|
|
5
|
+
class DaytonaCreateSandbox {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.description = {
|
|
8
|
+
displayName: 'Daytona Create Sandbox',
|
|
9
|
+
name: 'daytonaCreateSandbox',
|
|
10
|
+
group: ['transform'],
|
|
11
|
+
version: 1,
|
|
12
|
+
description: 'Create a Daytona sandbox for an agent session.',
|
|
13
|
+
defaults: {
|
|
14
|
+
name: 'Daytona Create Sandbox',
|
|
15
|
+
},
|
|
16
|
+
inputs: ['main'],
|
|
17
|
+
outputs: ['main'],
|
|
18
|
+
credentials: [
|
|
19
|
+
{
|
|
20
|
+
name: 'daytonaApi',
|
|
21
|
+
required: true,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
properties: [
|
|
25
|
+
{
|
|
26
|
+
displayName: 'Session ID',
|
|
27
|
+
name: 'sessionId',
|
|
28
|
+
type: 'string',
|
|
29
|
+
default: '',
|
|
30
|
+
required: true,
|
|
31
|
+
description: 'Agent session identifier used to label the sandbox.',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
displayName: 'Sandbox Name',
|
|
35
|
+
name: 'sandboxName',
|
|
36
|
+
type: 'string',
|
|
37
|
+
default: '',
|
|
38
|
+
description: 'Optional human-readable name for the sandbox.',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
displayName: 'Runtime',
|
|
42
|
+
name: 'runtime',
|
|
43
|
+
type: 'string',
|
|
44
|
+
default: 'nodejs',
|
|
45
|
+
description: 'Runtime/language to provision in the sandbox.',
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async execute() {
|
|
51
|
+
var _a, _b, _c, _d;
|
|
52
|
+
const items = this.getInputData();
|
|
53
|
+
const credentials = await this.getCredentials('daytonaApi');
|
|
54
|
+
const client = (0, daytonaClient_1.createDaytonaClient)({
|
|
55
|
+
baseUrl: credentials.baseUrl,
|
|
56
|
+
token: credentials.token,
|
|
57
|
+
});
|
|
58
|
+
const returnData = [];
|
|
59
|
+
for (let i = 0; i < items.length; i++) {
|
|
60
|
+
const sessionId = this.getNodeParameter('sessionId', i);
|
|
61
|
+
const sandboxName = this.getNodeParameter('sandboxName', i);
|
|
62
|
+
const runtime = this.getNodeParameter('runtime', i);
|
|
63
|
+
const sandbox = await (0, daytonaClient_1.createSandbox)(client, {
|
|
64
|
+
name: sandboxName || undefined,
|
|
65
|
+
sessionId,
|
|
66
|
+
runtime,
|
|
67
|
+
});
|
|
68
|
+
returnData.push({
|
|
69
|
+
json: {
|
|
70
|
+
sessionId,
|
|
71
|
+
sandboxId: (_b = (_a = sandbox === null || sandbox === void 0 ? void 0 : sandbox.id) !== null && _a !== void 0 ? _a : sandbox === null || sandbox === void 0 ? void 0 : sandbox.sandboxId) !== null && _b !== void 0 ? _b : (_c = sandbox === null || sandbox === void 0 ? void 0 : sandbox.metadata) === null || _c === void 0 ? void 0 : _c.id,
|
|
72
|
+
name: (_d = sandbox === null || sandbox === void 0 ? void 0 : sandbox.name) !== null && _d !== void 0 ? _d : sandboxName,
|
|
73
|
+
runtime,
|
|
74
|
+
raw: sandbox !== null && sandbox !== void 0 ? sandbox : null,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return [returnData];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.DaytonaCreateSandbox = DaytonaCreateSandbox;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class DaytonaDisposeSandbox implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DaytonaDisposeSandbox = void 0;
|
|
4
|
+
const daytonaClient_1 = require("../../lib/daytonaClient");
|
|
5
|
+
class DaytonaDisposeSandbox {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.description = {
|
|
8
|
+
displayName: 'Daytona Dispose Sandbox',
|
|
9
|
+
name: 'daytonaDisposeSandbox',
|
|
10
|
+
group: ['transform'],
|
|
11
|
+
version: 1,
|
|
12
|
+
description: 'Dispose a Daytona sandbox by ID.',
|
|
13
|
+
defaults: {
|
|
14
|
+
name: 'Daytona Dispose Sandbox',
|
|
15
|
+
},
|
|
16
|
+
inputs: ['main'],
|
|
17
|
+
outputs: ['main'],
|
|
18
|
+
credentials: [
|
|
19
|
+
{
|
|
20
|
+
name: 'daytonaApi',
|
|
21
|
+
required: true,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
properties: [
|
|
25
|
+
{
|
|
26
|
+
displayName: 'Sandbox ID',
|
|
27
|
+
name: 'sandboxId',
|
|
28
|
+
type: 'string',
|
|
29
|
+
default: '',
|
|
30
|
+
required: true,
|
|
31
|
+
description: 'Sandbox identifier to dispose.',
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async execute() {
|
|
37
|
+
const items = this.getInputData();
|
|
38
|
+
const credentials = await this.getCredentials('daytonaApi');
|
|
39
|
+
const client = (0, daytonaClient_1.createDaytonaClient)({
|
|
40
|
+
baseUrl: credentials.baseUrl,
|
|
41
|
+
token: credentials.token,
|
|
42
|
+
});
|
|
43
|
+
const returnData = [];
|
|
44
|
+
for (let i = 0; i < items.length; i++) {
|
|
45
|
+
const sandboxId = this.getNodeParameter('sandboxId', i);
|
|
46
|
+
const sandbox = await (0, daytonaClient_1.getSandbox)(client, sandboxId);
|
|
47
|
+
await (0, daytonaClient_1.disposeSandbox)(sandbox);
|
|
48
|
+
returnData.push({
|
|
49
|
+
json: {
|
|
50
|
+
sandboxId,
|
|
51
|
+
disposed: true,
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return [returnData];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.DaytonaDisposeSandbox = DaytonaDisposeSandbox;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class DaytonaRunCode implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DaytonaRunCode = void 0;
|
|
4
|
+
const daytonaClient_1 = require("../../lib/daytonaClient");
|
|
5
|
+
class DaytonaRunCode {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.description = {
|
|
8
|
+
displayName: 'Daytona Run Code',
|
|
9
|
+
name: 'daytonaRunCode',
|
|
10
|
+
group: ['transform'],
|
|
11
|
+
version: 1,
|
|
12
|
+
description: 'Run Node.js code in an existing Daytona sandbox.',
|
|
13
|
+
defaults: {
|
|
14
|
+
name: 'Daytona Run Code',
|
|
15
|
+
},
|
|
16
|
+
inputs: ['main'],
|
|
17
|
+
outputs: ['main'],
|
|
18
|
+
credentials: [
|
|
19
|
+
{
|
|
20
|
+
name: 'daytonaApi',
|
|
21
|
+
required: true,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
properties: [
|
|
25
|
+
{
|
|
26
|
+
displayName: 'Sandbox ID',
|
|
27
|
+
name: 'sandboxId',
|
|
28
|
+
type: 'string',
|
|
29
|
+
default: '',
|
|
30
|
+
required: true,
|
|
31
|
+
description: 'Sandbox identifier returned by Create Sandbox node.',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
displayName: 'Code',
|
|
35
|
+
name: 'code',
|
|
36
|
+
type: 'string',
|
|
37
|
+
typeOptions: {
|
|
38
|
+
rows: 8,
|
|
39
|
+
},
|
|
40
|
+
default: '',
|
|
41
|
+
required: true,
|
|
42
|
+
description: 'Node.js code to execute in the sandbox.',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
displayName: 'Timeout (ms)',
|
|
46
|
+
name: 'timeoutMs',
|
|
47
|
+
type: 'number',
|
|
48
|
+
default: 0,
|
|
49
|
+
description: 'Optional execution timeout in milliseconds.',
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async execute() {
|
|
55
|
+
var _a, _b, _c, _d;
|
|
56
|
+
const items = this.getInputData();
|
|
57
|
+
const credentials = await this.getCredentials('daytonaApi');
|
|
58
|
+
const client = (0, daytonaClient_1.createDaytonaClient)({
|
|
59
|
+
baseUrl: credentials.baseUrl,
|
|
60
|
+
token: credentials.token,
|
|
61
|
+
});
|
|
62
|
+
const returnData = [];
|
|
63
|
+
for (let i = 0; i < items.length; i++) {
|
|
64
|
+
const sandboxId = this.getNodeParameter('sandboxId', i);
|
|
65
|
+
const code = this.getNodeParameter('code', i);
|
|
66
|
+
const timeoutMs = this.getNodeParameter('timeoutMs', i);
|
|
67
|
+
const sandbox = await (0, daytonaClient_1.getSandbox)(client, sandboxId);
|
|
68
|
+
const result = await (0, daytonaClient_1.runNodeCode)(sandbox, code, timeoutMs > 0 ? timeoutMs : undefined);
|
|
69
|
+
returnData.push({
|
|
70
|
+
json: {
|
|
71
|
+
sandboxId,
|
|
72
|
+
exitCode: (_b = (_a = result === null || result === void 0 ? void 0 : result.exitCode) !== null && _a !== void 0 ? _a : result === null || result === void 0 ? void 0 : result.code) !== null && _b !== void 0 ? _b : result === null || result === void 0 ? void 0 : result.status,
|
|
73
|
+
stdout: (_c = result === null || result === void 0 ? void 0 : result.stdout) !== null && _c !== void 0 ? _c : result === null || result === void 0 ? void 0 : result.output,
|
|
74
|
+
stderr: (_d = result === null || result === void 0 ? void 0 : result.stderr) !== null && _d !== void 0 ? _d : result === null || result === void 0 ? void 0 : result.error,
|
|
75
|
+
raw: result !== null && result !== void 0 ? result : null,
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return [returnData];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.DaytonaRunCode = DaytonaRunCode;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class DaytonaStartSandbox implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DaytonaStartSandbox = void 0;
|
|
4
|
+
const daytonaClient_1 = require("../../lib/daytonaClient");
|
|
5
|
+
class DaytonaStartSandbox {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.description = {
|
|
8
|
+
displayName: 'Daytona Start Sandbox',
|
|
9
|
+
name: 'daytonaStartSandbox',
|
|
10
|
+
group: ['transform'],
|
|
11
|
+
version: 1,
|
|
12
|
+
description: 'Start a Daytona sandbox by ID or name.',
|
|
13
|
+
defaults: {
|
|
14
|
+
name: 'Daytona Start Sandbox',
|
|
15
|
+
},
|
|
16
|
+
inputs: ['main'],
|
|
17
|
+
outputs: ['main'],
|
|
18
|
+
credentials: [
|
|
19
|
+
{
|
|
20
|
+
name: 'daytonaApi',
|
|
21
|
+
required: true,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
properties: [
|
|
25
|
+
{
|
|
26
|
+
displayName: 'Identifier',
|
|
27
|
+
name: 'identifier',
|
|
28
|
+
type: 'string',
|
|
29
|
+
default: '',
|
|
30
|
+
required: true,
|
|
31
|
+
description: 'Sandbox ID or name.',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
displayName: 'Identifier Type',
|
|
35
|
+
name: 'identifierType',
|
|
36
|
+
type: 'options',
|
|
37
|
+
default: 'id',
|
|
38
|
+
options: [
|
|
39
|
+
{
|
|
40
|
+
name: 'ID',
|
|
41
|
+
value: 'id',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'Name',
|
|
45
|
+
value: 'name',
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
async execute() {
|
|
53
|
+
var _a, _b, _c, _d, _e;
|
|
54
|
+
const items = this.getInputData();
|
|
55
|
+
const credentials = await this.getCredentials('daytonaApi');
|
|
56
|
+
const client = (0, daytonaClient_1.createDaytonaClient)({
|
|
57
|
+
baseUrl: credentials.baseUrl,
|
|
58
|
+
token: credentials.token,
|
|
59
|
+
});
|
|
60
|
+
const returnData = [];
|
|
61
|
+
for (let i = 0; i < items.length; i++) {
|
|
62
|
+
const identifier = this.getNodeParameter('identifier', i);
|
|
63
|
+
const identifierType = this.getNodeParameter('identifierType', i);
|
|
64
|
+
const sandbox = identifierType === 'name'
|
|
65
|
+
? await (0, daytonaClient_1.getSandboxByName)(client, identifier)
|
|
66
|
+
: await (0, daytonaClient_1.getSandbox)(client, identifier);
|
|
67
|
+
const result = await (0, daytonaClient_1.startSandbox)(sandbox);
|
|
68
|
+
returnData.push({
|
|
69
|
+
json: {
|
|
70
|
+
identifier,
|
|
71
|
+
identifierType,
|
|
72
|
+
sandboxId: (_b = (_a = sandbox === null || sandbox === void 0 ? void 0 : sandbox.id) !== null && _a !== void 0 ? _a : sandbox === null || sandbox === void 0 ? void 0 : sandbox.sandboxId) !== null && _b !== void 0 ? _b : (_c = sandbox === null || sandbox === void 0 ? void 0 : sandbox.metadata) === null || _c === void 0 ? void 0 : _c.id,
|
|
73
|
+
name: (_d = sandbox === null || sandbox === void 0 ? void 0 : sandbox.name) !== null && _d !== void 0 ? _d : (_e = sandbox === null || sandbox === void 0 ? void 0 : sandbox.metadata) === null || _e === void 0 ? void 0 : _e.name,
|
|
74
|
+
raw: result !== null && result !== void 0 ? result : null,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return [returnData];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.DaytonaStartSandbox = DaytonaStartSandbox;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
|
|
2
|
+
export declare class DaytonaStopSandbox implements INodeType {
|
|
3
|
+
description: INodeTypeDescription;
|
|
4
|
+
execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
|
|
5
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DaytonaStopSandbox = void 0;
|
|
4
|
+
const daytonaClient_1 = require("../../lib/daytonaClient");
|
|
5
|
+
class DaytonaStopSandbox {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.description = {
|
|
8
|
+
displayName: 'Daytona Stop Sandbox',
|
|
9
|
+
name: 'daytonaStopSandbox',
|
|
10
|
+
group: ['transform'],
|
|
11
|
+
version: 1,
|
|
12
|
+
description: 'Stop a Daytona sandbox by ID or name.',
|
|
13
|
+
defaults: {
|
|
14
|
+
name: 'Daytona Stop Sandbox',
|
|
15
|
+
},
|
|
16
|
+
inputs: ['main'],
|
|
17
|
+
outputs: ['main'],
|
|
18
|
+
credentials: [
|
|
19
|
+
{
|
|
20
|
+
name: 'daytonaApi',
|
|
21
|
+
required: true,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
properties: [
|
|
25
|
+
{
|
|
26
|
+
displayName: 'Identifier',
|
|
27
|
+
name: 'identifier',
|
|
28
|
+
type: 'string',
|
|
29
|
+
default: '',
|
|
30
|
+
required: true,
|
|
31
|
+
description: 'Sandbox ID or name.',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
displayName: 'Identifier Type',
|
|
35
|
+
name: 'identifierType',
|
|
36
|
+
type: 'options',
|
|
37
|
+
default: 'id',
|
|
38
|
+
options: [
|
|
39
|
+
{
|
|
40
|
+
name: 'ID',
|
|
41
|
+
value: 'id',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'Name',
|
|
45
|
+
value: 'name',
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
async execute() {
|
|
53
|
+
var _a, _b, _c, _d, _e;
|
|
54
|
+
const items = this.getInputData();
|
|
55
|
+
const credentials = await this.getCredentials('daytonaApi');
|
|
56
|
+
const client = (0, daytonaClient_1.createDaytonaClient)({
|
|
57
|
+
baseUrl: credentials.baseUrl,
|
|
58
|
+
token: credentials.token,
|
|
59
|
+
});
|
|
60
|
+
const returnData = [];
|
|
61
|
+
for (let i = 0; i < items.length; i++) {
|
|
62
|
+
const identifier = this.getNodeParameter('identifier', i);
|
|
63
|
+
const identifierType = this.getNodeParameter('identifierType', i);
|
|
64
|
+
const sandbox = identifierType === 'name'
|
|
65
|
+
? await (0, daytonaClient_1.getSandboxByName)(client, identifier)
|
|
66
|
+
: await (0, daytonaClient_1.getSandbox)(client, identifier);
|
|
67
|
+
const result = await (0, daytonaClient_1.stopSandbox)(sandbox);
|
|
68
|
+
returnData.push({
|
|
69
|
+
json: {
|
|
70
|
+
identifier,
|
|
71
|
+
identifierType,
|
|
72
|
+
sandboxId: (_b = (_a = sandbox === null || sandbox === void 0 ? void 0 : sandbox.id) !== null && _a !== void 0 ? _a : sandbox === null || sandbox === void 0 ? void 0 : sandbox.sandboxId) !== null && _b !== void 0 ? _b : (_c = sandbox === null || sandbox === void 0 ? void 0 : sandbox.metadata) === null || _c === void 0 ? void 0 : _c.id,
|
|
73
|
+
name: (_d = sandbox === null || sandbox === void 0 ? void 0 : sandbox.name) !== null && _d !== void 0 ? _d : (_e = sandbox === null || sandbox === void 0 ? void 0 : sandbox.metadata) === null || _e === void 0 ? void 0 : _e.name,
|
|
74
|
+
raw: result !== null && result !== void 0 ? result : null,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return [returnData];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.DaytonaStopSandbox = DaytonaStopSandbox;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"node": "n8n-nodes-daytona-tool.DaytonaCreateSandbox",
|
|
3
|
+
"nodeVersion": "1.0",
|
|
4
|
+
"codexVersion": "1.0",
|
|
5
|
+
"categories": [
|
|
6
|
+
"Development"
|
|
7
|
+
],
|
|
8
|
+
"resources": {
|
|
9
|
+
"credentialDocumentation": [
|
|
10
|
+
{
|
|
11
|
+
"url": "https://www.daytona.io/docs/en/typescript-sdk/"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"primaryDocumentation": [
|
|
15
|
+
{
|
|
16
|
+
"url": "https://www.daytona.io/docs/en/typescript-sdk/"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"node": "n8n-nodes-daytona-tool.DaytonaDisposeSandbox",
|
|
3
|
+
"nodeVersion": "1.0",
|
|
4
|
+
"codexVersion": "1.0",
|
|
5
|
+
"categories": [
|
|
6
|
+
"Development"
|
|
7
|
+
],
|
|
8
|
+
"resources": {
|
|
9
|
+
"credentialDocumentation": [
|
|
10
|
+
{
|
|
11
|
+
"url": "https://www.daytona.io/docs/en/typescript-sdk/"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"primaryDocumentation": [
|
|
15
|
+
{
|
|
16
|
+
"url": "https://www.daytona.io/docs/en/typescript-sdk/"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"node": "n8n-nodes-daytona-tool.DaytonaRunCode",
|
|
3
|
+
"nodeVersion": "1.0",
|
|
4
|
+
"codexVersion": "1.0",
|
|
5
|
+
"categories": [
|
|
6
|
+
"Development"
|
|
7
|
+
],
|
|
8
|
+
"resources": {
|
|
9
|
+
"credentialDocumentation": [
|
|
10
|
+
{
|
|
11
|
+
"url": "https://www.daytona.io/docs/en/typescript-sdk/"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"primaryDocumentation": [
|
|
15
|
+
{
|
|
16
|
+
"url": "https://www.daytona.io/docs/en/typescript-sdk/"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"node": "n8n-nodes-daytona-tool.DaytonaStartSandbox",
|
|
3
|
+
"nodeVersion": "1.0",
|
|
4
|
+
"codexVersion": "1.0",
|
|
5
|
+
"categories": [
|
|
6
|
+
"Development"
|
|
7
|
+
],
|
|
8
|
+
"resources": {
|
|
9
|
+
"credentialDocumentation": [
|
|
10
|
+
{
|
|
11
|
+
"url": "https://www.daytona.io/docs/en/typescript-sdk/"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"primaryDocumentation": [
|
|
15
|
+
{
|
|
16
|
+
"url": "https://www.daytona.io/docs/en/typescript-sdk/"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"node": "n8n-nodes-daytona-tool.DaytonaStopSandbox",
|
|
3
|
+
"nodeVersion": "1.0",
|
|
4
|
+
"codexVersion": "1.0",
|
|
5
|
+
"categories": [
|
|
6
|
+
"Development"
|
|
7
|
+
],
|
|
8
|
+
"resources": {
|
|
9
|
+
"credentialDocumentation": [
|
|
10
|
+
{
|
|
11
|
+
"url": "https://www.daytona.io/docs/en/typescript-sdk/"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"primaryDocumentation": [
|
|
15
|
+
{
|
|
16
|
+
"url": "https://www.daytona.io/docs/en/typescript-sdk/"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-daytona-tool",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "n8n community nodes for running code in Daytona sandboxes.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"daytona",
|
|
8
|
+
"sandbox",
|
|
9
|
+
"agent"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"homepage": "https://www.daytona.io",
|
|
13
|
+
"author": {
|
|
14
|
+
"name": "Leandro Menezes"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://example.com/replace-with-your-repo.git"
|
|
19
|
+
},
|
|
20
|
+
"main": "dist/index.js",
|
|
21
|
+
"types": "dist/index.d.ts",
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc && copyfiles -u 1 src/nodes/**/*.node.json dist/nodes"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@daytonaio/sdk": "^0.130.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"copyfiles": "^2.4.1",
|
|
33
|
+
"typescript": "^5.3.3"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"n8n-core": "^1.0.0",
|
|
37
|
+
"n8n-workflow": "^1.0.0"
|
|
38
|
+
},
|
|
39
|
+
"n8n": {
|
|
40
|
+
"n8nNodesApiVersion": 1,
|
|
41
|
+
"credentials": [
|
|
42
|
+
"dist/credentials/DaytonaApi.credentials.js"
|
|
43
|
+
],
|
|
44
|
+
"nodes": [
|
|
45
|
+
"dist/nodes/Daytona/CreateSandbox.node.js",
|
|
46
|
+
"dist/nodes/Daytona/RunCode.node.js",
|
|
47
|
+
"dist/nodes/Daytona/DisposeSandbox.node.js",
|
|
48
|
+
"dist/nodes/Daytona/StartSandbox.node.js",
|
|
49
|
+
"dist/nodes/Daytona/StopSandbox.node.js"
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
}
|