İçeriğe geç
ajan.io

Belgeler menüsü

Bu sayfada

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, eval veya process gibi 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:

typescript
{
  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ğinde Authorization başlığını ve diğer kimlik bilgisi başlıklarını kaldırır. Bunları çapraz origin yönlendirmelerinde tutmak için preserveAuthOnRedirect: true ayarlayın. Bunu yalnızca yönlendirme hedefine güvendiğiniz API'ler için etkinleştirin.

Dönüş (varsayılan):

typescript
{
  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):

typescript
{
  status: number;           // HTTP status code
  headers: object;          // Response headers
  buffer: ArrayBuffer;      // Response body as ArrayBuffer
  success: boolean;         // true on success
}

Yanıt şekli responseType değerine bağlıdır. Varsayılan olarak json ve text özellikleri alırsınız. responseType: "stream" veya "binary" kullanıldığında bunun yerine bir buffer özelliği alırsınız — bu modda json ve text kullanılamaz.

Örnek: GET isteği

javascript
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

javascript
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

javascript
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

javascript
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 body parametresi otomatik olarak dizeleştirilir. application/x-www-form-urlencoded iç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-Length başlığı olmayan parçalı yanıtlar ve aşırı büyük hata yanıtları dahil olmak üzere Response too large hatası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=false ortam 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:

typescript
{
  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

javascript
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:

typescript
{
  csvText: string;          // CSV data as text
  compression?: string;     // 'gzip', 'snappy', 'brotli', 'lz4', 'zstd' (default), or 'uncompressed'
}

Dönüş: { base64: string, success: boolean }

Örnek:

javascript
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:

typescript
base64Parquet: string;    // Base64-encoded Parquet file

Dönüş: { base64: string, success: boolean }

Örnek:

javascript
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:

typescript
{
  buffer: Buffer;           // Arrow IPC Stream buffer
  compression?: string;     // Compression type (same as csv2parquet)
}

Dönüş: Base64 kodlanmış Parquet dosyası

Örnek:

javascript
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:

typescript
jsonData: Array;  // Array of objects to convert

Dönüş: CSV metni

Örnek:

javascript
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:

typescript
query: string;            // SQL query to validate

Dönüş: Geçerliyse kırpılmış sorgu dizesi, aksi halde hata fırlatır

Örnek:

javascript
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:

typescript
query: string;            // SQL query to validate

Dönüş: Salt okunursa kırpılmış sorgu dizesi, aksi halde hata fırlatır

Örnek:

javascript
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ı:

javascript
ld.signWithRS256(data, privateKey, options)

Parametreler:

  • data (string): İmzalanacak veri
  • privateKey (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

javascript
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:

typescript
...args: any[];           // Any number of values to log

Örnek:

javascript
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:

typescript
ms: number;               // Milliseconds to wait (0-30000)

Örnek:

javascript
// 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

javascript
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

javascript
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ülen Uint8Array bir .toString("base64") yöntemine sahip değildir. Base64 kodlama/çözme için bunun yerine btoa()/atob() kullanın.

Örnek: ld.request()'ten ArrayBuffer dönüştürme

javascript
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

javascript
// 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

javascript
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ürme
  • JSON.parse() - JSON dizelerini nesnelere ayrıştırma

Date

  • new Date() - Tarih nesneleri oluşturma
  • Date.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ü

javascript
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:

javascript
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:

javascript
// 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

javascript
// 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

javascript
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

javascript
// Bad: Hardcoded API key
const apiKey = "sk_live_abc123";

// Good: Use authentication fields
const apiKey = data.auth.api_key;

Kullanıcı girdisini temizleyin

javascript
// 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

javascript
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

javascript
// 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

javascript
// 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

javascript
// 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

javascript
// Bad: Sandbox freezes global objects
Array.prototype.customMethod = () => {}; // Error!

// Good: Create new objects
const customArray = [...originalArray];

Sonraki adımlar

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.