JS action
Dùng JavaScript để điều phối nhiều action trong một lần chạy, trong sandbox có giới hạn, với whitelist action được gọi và kiểm tra chu trình khi publish.
JS action là action viết bằng JavaScript. JS action không kết nối tới DB nào. Nó gọi các action khác bằng executeAction(slug, params), ghép kết quả và trả về. Dùng JS action khi một thao tác gồm nhiều bước, ví dụ lấy dữ liệu từ hai action rồi ghép lại, hoặc chạy một chuỗi action ghi theo thứ tự.
Vai trò cần có
Phần tiêu đề “Vai trò cần có”- Editor trở lên: tạo, sửa, publish JS action.
- Admin: cho phép JS action gọi một action ở chế độ restricted (whitelist, xem bên dưới).
Tạo JS action
Phần tiêu đề “Tạo JS action”- Vào Xây dựng > Action, bấm Tạo action.
- Nhập Tên, Slug, chọn Loại là JavaScript (không cần chọn data source) và chọn Kiểu. Chọn Ghi dữ liệu nếu JS action gọi action ghi, để người chạy phải xác nhận.
- Bấm Tạo, sau đó viết code ở tab Định nghĩa. Gõ
executeAction("để editor gợi ý các action gọi được. - Khai báo param của JS action ở phần Param như với action SQL. Code đọc các param này qua
ctx.params. - Bấm Lưu nháp, sau đó bấm Publish.
Viết code
Phần tiêu đề “Viết code”Code phải export default một hàm nhận ctx và trả về kết quả:
export default (ctx) => { const orders = executeAction('orders-by-status', { status: ctx.params.status }); const customers = executeAction('list-customers');
const emailById = {}; customers.forEach((c) => { emailById[c.id] = c.email; });
return orders.map((o) => ({ id: o.id, total: o.total, customer_email: emailById[o.customer_id] || null, }));};ctxgồmcurrentUser(id,emailcủa người đang chạy),environment(id,slug,isProduction),params(param của JS action) vàvars(biến của môi trường).executeAction(slug, params)trả về mảng các dòng của action được gọi. Nếu action con lỗi,executeActionném lỗi; bắt lỗi bằngtry/catch.- Nếu hàm trả về mảng object, trang Chạy action hiển thị bảng. Nếu trả về một giá trị đơn, trang hiển thị một dòng.
- Hai lời gọi tới cùng một action với cùng param trong một lần chạy chỉ thực thi một lần và dùng chung kết quả.
Sandbox và giới hạn
Phần tiêu đề “Sandbox và giới hạn”JS action chạy trong sandbox QuickJS phía server:
- Không có
fetch,require, hệ thống file hay mạng.executeActionlà cách duy nhất để truy cập dữ liệu bên ngoài. - Tối đa 50 lời gọi
executeActionmỗi lần chạy. - JS action gọi JS action lồng nhau tối đa 3 tầng.
- Mỗi lần chạy tối đa 30 giây và 128 MB bộ nhớ.
- Mỗi action con tự commit. Không có transaction chung cho cả chuỗi: nếu một bước sau lỗi, dữ liệu các bước trước đã ghi vẫn giữ nguyên. Dùng
try/catchđể gọi action bù trừ khi cần. - JS action chưa chạy nền được: không đưa vào hàng đợi, không chạy hàng loạt và không đặt lịch được.
Quyền khi gọi action con
Phần tiêu đề “Quyền khi gọi action con”Mỗi lời gọi executeAction đi qua toàn bộ bước kiểm tra quyền của action con, với quyền của người đang chạy JS action. Publish một JS action không cấp thêm quyền cho ai: nếu người chạy không có quyền chạy action con, lời gọi đó bị từ chối.
Whitelist: cho JS action gọi một action restricted
Phần tiêu đề “Whitelist: cho JS action gọi một action restricted”Cách cấu hình thường dùng là để action con ở chế độ restricted và chỉ cho JS action gọi nó. Khi đó người dùng chỉ dùng được action con thông qua JS action.
- Mở action con, tab Cài đặt & quyền, thẻ Quyền trên action (cần vai trò Admin).
- Chuyển Chế độ quyền sang
restricted — chỉ ai được cấpvà xác nhận. - Ở Cấp quyền chạy cho, chọn loại JS action, chọn JS action ở Chọn JS action…, sau đó bấm Cấp quyền.


Quyền cấp cho JS action chỉ có tác dụng khi action con ở chế độ restricted. Khi đó, JS action gọi được action con bằng quyền của người chạy JS action, còn người dùng không thấy action con ở trang Chạy action nếu không được cấp quyền riêng.
Editor vẫn thấy mọi action trong phần gợi ý của editor, kể cả action restricted. Action xuất hiện trong gợi ý chưa chắc gọi được: lời gọi chỉ thành công khi admin đã thêm JS action vào danh sách cấp quyền của action đó.
Kiểm tra khi publish
Phần tiêu đề “Kiểm tra khi publish”- Slug trong
executeActionphải là chuỗi cố định, ví dụexecuteAction('list-customers'). Slug ghép lúc chạy (executeAction(name)) bị từ chối, vì bước publish dựng đồ thị phụ thuộc từ chính đoạn code. - Mọi action được gọi phải tồn tại trong project.
- Không được có chu trình: nếu A gọi B và B gọi lại A (trực tiếp hoặc gián tiếp), publish bị từ chối và trang hiện đường đi, ví dụ
a → b → a.
Sau khi publish, action được JS action gọi không xoá được cho tới khi lời gọi đó được gỡ khỏi JS action.