noco 天津webhooks的模块

This commit is contained in:
2025-11-29 11:39:59 +08:00
parent 22c1db570c
commit 420612501e
7 changed files with 197 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@kevisual/noco",
"version": "0.0.4",
"version": "0.0.5",
"description": "",
"main": "index.js",
"scripts": {
@@ -21,7 +21,7 @@
],
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
"license": "MIT",
"packageManager": "pnpm@10.23.0",
"packageManager": "pnpm@10.24.0",
"type": "module",
"devDependencies": {
"@kevisual/dts": "^0.0.3",

4
pnpm-lock.yaml generated
View File

@@ -7,10 +7,6 @@ settings:
importers:
.:
dependencies:
form-data:
specifier: ^4.0.5
version: 4.0.5
devDependencies:
'@kevisual/dts':
specifier: ^0.0.3

View File

@@ -53,6 +53,7 @@ export class Query {
fetchOptions.body = JSON.stringify(options.data);
}
return fetch(url.href, fetchOptions).then(async (response) => {
console.log('Response Status:', response.status, response);
if (!response.ok) {
return { code: response.status, message: response.statusText };
}

View File

@@ -1,6 +1,7 @@
import { Query } from '../api.ts';
import { MetaBases, BaseOptions } from './base.ts';
import { MetaTables } from './tables.ts';
import { Webhook } from './webhook.ts';
export type MetaOptions = {
query: Query;
};
@@ -13,12 +14,16 @@ export class Meta {
query: Query;
bases: MetaBases;
tables: MetaTables;
webhooks: Webhook;
constructor(options?: MetaOptions) {
this.query = options?.query;
this.query = options?.query;
this.bases = new MetaBases({ query: this.query });
this.tables = new MetaTables({ query: this.query });
this.webhooks = new Webhook({ query: this.query });
}
}
// 重新导出所有 meta 相关的类型和类
export * from './base.ts';
export * from './base.ts';
export * from './webhook.ts';

139
src/meta/webhook.ts Normal file
View File

@@ -0,0 +1,139 @@
import { Query, ResponseList } from '../api.ts';
export type WebhookOptions = {
query: Query;
};
export class Webhook {
private query?: Query;
constructor(options?: WebhookOptions) {
this.query = options?.query;
}
listTableWebhooks(tableId: string): Promise<ResponseList<WebhookItem>> {
return this.query.makeRequest(
`/api/v2/meta/tables/${tableId}/hooks`,
{
method: 'GET',
}
);
}
createTableWebhook(
tableId: string,
data: WebhookItemCore
): Promise<any> {
return this.query.makeRequest(
`/api/v2/meta/tables/${tableId}/hooks`,
{
method: 'POST',
data: {
version: 'v3',
event: 'manual',
...data,
},
}
);
}
updateTableWebhook(
hookId: string,
data: WebhookItemCore
): Promise<any> {
return this.query.makeRequest(
`/api/v2/meta/hooks/${hookId}`,
{
method: 'PUT',
data,
}
);
}
deleteTableWebhook(hookId: string): Promise<any> {
return this.query.makeRequest(
`/api/v2/meta/hooks/${hookId}`,
{
method: 'DELETE',
}
);
}
}
const operations = ['insert', 'update', 'delete', 'bulk_insert', 'bulk_update', 'bulk_delete'];
type WebhookOperation = typeof operations[number];
/**
* Webhook 项目类型定义
*/
export type WebhookItem = {
id: string;
source_id: string;
base_id: string;
fk_model_id: string;
title: string;
description: string;
env: string; // 'all'
type: 'manual' | null;
operation: WebhookOperation[];
async: boolean;
payload: boolean;
url: string;
headers: Record<string, string>;
condition: boolean;
notification: string;
retries: number;
retry_interval: number;
timeout: number;
active: boolean;
created_at: string;
updated_at: string;
version: string; // 'v3'
trigger_field: boolean;
trigger_fields: any[];
};
export type WebhookItemCore = {
id?: string;
title: string;
description?: string | null;
operation: WebhookOperation | WebhookOperation[];
/**
* Webhook 触发的 json的
* 不能为空对象
* @example '{"type":"URL","include_user":false,"payload":{"method":"POST","body":"{{ json event }}","headers":[{"enabled":false,"name":"","value":""}],"parameters":[{"enabled":false,"name":"tableId","value":"mecdgojq151iwk9"}],"path":"https://kevision.xiongxiao.me/api/router","auth":""},"trigger_form":false}'
*/
notification: string | Record<string, any>;
/**
* 内置必填
*/
event: string; // after | 'manual',
/**
* 内置必填
*/
version?: string; // 'v3'
/**
* 是否启用
*/
active?: boolean;
}
export type WebhookNotification = {
type: 'URL' | 'Email' | 'DingTalk' | 'WeCom' | 'FeiShu';
include_user: boolean;
payload: {
method: 'POST' | 'GET' | 'PUT' | 'DELETE' | 'PATCH';
/**
* 请求体
* {{ json event }}
*/
body: string;
headers: Array<{
enabled: boolean;
name: string;
value: string;
}>;
parameters: Array<{
enabled: boolean;
name: string;
value: string;
}>;
path: string;
auth: string;
};
trigger_form: boolean;
}

View File

@@ -5,7 +5,7 @@ import util from 'node:util';
// # 签到表
// const table = 'mcby44q8zrayvn9'
// 本地
const table = 'mi89er1m951pb3g'
const table = 'mecdgojq151iwk9'
export const nocoApi = new NocoApi({
baseURL: config.NOCODB_URL || 'http://localhost:8080',
token: config.NOCODB_API_KEY || '',

47
test/list-hook.ts Normal file
View File

@@ -0,0 +1,47 @@
import { nocoApi } from "./common";
import bun from 'bun'
import util from 'node:util'
const tableId = 'mecdgojq151iwk9'; // starred_repos
const res = await nocoApi.meta.webhooks.listTableWebhooks(tableId);
console.log('表格 Webhook 列表:');
console.log(util.inspect(res, { depth: null }));
// {
// id: 'hkc9lp4n3w7co4l6',
// source_id: 'bdva8kahx60lu45',
// base_id: 'pdzc3q50vwnng5r',
// fk_model_id: 'mecdgojq151iwk9',
// title: '更新列表',
// description: null,
// env: 'all',
// type: null,
// event: 'after',
// operation: [ 'insert', 'update', 'delete' ],
// async: false,
// payload: true,
// url: null,
// headers: null,
// condition: false,
// notification: '{"type":"URL","include_user":false,"payload":{"method":"POST","body":"{{ json event }}","headers":[{"enabled":false,"name":"","value":""}],"parameters":[{"enabled":false,"name":"tableId","value":"mecdgojq151iwk9"}],"path":"https://kevision.xiongxiao.me/api/router","auth":""},"trigger_form":false}',
// retries: 0,
// retry_interval: 60000,
// timeout: 60000,
// active: true,
// created_at: '2025-11-29 01:57:05+00:00',
// updated_at: '2025-11-29 02:05:31+00:00',
// version: 'v3',
// trigger_field: false,
// trigger_fields: []
// }
const hookNotify = { "type": "URL", "include_user": false, "payload": { "method": "POST", "body": "{{ json event }}", "headers": [{ "enabled": false, "name": "", "value": "" }], "parameters": [{ "enabled": false, "name": "tableId", "value": "mecdgojq151iwk9" }], "path": "https://kevision.xiongxiao.me/api/router", "auth": "" }, "trigger_form": false }
const createHook = await nocoApi.meta.webhooks.createTableWebhook(tableId, {
title: '测试通过 API 创建的 Webhook2',
// operation: ['insert', 'update', 'delete'],
operation: ['insert', 'update', 'delete'],
notification: hookNotify,
event: 'manual',
});
console.log('创建 Webhook 结果:');
console.log(util.inspect(createHook, { depth: null }));