This commit is contained in:
2025-12-12 11:38:05 +08:00
parent fc5b6fcc19
commit c4ae0bef19
8 changed files with 223 additions and 44 deletions

View File

@@ -16,6 +16,7 @@ type MakeRequestOptions = {
// body 优先级别高于 data // body 优先级别高于 data
isFromData?: boolean; isFromData?: boolean;
body?: any; body?: any;
headers?: Record<string, string>;
}; };
export class Query { export class Query {
baseURL: string; baseURL: string;
@@ -36,6 +37,7 @@ export class Query {
const method = options.method || 'GET'; const method = options.method || 'GET';
const headers: HeadersInit = { const headers: HeadersInit = {
'xc-token': `${this.token}`, 'xc-token': `${this.token}`,
...options.headers,
}; };
// 如果 body 不是 FormData才设置 Content-Type // 如果 body 不是 FormData才设置 Content-Type

View File

@@ -9,3 +9,7 @@ export * from './data/upload.ts';
export type { CreateColumnData, CreateTableData } from './meta/tables.ts'; export type { CreateColumnData, CreateTableData } from './meta/tables.ts';
export type { QueryParams } from './record.ts'; export type { QueryParams } from './record.ts';
export { ApiToken } from './meta/api-token.ts';
export { Users } from './meta/users.ts';

View File

@@ -23,34 +23,47 @@ export class NocoApi {
this.upload = new Upload(this.query); this.upload = new Upload(this.query);
this.record = new Record({ query: this.query, table, meta: this.meta }); this.record = new Record({ query: this.query, table, meta: this.meta });
} }
get baseURL() {
return this.query.baseURL;
}
set baseURL(url: string) {
this.query.baseURL = url;
}
/** /**
* *
* @param baseId * @param baseId
* @param data * @param data
*/ */
async createExampleTable(baseId: string, data?: ExampleTableData) { async createExampleTable(baseId: string, data?: ExampleTableData) {
const defaultColumns = [{ const defaultColumns = [
title: 'Title', {
title: 'Id',
uidt: "ID",
pk: true,
pv: true,
},
{
title: '标题',
uidt: 'SingleLineText', uidt: 'SingleLineText',
description: '标题列', description: '标题列',
}, },
{ {
title: 'Summary', title: '摘要',
uidt: 'LongText', uidt: 'LongText',
description: '摘要列', description: '摘要列',
}, },
{ {
title: 'Tags', title: '标签',
uidt: 'MultiSelect', uidt: 'MultiSelect',
description: '标签列', description: '标签列',
}, },
{ {
title: 'Description', title: '描述',
uidt: 'LongText', uidt: 'LongText',
description: '描述列', description: '描述列',
}, },
{ {
title: 'Link', title: '链接',
uidt: 'URL', uidt: 'URL',
description: '链接列', description: '链接列',
}] }]

31
src/meta/api-token.ts Normal file
View File

@@ -0,0 +1,31 @@
import { Query } from '../api.ts';
export type BaseOptions = {
query: Query;
};
export class ApiToken {
query: Query;
constructor(options?: BaseOptions) {
this.query = options?.query;
}
getTokenList(data: { baseId: string }) {
return this.query.makeRequest(`/api/v2/meta/bases/${data.baseId}/api-tokens`, {
method: 'GET',
});
}
createToken(data: { baseId?: string, description?: string; fk_user_id?: string }) {
// 创建 API Token
return this.query.makeRequest(`/api/v2/meta/bases/${data.baseId}/api-tokens`, {
method: 'POST',
data,
});
}
deleteToken(data: { baseId: string; tokenId: string }) {
return this.query.makeRequest(`/api/v2/meta/bases/${data.baseId}/api-tokens/${data.tokenId}`, {
method: 'DELETE',
});
}
}

View File

@@ -68,6 +68,8 @@ export type CreateColumnData = {
title: string; title: string;
uidt?: ColumnTypes uidt?: ColumnTypes
description?: string; description?: string;
/** id 自增的必填项 */
pk?: boolean;
/** /**
* 是否为主键 primay 的值 * 是否为主键 primay 的值
*/ */
@@ -92,18 +94,43 @@ export type CreateColumnData = {
meta?: Record<string, any>; meta?: Record<string, any>;
} }
export const columnTypes = [ export const columnTypes = [
'SingleLineText', 'SingleLineText', // 单行文本
'LongText', 'LongText', // 长文本
'URL', 'PhoneNumber', // 电话号码
'Email', 'Email', // 邮箱
'Number', 'URL', // 链接
'SingleSelect', 'Number', // 数字
'MultiSelect', 'Decimal', // 小数
'DateTime', 'Percent', // 百分比
'Time', 'Currency', // 货币
'Date', 'Duration', // 时长
'Checkbox', 'Date', // 日期
'JSON' 'Time', // 时间
'DateTime', // 日期时间
'Year', // 年份
'SingleSelect', // 单选
'MultiSelect', // 多选
'User', // 用户
'Attachment', // 附件
'Checkbox', // 复选框
'Rating', // 评分
'Button', // 按钮
'Formula', // 公式
'Barcode', // 条形码
'QRCode', // 二维码
'Links', // 链接关系
'LinkToAnotherRecord', // 关联记录
'Lookup', // 查找
'Rollup', // 汇总
'ID', // ID
'CreatedTime', // 创建时间
'LastModifiedTime', // 最后修改时间
'CreatedBy', // 创建者
'LastModifiedBy', // 最后修改者
'GeoData', // 地理数据
'Geometry', // 几何图形
'JSON', // JSON
'SpecificDBType' // 特定数据库类型
] as const; ] as const;
export type ColumnTypes = typeof columnTypes[number]; export type ColumnTypes = typeof columnTypes[number];

49
src/meta/users.ts Normal file
View File

@@ -0,0 +1,49 @@
import { Query, ResponseList } from '../api.ts';
type Options = {
query: Query;
};
export class Users {
query?: Query;
constructor(options?: Options) {
this.query = options?.query;
}
async listUsers(baseId?: string): Promise<ResponseList<UserItem>> {
// return this.query.makeRequest(`/api/v2/meta/bases/${baseId}/users`, {
// method: 'GET',
// });
return this.query.makeRequest(`api/v1/db/meta/projects/${baseId}/users`, {
method: 'GET',
});
}
async createUser(baseId: string, data: Partial<UserItem>): Promise<UserItem> {
// return this.query.makeRequest(`/api/v2/meta/bases/${baseId}/users`, {
return this.query.makeRequest(`/api/v1/db/meta/projects/${baseId}/users`, {
method: 'POST',
data,
});
}
async deleteUser(userId: string): Promise<{ code: number; message: string }> {
// return this.query.makeRequest(`/api/v2/meta/bases/${baseId}/users/${userId}`, {
return this.query.makeRequest(`/api/v1/users/${userId}`, {
method: 'DELETE',
headers: {
'xc-gui': 'true'
}
});
}
}
const userRoles = ['no-access', 'commenter', 'editor', 'guest', 'owner', 'viewer', 'creator'] as const;
type UserRole = typeof userRoles[number];
type UserItem = {
email: string;
display_name: string;
invite_token: string;
id: string;
meta?: any;
main_roles?: string;// org-level-creator,super
base_id?: string;
roles: UserRole;
created_at: string;
};

View File

@@ -1,9 +1,10 @@
import { NocoApi } from './../src/main.ts'; import { NocoApi, } from './../src/main.ts';
import { useConfig } from '@kevisual/use-config' import { useConfig } from '@kevisual/use-config'
import { CreateBaseData } from '../src/meta/index.ts'; import { CreateBaseData } from '../src/meta/index.ts';
export const config = useConfig() export const config = useConfig()
import util from 'node:util'; import util from 'node:util';
import { writeFile, writeFileSync } from 'node:fs'; import { writeFile, writeFileSync } from 'node:fs';
import { ApiToken, Users } from "./../src/index.ts"
// # 签到表 // # 签到表
// const table = 'mcby44q8zrayvn9' // const table = 'mcby44q8zrayvn9'
// 本地 // 本地
@@ -14,12 +15,23 @@ export const nocoApi = new NocoApi({
table, table,
}); });
export const apiToken = new ApiToken({
query: nocoApi.query,
});
export const showMore = (obj: any) => {
return util.inspect(obj, { depth: null, colors: true });
}
// const res = await nocoApi.record.list() // const res = await nocoApi.record.list()
// console.log(util.inspect(res.data, { depth: null, colors: true })) // console.log(util.inspect(res.data, { depth: null, colors: true }))
const res =await nocoApi.record.getTableMeta() // const res = await nocoApi.record.getTableMeta()
// console.log(util.inspect(res, { depth: null, colors: true })) // // console.log(util.inspect(res, { depth: null, colors: true }))
const keys = Object.keys(res.data || {}) // const keys = Object.keys(res.data || {})
console.log('表字段列表:', keys); // console.log('表字段列表:', keys);
writeFileSync('table-metadata.json', JSON.stringify(res, null, 2)); // writeFileSync('table-metadata.json', JSON.stringify(res, null, 2));
export const users = new Users({
query: nocoApi.query,
});

41
test/token.ts Normal file
View File

@@ -0,0 +1,41 @@
import { NocoApi, } from '../src/main.ts';
import { apiToken, showMore, nocoApi, config, users } from './common.ts'
const baseId = 'pypv3deh9qzol7q' // ai table base
const fk_user_id = 'usmdq13auglrp3w2';//
// const create = await apiToken.createToken({ baseId: baseId, description: '测试创建的 Token 用fk_user_id', fk_user_id })
// console.log('创建的 Token 信息:')
// console.log(showMore(create))
// id: 3
const main = async () => {
const aiTableToken = 'tetes'
const linkBaseId = 'pdzc3q50vwnng5r'
const linkTable = 'mxxwx8v5i45wd7o'
const nocoApi2 = new NocoApi({
baseURL: config.NOCODB_URL || 'http://localhost:8080',
token: aiTableToken,
table: linkTable,
});
const res = await nocoApi2.record.list()
console.log(showMore(res))
}
// main()
const userLIST = await users.listUsers(baseId)
console.log(showMore(userLIST))
// const user = await users.createUser(baseId, {
// email: 'kevisual@xiongxiao.me',
// roles: 'guest',
// })
// console.log('创建用户结果:')
// console.log(showMore(user))
const user = await users.deleteUser('usj8qbcns1uqm3ti')
console.log('删除用户结果:')
console.log(showMore(user))