Sandbox yardımcı işlevleri
Özel entegrasyonlar, aksiyonlar, tetikleyiciler ve iş akışı kod düğümlerinde kullanılabilen yerleşik JavaScript yardımcı işlevlerinin tam referansı
Genel bakış
Entegrasyonlar, aksiyonlar, tetikleyiciler veya iş akışı kod düğümleri için JavaScript kodu yazarken bir dizi yerleşik yardımcı işleve erişiminiz vardır. Bu işlevler, harici kitaplık gerektirmeden temel yetenekler sunan güvenli bir sandbox JavaScript ortamında çalışır.
Bu yardımcılar yalnızca JavaScript kodunda kullanılabilir. Python Code düğümleri ayrı bir çalışma zamanı kullanır ve
ld.*işlevlerini desteklemez. Python davranışı için Code node sayfasına bakın.
Sandbox nedir?
Sandbox, şu özelliklere sahip güvenli, yalıtılmış bir JavaScript yürütme ortamıdır:
- Güvenilmeyen kodu güvenle çalıştırır - Bellek sınırlı ve zaman aşımı zorunlu yürütme
- Temel yardımcılar sağlar - HTTP istekleri, veri dönüşümleri, kriptografi
- Güvenlik risklerini önler - Dosya sistemi erişimi yok,
evalveyaprocessgibi tehlikeli global'ler yok - Bağımlılık gerektirmez - npm paketleri veya harici içe aktarımlar gerekmez
Özel entegrasyon kodu güvenli bir sandbox ortamında çalışır. Harici kitaplıkları (npm, pip vb.) yükleyemez veya içe aktaramazsınız - yalnızca burada belgelenen yerleşik JavaScript/Node.js API'leri kullanılabilir. Gelişmiş işleme için (ör. PDF ayrıştırma, görsel manipülasyonu) harici API'leri veya hizmetleri kullanın ve bunları entegrasyon kodunuzdan çağırın.
Bu yardımcılar nerede kullanılabilir
Sandbox yardımcı işlevleri şuralarda kullanılabilir:
- Özel entegrasyon aksiyonları - Harici API'lerle etkileşim kuran kod
- Özel entegrasyon tetikleyicileri - Olayları izleyen kod
- Kimlik doğrulama akışları - OAuth ve API anahtarı doğrulama kodu
- İş akışı kod düğümleri - İş akışı otomasyonlarında özel JavaScript. Python için Code node sayfasına bakın.
HTTP ve ağ
ld.request()
Otomatik JSON işleme ve hata yönetimi ile harici API'lere HTTP istekleri yapın.
Parametreler:
{
method: string; // HTTP method: 'GET', 'POST', 'PUT', 'PATCH', 'DELETE'
url: string; // Full URL to request
headers?: object; // Request headers
params?: object; // URL query parameters
body?: object | string; // Request body (auto-stringified if object)
responseType?: string; // 'json', 'text', 'stream', or 'binary' for file downloads
preserveAuthOnRedirect?: boolean; // Keep auth headers on cross-origin redirects (default: false)
}Varsayılan olarak
ld.request(), bir istek farklı bir origin'e yönlendirildiğindeAuthorizationbaşlığını ve diğer kimlik bilgisi başlıklarını kaldırır. Bunları çapraz origin yönlendirmelerinde tutmak içinpreserveAuthOnRedirect: trueayarlayın. Bunu yalnızca yönlendirme hedefine güvendiğiniz API'ler için etkinleştirin.
Dönüş (varsayılan):
{
status: number; // HTTP status code
headers: object; // Response headers
json: any; // Response body parsed as JSON (undefined if not valid JSON)
text: string; // Response body as text
}Dönüş (responseType: "stream" veya "binary" ile):
{
status: number; // HTTP status code
headers: object; // Response headers
buffer: ArrayBuffer; // Response body as ArrayBuffer
success: boolean; // true on success
}Yanıt şekli
responseTypedeğerine bağlıdır. Varsayılan olarakjsonvetextözellikleri alırsınız.responseType: "stream"veya"binary"kullanıldığında bunun yerine birbufferözelliği alırsınız — bu moddajsonvetextkullanılamaz.
Örnek: GET isteği
const options = {
method: "GET",
url: "https://api.example.com/users/123",
headers: {
Authorization: `Bearer ${data.auth.access_token}`,
Accept: "application/json",
},
};
const response = await ld.request(options);
return response.json;Örnek: Gövdeli POST isteği
const options = {
method: "POST",
url: "https://api.example.com/tickets",
headers: {
Authorization: `Bearer ${data.auth.api_key}`,
"Content-Type": "application/json",
},
body: {
title: data.input.title,
description: data.input.description,
priority: "high",
},
};
const response = await ld.request(options);
return {
ticketId: response.json.id,
url: response.json.url,
};Örnek: Dosya indirme
const options = {
method: "GET",
url: `https://api.example.com/files/${data.input.fileId}/download`,
headers: {
Authorization: `Bearer ${data.auth.access_token}`,
},
responseType: "stream", // or 'binary'
};
const response = await ld.request(options);
// Convert ArrayBuffer to base64
const bytes = new Uint8Array(response.buffer);
const binaryString = String.fromCharCode(...bytes);
return {
files: {
fileName: "document.pdf",
mimeType: "application/pdf",
base64: btoa(binaryString),
},
};Örnek: Form verisi yükleme
const formData = new FormData();
formData.append("file", data.input.file.base64, data.input.file.fileName);
formData.append("description", "Uploaded via ajan");
const options = {
method: "POST",
url: "https://api.example.com/upload",
headers: {
Authorization: `Bearer ${data.auth.access_token}`,
},
body: formData,
};
const response = await ld.request(options);
return response.json;Davranış ve limitler
- İstek gövdesi işleme: Bir nesne geçerseniz
bodyparametresi otomatik olarak dizeleştirilir.application/x-www-form-urlencodediçerik türü için gövde otomatik olarak eşleşen biçime dönüştürülür. - Yanıt gövdesi başına 100 MB: Her
ld.request()yanıt gövdesi 100 MB ile sınırlıdır. Daha fazla veri döndüren istekler,Content-Lengthbaşlığı olmayan parçalı yanıtlar ve aşırı büyük hata yanıtları dahil olmak üzereResponse too largehatasıyla başarısız olur. Daha büyük dosyalar getirmeniz gerekiyorsa, bunlarıld.request()üzerinden döndürmek yerine S3 gibi harici depolamaya aktarın. - Yürütme yanıtı başına 150 MB: Bir yürütmenin döndürdüğü tamamlanmış yanıta ayrı bir üst sınır uygulanır: döndürülen değer, günlükleri ve base64 olarak satır içi döndürülen dosyalar. Daha büyük yanıtlar şu hatayla başarısız olur:
Code execution result exceeded the maximum size of 150 MB. Return a smaller result from your code.İş akışlarında saklanan düğüm çıktısının daha düşük 25 MB limiti vardır. Code node sayfasına bakın. - Ağ kısıtlamaları: Özel ve dahili ağ adreslerine yapılan istekler varsayılan olarak engellenir. Dahili uç noktalara erişmesi gereken özel bir dağıtım işletiyorsanız
URL_VALIDATION_ENABLED=falseortam değişkenini ayarlayın. Bu, iş akışı HTTP Request düğümleri, MCP sunucu URL'leri ve AgentCard URL'leri ile yönlendirmeler dahil A2A istekleri için de geçerlidir.
ld.awsRequest()
S3, API Gateway veya özel AWS API'leri gibi AWS hizmetlerine AWS SigV4 imzalı istekler yapın.
Parametreler:
{
method: string; // HTTP method
url: string; // AWS service URL
headers?: object; // Additional headers
body?: object | string; // Request body
region: string; // AWS region (e.g., 'us-east-1')
service: string; // AWS service name (e.g., 's3', 'execute-api')
credentials: { // AWS credentials
accessKeyId: string; // AWS access key ID
secretAccessKey: string; // AWS secret access key
sessionToken?: string; // AWS session token (for temporary credentials)
}
}Örnek: S3 dosya yükleme
const options = {
method: "PUT",
url: `https://my-bucket.s3.us-east-1.amazonaws.com/${data.input.fileName}`,
headers: {
"Content-Type": data.input.mimeType,
},
body: Buffer.from(data.input.file.base64, "base64"),
region: "us-east-1",
service: "s3",
credentials: {
accessKeyId: data.auth.aws_access_key_id,
secretAccessKey: data.auth.aws_secret_access_key,
},
};
const response = await ld.awsRequest(options);
return {
success: true,
url: options.url,
};Veri biçimi dönüşümleri
ld.csv2parquet()
CSV metnini isteğe bağlı sıkıştırma ve dizi desteğiyle Parquet biçimine dönüştürün.
Parametreler:
{
csvText: string; // CSV data as text
compression?: string; // 'gzip', 'snappy', 'brotli', 'lz4', 'zstd' (default), or 'uncompressed'
}Dönüş: { base64: string, success: boolean }
Örnek:
const csvText = `name,age,skills
Alice,30,"[Python,JavaScript]"
Bob,25,"[Java,Go]"`;
const result = await ld.csv2parquet(csvText, {
compression: "gzip",
});
return {
files: {
fileName: "data.parquet",
mimeType: "application/vnd.apache.parquet",
base64: result.base64,
},
};Dizi benzeri dizeler içeren CSV sütunları (ör.
"[Python,JavaScript]") otomatik olarak algılanır ve Parquet List sütunlarına dönüştürülür.
ld.parquet2csv()
Parquet biçimini CSV metnine dönüştürün; List sütunlarını uygun şekilde işler.
Parametreler:
base64Parquet: string; // Base64-encoded Parquet fileDönüş: { base64: string, success: boolean }
Örnek:
const parquetBase64 = data.input.parquetFile.base64;
const result = await ld.parquet2csv(parquetBase64);
return {
files: {
fileName: "data.csv",
mimeType: "text/csv",
base64: result.base64,
},
};ld.arrow2parquet()
Arrow IPC Stream biçimini Parquet'e dönüştürün.
Parametreler:
{
buffer: Buffer; // Arrow IPC Stream buffer
compression?: string; // Compression type (same as csv2parquet)
}Dönüş: Base64 kodlanmış Parquet dosyası
Örnek:
const arrowBuffer = Buffer.from(data.input.arrowFile.base64, "base64");
const parquetBase64 = await ld.arrow2parquet(arrowBuffer, {
compression: "snappy",
});
return {
files: {
fileName: "data.parquet",
mimeType: "application/vnd.apache.parquet",
base64: parquetBase64,
},
};ld.json2csv()
nodejs-polars kitaplığını kullanarak JSON verisini CSV biçimine dönüştürün.
Parametreler:
jsonData: Array; // Array of objects to convertDönüş: CSV metni
Örnek:
const users = [
{ name: "Alice", email: "alice@example.com", age: 30 },
{ name: "Bob", email: "bob@example.com", age: 25 },
{ name: "Charlie", email: "charlie@example.com", age: 35 },
];
const csvText = await ld.json2csv(users);
return {
files: {
fileName: "users.csv",
mimeType: "text/csv",
text: csvText,
},
};Veritabanı ve SQL
ld.validateSqlQuery()
SQL sorgu sözdiziminin boş olmadığını ve tek bir ifade içerdiğini doğrulayın.
Parametreler:
query: string; // SQL query to validateDönüş: Geçerliyse kırpılmış sorgu dizesi, aksi halde hata fırlatır
Örnek:
const query = data.input.sqlQuery;
try {
ld.validateSqlQuery(query);
// Query is valid, proceed with execution
const response = await ld.request({
method: "POST",
url: "https://api.example.com/query",
headers: {
Authorization: `Bearer ${data.auth.access_token}`,
},
body: { query },
});
return response.json;
} catch (error) {
return {
error: `Invalid SQL query: ${error.message}`,
};
}ld.ensureReadOnlySqlQuery()
Yürütme türünü kontrol ederek bir SQL sorgusunun salt okunur olmasını zorunlu kılın.
Parametreler:
query: string; // SQL query to validateDönüş: Salt okunursa kırpılmış sorgu dizesi, aksi halde hata fırlatır
Örnek:
const query = data.input.sqlQuery;
try {
ld.ensureReadOnlySqlQuery(query);
// Query is read-only, safe to execute
const response = await ld.request({
method: "POST",
url: `${data.auth.database_url}/query`,
headers: {
Authorization: `Bearer ${data.auth.access_token}`,
},
body: { query },
});
return response.json.results;
} catch (error) {
return {
error: "Only read-only queries (SELECT) are allowed",
};
}Bu işlev, sorgunun yürütme türünün yalnızca LISTING veya INFORMATION olduğundan emin olmak için kontrol eder. Veriyi değiştiren sorgular (INSERT, UPDATE, DELETE) reddedilir.
Kriptografi
ld.signWithRS256()
JWT imzalama ve OAuth akışlarında yaygın olarak kullanılan RSA-SHA256 dijital imzaları oluşturun.
İşlev imzası:
ld.signWithRS256(data, privateKey, options)Parametreler:
data(string): İmzalanacak veriprivateKey(string): PEM biçimli RSA özel anahtarıoptions(object, isteğe bağlı):encoding(string): Çıktı kodlaması -'base64'(varsayılan) veya'hex'
Dönüş: { signature: string } — belirtilen kodlamada imzayı içeren nesne
Örnek: JWT imzalama
const header = {
alg: "RS256",
typ: "JWT",
};
const payload = {
iss: "your-client-id",
sub: "user@example.com",
aud: "https://api.example.com",
exp: Math.floor(Date.now() / 1000) + 3600, // 1 hour
iat: Math.floor(Date.now() / 1000),
};
const encodedHeader = btoa(JSON.stringify(header));
const encodedPayload = btoa(JSON.stringify(payload));
const signingInput = `${encodedHeader}.${encodedPayload}`;
const result = ld.signWithRS256(signingInput, data.auth.private_key, {
encoding: "base64",
});
const jwt = `${signingInput}.${result.signature}`;
// Use JWT for authentication
const response = await ld.request({
method: "POST",
url: "https://api.example.com/auth/token",
body: {
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
assertion: jwt,
},
});
return response.json;Özel anahtar PEM biçiminde olmalıdır. Geçersiz anahtarlar kullanıcı dostu hata mesajları fırlatır. Özel anahtarları asla günlüklerde veya dönüş değerlerinde açığa çıkarmayın.
Yardımcı işlevler
ld.log()
"Test Action" düğmesinin altında görünen yürütme günlüklerine hata ayıklama bilgisi yazın.
Parametreler:
...args: any[]; // Any number of values to logÖrnek:
ld.log("Starting ticket creation");
ld.log("Input data:", data.input);
const response = await ld.request(options);
ld.log("Response status:", response.status);
ld.log("Ticket created:", response.json);
return response.json;Entegrasyon kodunuzu ayıklamak için geliştirme sırasında
ld.log()işlevini bolca kullanın. Günlükler, hassas kimlik doğrulama değerlerini gizlemek için otomatik olarak düzenlenir.
ld.wait()
Belirtilen milisaniye kadar yürütmeyi duraklatın. Hız sınırlama veya yeniden deneme mantığı için yararlıdır.
Parametreler:
ms: number; // Milliseconds to wait (0-30000)Örnek:
// Retry with delay
let retries = 3;
while (retries > 0) {
const response = await ld.request(options);
if (response.status === 429) {
await ld.wait(2000); // Wait 2 seconds before retrying
retries--;
continue;
}
return response.json;
}
return { error: "Rate limit exceeded after retries" };atob() / btoa()
İçe aktarım gerektirmeden global olarak kullanılabilen Base64 kodlama ve çözme işlevleri.
atob() - Base64 dizesini ikili dizeye çözme btoa() - İkili dizeyi base64'e kodlama
Örnek: Base64 URL çözme
function base64UrlDecode(base64Url) {
// Convert base64url to standard base64
const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
return atob(base64);
}
const token = data.input.jwt_token;
const [header, payload, signature] = token.split(".");
const decodedPayload = JSON.parse(base64UrlDecode(payload));
ld.log("Token payload:", decodedPayload);
return decodedPayload;Örnek: Temel kimlik doğrulama
const credentials = btoa(`${data.auth.username}:${data.auth.password}`);
const response = await ld.request({
method: "GET",
url: "https://api.example.com/data",
headers: {
Authorization: `Basic ${credentials}`,
},
});
return response.json;Buffer.from()
Tipli dizi biçimleri arasında dönüştürme için minimal bir polyfill. Tek bir argüman kabul eder (Array, Uint8Array veya ArrayBuffer) ve bir Uint8Array döndürür.
Bu, tam Node.js Buffer değildir. Yalnızca Array, Uint8Array veya ArrayBuffer kabul eder — dizeleri değil.
Buffer.from("hello")gibi bir dize geçirmek hata fırlatır. DöndürülenUint8Arraybir.toString("base64")yöntemine sahip değildir. Base64 kodlama/çözme için bunun yerinebtoa()/atob()kullanın.
Örnek: ld.request()'ten ArrayBuffer dönüştürme
const response = await ld.request({
method: "GET",
url: `https://api.example.com/files/${data.input.fileId}`,
headers: { Authorization: `Bearer ${data.auth.access_token}` },
responseType: "stream",
});
// Convert ArrayBuffer to Uint8Array for processing
const bytes = Buffer.from(response.buffer);Örnek: İndirilen dosyayı base64 kodlama
// Use btoa() for base64 encoding since Buffer.toString() is not available
const binaryString = String.fromCharCode(...new Uint8Array(response.buffer));
const base64Data = btoa(binaryString);
return {
files: {
fileName: "document.pdf",
mimeType: "application/pdf",
base64: base64Data,
},
};FormData
Dosya yüklemeleri ve karmaşık istek gövdeleri için multipart form verisi oluşturun.
Örnek: Meta verili dosya yükleme
const formData = new FormData();
formData.append("file", data.input.file.base64, data.input.file.fileName);
formData.append("title", data.input.title);
formData.append("category", data.input.category);
formData.append("tags", JSON.stringify(data.input.tags));
const response = await ld.request({
method: "POST",
url: "https://api.example.com/documents",
headers: {
Authorization: `Bearer ${data.auth.access_token}`,
},
body: formData,
});
return response.json;Standart JavaScript API'leri
Sandbox ayrıca standart JavaScript yerleşiklerine erişim sağlar:
JSON
JSON.stringify()- Nesneleri JSON dizelerine dönüştürmeJSON.parse()- JSON dizelerini nesnelere ayrıştırma
Date
new Date()- Tarih nesneleri oluşturmaDate.now()- Geçerli zaman damgasını alma- Tüm standart Date yöntemleri
Math
Math.floor(),Math.ceil(),Math.round()Math.random(),Math.max(),Math.min()- Tüm standart Math yöntemleri
RegExp
new RegExp()- Düzenli ifadeler oluşturma- Dize regex yöntemleri:
match(),replace(),test()
Array ve Object
- Tüm standart Array yöntemleri:
map(),filter(),reduce()vb. - Tüm standart Object yöntemleri:
keys(),values(),entries()vb.
Örnek: Veri dönüşümü
const users = data.input.users;
// Filter active users
const activeUsers = users.filter((user) => user.status === "active");
// Transform to required format
const formatted = activeUsers.map((user) => ({
id: user.id,
name: `${user.firstName} ${user.lastName}`,
email: user.email.toLowerCase(),
joinedDate: new Date(user.createdAt).toISOString().split("T")[0],
}));
// Sort by join date
formatted.sort((a, b) => new Date(b.joinedDate) - new Date(a.joinedDate));
return {
users: formatted,
total: formatted.length,
};En iyi uygulamalar
Hata işleme
API çağrılarını her zaman try-catch bloklarıyla sarın ve yararlı hata mesajları sağlayın:
try {
const response = await ld.request(options);
return response.json;
} catch (error) {
ld.log("Error details:", error.message, error.stack);
return {
error: `Failed to fetch data: ${error.message}`,
};
}Giriş doğrulama
Kullanıcı girdilerini kullanmadan önce doğrulayın:
// Validate required fields
if (!data.input.email || !data.input.name) {
return {
error: "Missing required fields: email and name are required",
};
}
// Validate email format
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(data.input.email)) {
return {
error: "Invalid email format",
};
}
// Validate file type
const allowedTypes = ["application/pdf", "image/jpeg", "image/png"];
if (
data.input.file &&
!allowedTypes.includes(data.input.file.mimeType)
) {
return {
error: `Unsupported file type. Allowed: ${allowedTypes.join(", ")}`,
};
}Performans ipuçları
API çağrılarını en aza indirin
// Bad: Multiple sequential calls
const user = await ld.request({ url: "/users/123" });
const posts = await ld.request({ url: `/users/123/posts` });
const comments = await ld.request({ url: `/users/123/comments` });
// Good: Use batch endpoints when available
const response = await ld.request({
url: "/users/123?include=posts,comments",
});Sayfalama kullanın
const allResults = [];
let page = 1;
const pageSize = 100;
while (true) {
const response = await ld.request({
url: "https://api.example.com/data",
params: {
page,
pageSize,
},
});
allResults.push(...response.json.items);
if (response.json.items.length < pageSize) {
break; // No more pages
}
page++;
}
return allResults;Güvenlik hususları
Gizlilikleri asla sabit kodlamayın
// Bad: Hardcoded API key
const apiKey = "sk_live_abc123";
// Good: Use authentication fields
const apiKey = data.auth.api_key;Kullanıcı girdisini temizleyin
// Sanitize SQL-like input
const searchTerm = data.input.search.replace(/['"]/g, "");
// Validate URL parameters
const itemId = data.input.itemId.replace(/[^a-zA-Z0-9-_]/g, "");Hız limitlerini yönetin
try {
const response = await ld.request(options);
return response.json;
} catch (error) {
if (error.message.includes("429") || error.message.includes("rate limit")) {
return {
error: "API rate limit exceeded. Please try again in a few minutes.",
};
}
throw error;
}Yaygın tuzaklar
1. Async/Await'i düzgün işlememek
// Bad: Not awaiting promises
const response = ld.request(options); // Returns Promise, not response!
return response.json; // undefined
// Good: Always await
const response = await ld.request(options);
return response.json;2. Kontroller olmadan iç içe özelliklere erişmek
// Bad: Can throw if user or address is undefined
const city = response.json.user.address.city;
// Good: Use optional chaining
const city = response.json?.user?.address?.city || "Unknown";3. JSON dizelerini ayrıştırmamak
// Bad: Assuming string is already an object
const properties = data.input.properties; // String: '{"name":"value"}'
properties.name; // undefined
// Good: Parse JSON strings
const properties = JSON.parse(data.input.properties);
properties.name; // "value"4. Dondurulmuş nesneleri değiştirmek
// Bad: Sandbox freezes global objects
Array.prototype.customMethod = () => {}; // Error!
// Good: Create new objects
const customArray = [...originalArray];Sonraki adımlar
- Özel entegrasyon oluşturma - İlk entegrasyonunuzu oluşturun
- Özel entegrasyonlarda dosya desteği - Dosya girdilerini ve çıktılarını yönetin
- Integration Agent - Entegrasyon kodu yazmada yardım alın
- Workflow Code Node - İş akışlarında özel kod yazın
SSS
Yaygın yardımcı davranış gerektiren özel entegrasyonlar, aksiyonlar, tetikleyiciler veya iş akışı kod düğümleri oluştururken sandbox yardımcı işlevlerini kullanın. Şablon kodunu azaltabilir ve özel mantığı sürdürmeyi kolaylaştırabilirler.
İşlevi desteklenen bir bağlamda kullanıp kullanmadığınızı, işlev adı ve argümanlarının doğru olup olmadığını ve çalışma zamanının ihtiyaç duyduğunuz davranışı destekleyip desteklemediğini kontrol edin.