API reference: @cogover/sdk
@cogover/sdk là contract TypeScript công khai để phát triển Custom Backend Module
trên Cogover. Thông tin xác thực của Cogover không bao giờ được đưa vào code của
module; các capability call bị giới hạn bởi quyền và hạn mức đã cấu hình cho
project.
Mục lục
Tài liệu tham chiếu được chia thành các trang sau. Mỗi trang mô tả một nhóm chức năng của SDK.
| Trang | Nội dung |
|---|---|
| Script và HTTP route | defineScript; HTTP router và request context; Danh tính invocation và workspace hiện tại; HTTP response API; Logging |
| Record và schema | Record API; Chọn field; Record liên kết; Aggregate; Filter và sort; Danh tính thực hiện thao tác record; Schema API; Khai báo Workspace |
| Record trigger | Record trigger |
| Background job | Background job |
| Outbound HTTP và secret | Outbound HTTP fetch; Secret và credential |
| Mã hoá và chữ ký | Mã hoá và chữ ký |
| Inbound webhook | Inbound webhook |
| Project state và lock | Project state; Distributed locks |
| Push message | Push message |
| Notification và email | Notification; Email |
| Cơ cấu tổ chức | Cơ cấu tổ chức |
| Custom Module Action | Custom Module Action; Schema builder |
| Process và AI Agent | Process và AI Agent |
Các mục dưới đây áp dụng cho mọi nhóm chức năng: các lỗi mà mọi API có thể ném, giới hạn của một lần thực thi, cách đọc các giới hạn đó trong code và helper tương thích.
Errors
class CogoverApiError extends Error {
readonly code: string;
readonly r: number | undefined;
readonly details?: unknown;
constructor(code: string, message: string, details?: unknown);
}
class NotFoundError extends CogoverApiError {
readonly resource: string;
readonly resourceId: string;
constructor(resource: string, resourceId: string, message?: string, details?: unknown);
}
class ValidationError extends CogoverApiError {
constructor(message: string, details?: unknown);
}
class PermissionDeniedError extends CogoverApiError {
constructor(message: string, details?: unknown);
}
class RateLimitError extends CogoverApiError {
constructor(message: string, details?: unknown);
}
class RetryableError extends CogoverApiError {
constructor(message: string, details?: unknown);
}
class StateConflictError extends CogoverApiError {
constructor(message: string, details?: unknown);
}
class LockUnavailableError extends CogoverApiError {
constructor(key: string, message?: string, details?: unknown);
}
class LockLostError extends CogoverApiError {
constructor(message: string, details?: unknown);
}Các lỗi dịch vụ được SDK map sang các error trên. Các error giữ:
error.code: nhóm lỗi SDK, ví dụPERMISSION_DENIED.-
error.r: mãrgốc từ server, ví dụ37; làundefinednếu không có response từ server (như lỗi validation trong SDK). error.message: thông báo gốc;error.detailsgiữ chi tiết kèm theo, gồmr.
RetryableError (code: "RETRYABLE") báo một lỗi tạm thời. SDK ném lỗi này cho thao
tác ghi record mà trigger before-change không kiểm tra được (details.reason là
"TRIGGER_FAILED", xem Record trigger) và
cho lần khởi chạy Process hoặc AI Agent thất bại tạm thời (xem
Process và AI Agent), và code của
project tự ném lỗi này. Handler của trigger after-change hoặc job handler ném
lỗi này để báo một lỗi tạm thời, và Cogover sẽ chạy lại handler sau (xem
Quy tắc thực thi after-change và
Quy tắc thực thi job). Ở những nơi khác lỗi này không có
ý nghĩa đặc biệt: script để lỗi thoát ra sẽ trả HTTP 422, và trigger before-change
ném lỗi này sẽ làm thao tác ghi bị từ chối như mọi lỗi khác.
Lệnh đọc record (get, getMany hoặc list) không có option fields hợp lệ ném
ValidationError với message fields is required: pass field slugs or "*" (@cogover/sdk 0.13.0+). Cogover trả cùng lỗi này cho phiên bản project đã publish bằng
SDK cũ mà đọc không có fields (xem Chọn field).
jobs.enqueue, secrets.get và crypto thất bại với ValidationError,
PermissionDeniedError hoặc RateLimitError như mô tả trong mục của chúng, và với
CogoverApiError có code là JOBS_DISABLED hoặc SECRETS_DISABLED khi tính
năng chưa được bật cho Workspace. crypto.aesDecrypt và crypto.rsaDecrypt ném
CogoverApiError với code: "DECRYPTION_FAILED" khi không giải mã được ciphertext.
notifications.send và email.send thất bại với ValidationError, NotFoundError,
PermissionDeniedError hoặc RateLimitError như mô tả trong mục của chúng, với
CogoverApiError có code là NOTIFICATIONS_DISABLED hoặc EMAIL_DISABLED khi tính
năng bị tắt, và với CogoverApiError có code là DUPLICATE_IN_PROGRESS trong lúc
một lời gọi trước đó cùng idempotencyKey vẫn đang gửi. Hộp thư gửi không được
Project policy cho phép được báo bằng PermissionDeniedError có details.reason là
"EMAIL_SENDER_NOT_GRANTED".
processes và agents thất bại với ValidationError, NotFoundError,
PermissionDeniedError, RateLimitError hoặc RetryableError như mô tả ở
Process và AI Agent. Process hoặc agent không được
Project policy cho phép được báo bằng PermissionDeniedError có details.reason là
"PROCESSES_NOT_ALLOWED" hoặc "AGENTS_NOT_ALLOWED", và approvalPolicy: "autoApprove"
không được cho phép được báo với "AGENT_AUTO_APPROVE_NOT_ALLOWED". Hai API này còn thất
bại với CogoverApiError có code là MAX_HOP_EXCEEDED khi ngân sách tự động hoá đã
hết, IDEMPOTENCY_CONFLICT khi một danh tính khác của project đã dùng idempotencyKey,
AGENT_DEPTH_EXCEEDED khi các AI Agent khởi chạy lẫn nhau quá sâu, NOT_SUPPORTED với
onComplete hoặc onResult trong phiên phát triển local, và PROCESSES_DISABLED hoặc
AGENTS_DISABLED khi tính năng không khả dụng. agents.start còn thất bại với
CogoverApiError có code là INSUFFICIENT_CREDITS, AI_SUBSCRIPTION_REQUIRED,
AI_SEAT_REQUIRED, AGENT_CREDIT_LIMIT_EXCEEDED hoặc MODEL_NOT_PRICED khi dịch vụ AI
Agent từ chối lượt chạy vì tính phí credit AI. Node Process hoặc AI Agent gọi một
Custom Module Action nhận các lỗi mô tả ở
Lỗi bên gọi nhận được.
Script có thể bắt lỗi và tự chọn mã/thông báo trả cho client, không cần forward lỗi gốc.
Thông báo public trong msg, message và các field tương tự luôn phải viết bằng
tiếng Anh, kể cả khi tài liệu hoặc giao diện sử dụng ngôn ngữ khác.
try {
await orders.records.update(id, fields);
} catch (error) {
if (error instanceof CogoverApiError && error.r === 37) {
return { r: 1001, msg: "You do not have permission to update this order." };
}
throw error;
}
Import CogoverApiError từ @cogover/sdk. JSON do script return vẫn là response
do script tự định nghĩa với HTTP 200.
Với lỗi SDK thoát khỏi defineScript, endpoint HTTP trả lỗi có r bằng HTTP
status, code và msg an toàn:
| SDK code | HTTP / r |
|---|---|
PERMISSION_DENIED |
403 |
NOT_FOUND |
404 |
METHOD_NOT_ALLOWED |
405 |
VALIDATION_ERROR |
400 |
RATE_LIMITED |
429 |
STATE_CONFLICT |
409 |
LOCK_NOT_ACQUIRED |
409 |
LOCK_LOST |
409 |
STATE_SERVICE_UNAVAILABLE |
503 |
LOCK_SERVICE_UNAVAILABLE |
503 |
ORGANIZATION_UNAVAILABLE |
503 |
FETCH_DISABLED |
503 |
FETCH_BLOCKED |
400 |
FETCH_REQUEST_TOO_LARGE |
413 |
FETCH_RESPONSE_TOO_LARGE |
502 |
FETCH_TIMEOUT |
504 |
FETCH_FAILED |
502 |
COGOVER_API_ERROR |
422 |
RETRYABLE |
422 |
Thiếu phê duyệt danh tính được chọn trả thêm reason: "IDENTITY_NOT_GRANTED";
không có nghĩa nhân sự đích đã bị từ chối truy cập một bản ghi cụ thể.
Không trả thông báo lỗi gốc, stack trace hoặc details tuỳ ý.
writesMayHaveCompleted là true nếu lần thực thi đã gửi ít nhất một lời gọi có thể
thay đổi dữ liệu bên ngoài, kể cả khi thao tác sau đó thất bại: ghi record,
state.set hoặc state.delete, mọi lời gọi locks (kể cả acquire trả null), push
message, notifications.send, email.send, jobs.enqueue, processes.start,
agents.start, hoặc fetch có method khác GET và HEAD.
Vì vậy LockUnavailableError thoát khỏi script luôn báo true. Đây là cảnh báo thận
trọng, không xác nhận ghi thành công.
Lỗi không xác định và lỗi giới hạn tài nguyên vẫn trả HTTP 422 chung.
Các phản hồi này không rollback thao tác ghi trước đó; không tự động retry ghi.
Giới hạn của một lần thực thi
Mỗi lần thực thi chạy trong giới hạn của nền tảng. Các giá trị dưới đây là mặc định; chúng do nền tảng thiết lập và có thể khác giữa các môi trường.
| Ngân sách của một lần thực thi | HTTP route | Trigger before-change | Trigger after-change | Background job |
|---|---|---|---|---|
Capability call (capabilityCalls) |
100 | 20 | 100 | 1.000 |
Lời gọi cục bộ (localCalls) |
200 | 50 | 200 | 1.000 |
Record đọc (recordsRead) |
10.000 | 4.000 | 10.000 | 50.000 |
Record ghi (recordsWritten) |
10.000 | — | 10.000 | 50.000 |
-
Capability call. Mỗi lời gọi
data,schema,state,locks,push,notifications,email,jobs,secrets,fetch,processeshoặcagents, và mỗi lần đọcorgcówithDisplay: true, tính một lần. -
Lời gọi cục bộ. Lời gọi
cryptovà lần đọcorgkhông cówithDisplaydo chính Cogover xử lý, nên tính vào ngân sách riêng. Keycryptodạng{ secret: name }vẫn là một lần đọc secret (xem quota bên dưới). -
Record đọc. Các record mà
records.get,records.getManyvàrecords.listtrả về, cùng các record liên kết màexpandLookupsđọc. Một lần đọc bị từ chối trước khi gửi nếu có thể vượt ngân sách:records.gettính 1,records.getManytính số ID, cònrecords.listtínhlimitcủa nó (mặc định 20).records.aggregatekhông trả record nên không tính. -
Record ghi.
create,updatevàupsertByUniqueFieldtính 1,batchInsertvàbatchUpdatetính số record,deleteManytính số ID, được tính khi lời gọi được gửi. Trigger before-change không ghi được record. -
Lời gọi có thể vượt một ngân sách, và mọi lời gọi sau đó thuộc ngân sách đó, ném
RateLimitErrormà không được gửi đi, nên script có thể bắt được.details.budgetlà tên ngân sách,details.limitlà kích thước,details.usedlà phần lần thực thi đã dùng, và với record thìdetails.requestedlà số lời gọi yêu cầu. Chờ không giúp được gì: ngân sách thuộc về lần thực thi. Hãy đọc ít record hơn, dùngrecords.aggregatecho số tổng, hoặc chuyển việc sang background job. Lần thực thi vẫn tiếp tục gọi sau 1.000 lời gọi bị từ chối sẽ bị kết thúc vớicode: "RATE_LIMITED"; script không bắt được lỗi này. -
Một HTTP route có 8 giây wall-clock, tính từ lúc handler bắt đầu chạy, kể cả thời gian
chờ capability call, chờ lock hoặc chờ server bên ngoài. Record trigger dùng
timeoutMscủa nó, background job dùngtimeoutMscủa job. Custom Module Action có ngân sách của một HTTP route vàtimeoutMsriêng, tối đa 8 giây. Vượt thời gian sẽ kết thúc toàn bộ lần thực thi: script không bắt được, và HTTP route trả response HTTP 422 chung. Các capability call của một lần thực thi chạy lần lượt, kể cả khi được bắt đầu cùng lúc bằngPromise.all. -
Một capability request, đã mã hoá JSON cùng tham số, không được vượt quá 262.144
byte. Request lớn hơn bị từ chối trước khi gửi bằng
ValidationError, hoặcCogoverApiErrorcócode: "FETCH_REQUEST_TOO_LARGE"vớifetch;details.limitlà giới hạn. Kết quả capability lớn hơn 1.048.576 byte cũng bị giữ lại theo cách đó (FETCH_RESPONSE_TOO_LARGEvớifetch): hãy yêu cầu ít record hơn, hoặc nêu field thay cho"*". Bản thân thao tác vẫn đã chạy, nên thao tác ghi có thể đã hoàn tất. -
Khi Workspace đã có quá nhiều lần thực thi đang chờ, lời gọi HTTP mới bị từ chối với
HTTP 429 và
code: "RATE_LIMITED"trước khi chạy bất cứ gì; hãy thử lại sau. Lỗi này không códetails.budget.
Một số API còn có quota riêng cho mỗi lần thực thi, như 20 lời gọi fetch, 20 lần đọc
secret, 20 lời gọi processes.start hoặc 5 lời gọi agents.start. Vượt các quota này
cũng được báo bằng RateLimitError.
Đọc giới hạn trong code
const limits: LimitsApi;
interface LimitsApi {
usage(): LimitUsage;
}
interface LimitUsage {
readonly capabilityCalls: LimitCounter;
readonly localCalls: LimitCounter;
readonly recordsRead: LimitCounter;
readonly recordsWritten: LimitCounter;
readonly elapsedMs: number;
readonly timeLimitMs: number;
}
interface LimitCounter {
readonly used: number;
readonly limit: number;
readonly remaining: number;
}
limits được package export và cũng là thành phần limits trong context của script,
route, record trigger, background job và Custom Module Action. limits.usage() trả các ngân sách của lần thực
thi hiện tại tính đến lời gọi Cogover gần nhất: việc đọc không phải capability call.
remaining là limit - used và không nhỏ hơn 0. elapsedMs là thời gian từ lúc handler
bắt đầu tính đến lời gọi gần nhất đó, còn timeLimitMs là thời gian wall-clock lần thực
thi được phép chạy. Gọi ngoài handler, ví dụ khi module đang nạp hoặc trong test chạy
ngoài Cogover, usage() ném CogoverApiError với code: "CAPABILITY_UNAVAILABLE".
Khi code chạy local bằng Cogover Dev CLI, mỗi handler nhận ngân sách theo loại lần thực
thi của nó và bị từ chối giống như trên Cogover; record liên kết mà expandLookups đọc
không được tính ở local.
import { defineScript } from "@cogover/sdk";
export default defineScript(async ({ data, jobs, limits }) => {
const orders = data.object("order");
let cursor: string | undefined;
let total = 0;
do {
const page = await orders.records.list({ fields: ["amount"], limit: 200, cursor });
for (const order of page.items) total += Number(order.fields.amount ?? 0);
cursor = page.nextCursor;
const usage = limits.usage();
if (cursor !== undefined && (usage.recordsRead.remaining < 200 || usage.capabilityCalls.remaining < 2)) {
// Chuyển phần còn lại sang background job, vốn có ngân sách lớn hơn.
await jobs.enqueue("sum_orders", { cursor, total });
return { total, complete: false };
}
} while (cursor !== undefined);
return { total, complete: true };
});
Với một số tổng như ví dụ này, records.aggregate chỉ tốn một capability call và không
đọc record nào; chỉ duyệt từng trang record khi kết quả không biểu diễn được bằng aggregate.
Helper tương thích
function createGreeting(name: string): string;
createGreeting("Cogover") trả "Hello Cogover". Hàm được giữ để tương thích SDK
0.1.x và không thuộc Data API.
Rate this page
On this page