update
This commit is contained in:
@@ -16,6 +16,7 @@ type MakeRequestOptions = {
|
||||
// body 优先级别高于 data
|
||||
isFromData?: boolean;
|
||||
body?: any;
|
||||
headers?: Record<string, string>;
|
||||
};
|
||||
export class Query {
|
||||
baseURL: string;
|
||||
@@ -36,6 +37,7 @@ export class Query {
|
||||
const method = options.method || 'GET';
|
||||
const headers: HeadersInit = {
|
||||
'xc-token': `${this.token}`,
|
||||
...options.headers,
|
||||
};
|
||||
|
||||
// 如果 body 不是 FormData,才设置 Content-Type
|
||||
|
||||
@@ -8,4 +8,8 @@ export * from './data/upload.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';
|
||||
63
src/main.ts
63
src/main.ts
@@ -23,37 +23,50 @@ export class NocoApi {
|
||||
this.upload = new Upload(this.query);
|
||||
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 data
|
||||
*/
|
||||
async createExampleTable(baseId: string, data?: ExampleTableData) {
|
||||
const defaultColumns = [{
|
||||
title: 'Title',
|
||||
uidt: 'SingleLineText',
|
||||
description: '标题列',
|
||||
},
|
||||
{
|
||||
title: 'Summary',
|
||||
uidt: 'LongText',
|
||||
description: '摘要列',
|
||||
},
|
||||
{
|
||||
title: 'Tags',
|
||||
uidt: 'MultiSelect',
|
||||
description: '标签列',
|
||||
},
|
||||
{
|
||||
title: 'Description',
|
||||
uidt: 'LongText',
|
||||
description: '描述列',
|
||||
},
|
||||
{
|
||||
title: 'Link',
|
||||
uidt: 'URL',
|
||||
description: '链接列',
|
||||
}]
|
||||
const defaultColumns = [
|
||||
{
|
||||
title: 'Id',
|
||||
uidt: "ID",
|
||||
pk: true,
|
||||
pv: true,
|
||||
},
|
||||
{
|
||||
title: '标题',
|
||||
uidt: 'SingleLineText',
|
||||
description: '标题列',
|
||||
},
|
||||
{
|
||||
title: '摘要',
|
||||
uidt: 'LongText',
|
||||
description: '摘要列',
|
||||
},
|
||||
{
|
||||
title: '标签',
|
||||
uidt: 'MultiSelect',
|
||||
description: '标签列',
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
uidt: 'LongText',
|
||||
description: '描述列',
|
||||
},
|
||||
{
|
||||
title: '链接',
|
||||
uidt: 'URL',
|
||||
description: '链接列',
|
||||
}]
|
||||
const columns = data?.columns || [];
|
||||
for (const col of defaultColumns) {
|
||||
if (!columns.find(c => c.title === col.title)) {
|
||||
|
||||
31
src/meta/api-token.ts
Normal file
31
src/meta/api-token.ts
Normal 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',
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -68,6 +68,8 @@ export type CreateColumnData = {
|
||||
title: string;
|
||||
uidt?: ColumnTypes
|
||||
description?: string;
|
||||
/** id 自增的必填项 */
|
||||
pk?: boolean;
|
||||
/**
|
||||
* 是否为主键 primay 的值
|
||||
*/
|
||||
@@ -92,18 +94,43 @@ export type CreateColumnData = {
|
||||
meta?: Record<string, any>;
|
||||
}
|
||||
export const columnTypes = [
|
||||
'SingleLineText',
|
||||
'LongText',
|
||||
'URL',
|
||||
'Email',
|
||||
'Number',
|
||||
'SingleSelect',
|
||||
'MultiSelect',
|
||||
'DateTime',
|
||||
'Time',
|
||||
'Date',
|
||||
'Checkbox',
|
||||
'JSON'
|
||||
'SingleLineText', // 单行文本
|
||||
'LongText', // 长文本
|
||||
'PhoneNumber', // 电话号码
|
||||
'Email', // 邮箱
|
||||
'URL', // 链接
|
||||
'Number', // 数字
|
||||
'Decimal', // 小数
|
||||
'Percent', // 百分比
|
||||
'Currency', // 货币
|
||||
'Duration', // 时长
|
||||
'Date', // 日期
|
||||
'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;
|
||||
|
||||
export type ColumnTypes = typeof columnTypes[number];
|
||||
|
||||
49
src/meta/users.ts
Normal file
49
src/meta/users.ts
Normal 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;
|
||||
};
|
||||
@@ -1,9 +1,10 @@
|
||||
import { NocoApi } from './../src/main.ts';
|
||||
import { NocoApi, } from './../src/main.ts';
|
||||
import { useConfig } from '@kevisual/use-config'
|
||||
import { CreateBaseData } from '../src/meta/index.ts';
|
||||
export const config = useConfig()
|
||||
import util from 'node:util';
|
||||
import { writeFile, writeFileSync } from 'node:fs';
|
||||
import { ApiToken, Users } from "./../src/index.ts"
|
||||
// # 签到表
|
||||
// const table = 'mcby44q8zrayvn9'
|
||||
// 本地
|
||||
@@ -14,12 +15,23 @@ export const nocoApi = new NocoApi({
|
||||
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()
|
||||
// console.log(util.inspect(res.data, { depth: null, colors: true }))
|
||||
|
||||
const res =await nocoApi.record.getTableMeta()
|
||||
// console.log(util.inspect(res, { depth: null, colors: true }))
|
||||
const keys = Object.keys(res.data || {})
|
||||
console.log('表字段列表:', keys);
|
||||
writeFileSync('table-metadata.json', JSON.stringify(res, null, 2));
|
||||
// const res = await nocoApi.record.getTableMeta()
|
||||
// // console.log(util.inspect(res, { depth: null, colors: true }))
|
||||
// const keys = Object.keys(res.data || {})
|
||||
// console.log('表字段列表:', keys);
|
||||
// writeFileSync('table-metadata.json', JSON.stringify(res, null, 2));
|
||||
|
||||
|
||||
export const users = new Users({
|
||||
query: nocoApi.query,
|
||||
});
|
||||
41
test/token.ts
Normal file
41
test/token.ts
Normal 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))
|
||||
Reference in New Issue
Block a user