update
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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';
|
||||||
25
src/main.ts
25
src/main.ts
@@ -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
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;
|
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
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 { 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
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