plugin list: list registered plugins (id/name/status/runtimeType) plugin register: register by URL (--name --url --positions) plugin config list: list base configs (pluginId/tableId/enabled/form/write) plugin config enable/disable: enable/disable per table or base-wide Added 5 client methods: getPlugins, registerPlugin, listPluginConfigs, upsertPluginConfig for CRUD.
225 lines
8.5 KiB
JavaScript
225 lines
8.5 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.ApiError = exports.Client = void 0;
|
|
/**
|
|
* High-level API client. Each method maps to one REST endpoint of the
|
|
* inkreach-teable backend, using the SELF-BUILT contract (not official teable).
|
|
*
|
|
* Base/table/field/record/view endpoints are compatible with official teable
|
|
* open-api; workflow/automation endpoints use the project's own contract.
|
|
*/
|
|
const request_1 = require("./request");
|
|
Object.defineProperty(exports, "ApiError", { enumerable: true, get: function () { return request_1.ApiError; } });
|
|
class Client {
|
|
cfg;
|
|
constructor(cfg) {
|
|
this.cfg = cfg;
|
|
}
|
|
get headers() {
|
|
return this.cfg.token ? { Authorization: `Bearer ${this.cfg.token}` } : {};
|
|
}
|
|
async call(method, p, body) {
|
|
const res = await (0, request_1.request)(this.cfg.endpoint, p, { method, headers: this.headers, body });
|
|
return res.data;
|
|
}
|
|
// ---- auth / user ----
|
|
getMe() {
|
|
// GET /api/auth/user — @TokenAccess() enabled, works with PAT.
|
|
// (/api/auth/user/me is session-only and 403s for PAT.)
|
|
return this.call('GET', '/api/auth/user');
|
|
}
|
|
// ---- access tokens (PAT) ----
|
|
listAccessTokens() {
|
|
return this.call('GET', '/api/access-token');
|
|
}
|
|
createAccessToken(body) {
|
|
return this.call('POST', '/api/access-token', body);
|
|
}
|
|
deleteAccessToken(id) {
|
|
return this.call('DELETE', `/api/access-token/${id}`);
|
|
}
|
|
// ---- base ----
|
|
listBases() {
|
|
// GET /api/base/access/all — lists bases the user can access.
|
|
return this.call('GET', '/api/base/access/all');
|
|
}
|
|
getBase(baseId) {
|
|
return this.call('GET', `/api/base/${baseId}`);
|
|
}
|
|
// ---- table ----
|
|
listTables(baseId) {
|
|
return this.call('GET', `/api/base/${baseId}/table`);
|
|
}
|
|
getTable(tableId) {
|
|
return this.call('GET', `/api/table/${tableId}`);
|
|
}
|
|
createTable(baseId, body) {
|
|
return this.call('POST', `/api/base/${baseId}/table`, body);
|
|
}
|
|
updateTable(tableId, body) {
|
|
return this.call('PUT', `/api/table/${tableId}`, body);
|
|
}
|
|
deleteTable(tableId) {
|
|
return this.call('DELETE', `/api/table/${tableId}`);
|
|
}
|
|
// ---- field ----
|
|
listFields(tableId) {
|
|
return this.call('GET', `/api/table/${tableId}/field`);
|
|
}
|
|
getField(fieldId) {
|
|
return this.call('GET', `/api/field/${fieldId}`);
|
|
}
|
|
createField(tableId, body) {
|
|
return this.call('POST', `/api/table/${tableId}/field`, body);
|
|
}
|
|
updateField(fieldId, body) {
|
|
return this.call('PUT', `/api/field/${fieldId}`, body);
|
|
}
|
|
deleteField(fieldId) {
|
|
return this.call('DELETE', `/api/field/${fieldId}`);
|
|
}
|
|
// ---- record ----
|
|
getRecords(tableId, query) {
|
|
const qs = query ? '?' + new URLSearchParams(this.flattenQuery(query)).toString() : '';
|
|
return this.call('GET', `/api/table/${tableId}/record${qs}`);
|
|
}
|
|
/** Flatten search[] tuple arrays into repeated query keys (Teable expects search[]=...). */
|
|
flattenQuery(query) {
|
|
const out = {};
|
|
for (const [k, v] of Object.entries(query)) {
|
|
if (v === undefined || v === null)
|
|
continue;
|
|
if (Array.isArray(v)) {
|
|
v.forEach((item) => {
|
|
out[`${k}[]`] = typeof item === 'object' ? JSON.stringify(item) : String(item);
|
|
});
|
|
}
|
|
else if (typeof v === 'object') {
|
|
out[k] = JSON.stringify(v);
|
|
}
|
|
else {
|
|
out[k] = String(v);
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
getRecord(recordId, query) {
|
|
const qs = query ? '?' + new URLSearchParams(this.flattenQuery(query)).toString() : '';
|
|
return this.call('GET', `/api/record/${recordId}${qs}`);
|
|
}
|
|
createRecord(tableId, body) {
|
|
return this.call('POST', `/api/table/${tableId}/record`, body);
|
|
}
|
|
updateRecord(tableId, body) {
|
|
return this.call('PATCH', `/api/table/${tableId}/record`, body);
|
|
}
|
|
updateRecordOne(recordId, body) {
|
|
return this.call('PATCH', `/api/record/${recordId}`, body);
|
|
}
|
|
deleteRecord(tableId, body) {
|
|
return this.call('DELETE', `/api/table/${tableId}/record`, body);
|
|
}
|
|
// ---- view ----
|
|
listViews(tableId) {
|
|
return this.call('GET', `/api/table/${tableId}/view`);
|
|
}
|
|
getView(viewId) {
|
|
return this.call('GET', `/api/view/${viewId}`);
|
|
}
|
|
createView(tableId, body) {
|
|
return this.call('POST', `/api/table/${tableId}/view`, body);
|
|
}
|
|
updateView(viewId, body) {
|
|
return this.call('PATCH', `/api/view/${viewId}`, body);
|
|
}
|
|
deleteView(viewId) {
|
|
return this.call('DELETE', `/api/view/${viewId}`);
|
|
}
|
|
// ---- workflow (self-built contract) ----
|
|
listWorkflows(baseId) {
|
|
return this.call('GET', `/api/base/${baseId}/workflow`);
|
|
}
|
|
getWorkflow(workflowId) {
|
|
return this.call('GET', `/api/base/any/workflow/${workflowId}`);
|
|
}
|
|
/**
|
|
* Get workflow by explicit baseId + workflowId. getWorkflow() above hits a
|
|
* route that resolves base from the workflow itself, but some auth/permission
|
|
* paths need the base-scoped route. Prefer this when baseId is known.
|
|
*/
|
|
getWorkflowInBase(baseId, workflowId) {
|
|
return this.call('GET', `/api/base/${baseId}/workflow/${workflowId}`);
|
|
}
|
|
createWorkflow(baseId, body) {
|
|
return this.call('POST', `/api/base/${baseId}/workflow`, body);
|
|
}
|
|
updateWorkflow(baseId, workflowId, body) {
|
|
return this.call('PATCH', `/api/base/${baseId}/workflow/${workflowId}`, body);
|
|
}
|
|
deleteWorkflow(baseId, workflowId) {
|
|
return this.call('DELETE', `/api/base/${baseId}/workflow/${workflowId}`);
|
|
}
|
|
activateWorkflow(baseId, workflowId) {
|
|
return this.call('POST', `/api/base/${baseId}/workflow/${workflowId}/activate`);
|
|
}
|
|
deactivateWorkflow(baseId, workflowId) {
|
|
return this.call('POST', `/api/base/${baseId}/workflow/${workflowId}/deactivate`);
|
|
}
|
|
testWorkflow(baseId, workflowId) {
|
|
return this.call('POST', `/api/base/${baseId}/workflow/${workflowId}/test`);
|
|
}
|
|
/** PUT /node — whole-graph replacement (delete-all + create-all in a txn). */
|
|
replaceNodes(baseId, workflowId, body) {
|
|
return this.call('PUT', `/api/base/${baseId}/workflow/${workflowId}/node`, body);
|
|
}
|
|
// ---- secrets ----
|
|
listSecrets(baseId, workflowId) {
|
|
return this.call('GET', `/api/base/${baseId}/workflow/${workflowId}/secret`);
|
|
}
|
|
createSecret(baseId, workflowId, body) {
|
|
return this.call('POST', `/api/base/${baseId}/workflow/${workflowId}/secret`, body);
|
|
}
|
|
updateSecret(baseId, workflowId, secretId, body) {
|
|
return this.call('PATCH', `/api/base/${baseId}/workflow/${workflowId}/secret/${secretId}`, body);
|
|
}
|
|
deleteSecret(baseId, workflowId, secretId) {
|
|
return this.call('DELETE', `/api/base/${baseId}/workflow/${workflowId}/secret/${secretId}`);
|
|
}
|
|
// ---- execution history ----
|
|
listExecutions(baseId, workflowId) {
|
|
return this.call('GET', `/api/base/${baseId}/workflow/${workflowId}/execution`);
|
|
}
|
|
getExecution(baseId, workflowId, executionId) {
|
|
return this.call('GET', `/api/base/${baseId}/workflow/${workflowId}/execution/${executionId}`);
|
|
}
|
|
rerunExecution(baseId, workflowId, executionId) {
|
|
return this.call('POST', `/api/base/${baseId}/workflow/${workflowId}/execution/${executionId}/rerun`);
|
|
}
|
|
// ---- trigger (manual fire for testing) ----
|
|
fireButtonClick(tableId, recordId, fieldId) {
|
|
return this.call('POST', `/api/table/${tableId}/record/${recordId}/${fieldId}/button-click`);
|
|
}
|
|
fireWebhook(baseId, workflowId, body) {
|
|
// NOTE: real backend route is /api/webhook/{baseId}/{workflowId} (no /base/ /workflow/ segments)
|
|
return this.call('POST', `/api/webhook/${baseId}/${workflowId}`, body);
|
|
}
|
|
// ---- SQL (read-only) ----
|
|
sql(baseId, sql) {
|
|
return this.call('POST', `/api/base/${baseId}/sql`, { sql });
|
|
}
|
|
// ---- plugin ----
|
|
getPlugins() {
|
|
return this.call('GET', '/api/plugin');
|
|
}
|
|
registerPlugin(body) {
|
|
return this.call('POST', '/api/plugin', body);
|
|
}
|
|
listPluginConfigs(baseId) {
|
|
return this.call('GET', `/api/base/${baseId}/plugin-config`);
|
|
}
|
|
upsertPluginConfig(baseId, pluginId, body) {
|
|
return this.call('PUT', `/api/base/${baseId}/plugin-config/${pluginId}`, body);
|
|
}
|
|
}
|
|
exports.Client = Client;
|