UNPKG

@kevisual/noco

Version:

一个轻量级的 NocoDB API SDK,支持表记录操作和 Base 管理功能。

429 lines (422 loc) 10.1 kB
// src/record.ts var stystemFields = ["nc_order", "nc_created_by", "nc_updated_by"]; class Record { query; table; meta; constructor({ query, table, meta }) { this.query = query; this.table = table; this.meta = meta; } list(params = {}) { return this.query.makeRequest(`/api/v2/tables/${this.table}/records`, { method: "GET", params }); } create(data) { return this.query.makeRequest(`/api/v2/tables/${this.table}/records`, { method: "POST", data }); } read(id) { return this.query.makeRequest(`/api/v2/tables/${this.table}/records/${id}`, { method: "GET" }); } update(data) { return this.query.makeRequest(`/api/v2/tables/${this.table}/records`, { method: "PATCH", data }); } delete(data) { return this.query.makeRequest(`/api/v2/tables/${this.table}/records`, { method: "DELETE", data }); } count() { return this.query.makeRequest(`/api/v2/tables/${this.table}/records/count`, { method: "GET" }); } listLinks(linkFieldId, Id) { return this.query.makeRequest(`/api/v2/tables/${this.table}/links/${linkFieldId}/records/${Id}`, { method: "GET" }); } updateLinks(linkFieldId, Id, data) { return this.query.makeRequest(`/api/v2/tables/${this.table}/links/${linkFieldId}/records/${Id}`, { method: "POST", data }); } deleteLinks(linkFieldId, Id) { return this.query.makeRequest(`/api/v2/tables/${this.table}/links/${linkFieldId}/records/${Id}`, { method: "DELETE" }); } getTableMeta() { return this.meta.tables.getTableMeta(this.table); } async getTableSchema() { const res = await this.getTableMeta(); if (res.code === 200) { const columns = res.data.columns; const _columns = columns.filter((col) => !stystemFields.includes(col.title)).map((col) => ({ id: col.id, name: col.title, type: col.uidt, required: col.rqd, primary: col.pv, options: col.colOptions })); const schema = {}; for (const col of _columns) { schema[col.name] = { type: col.type, required: col.required, options: col.options }; } return { code: 200, data: { columns: _columns, schema } }; } return res; } } // src/api.ts class Query { baseURL; token; constructor({ baseURL, token }) { this.baseURL = baseURL; this.token = token; } makeRequest(endpoint, options) { const url = new URL(endpoint, this.baseURL); const isJson = options.json ?? true; const bodyIsFormData = options.isFromData || false; if (options.params) { Object.entries(options.params).forEach(([key, value]) => { url.searchParams.append(key, String(value)); }); } const method = options.method || "GET"; const headers = { "xc-token": `${this.token}`, ...options.headers }; if (!bodyIsFormData) { headers["Content-Type"] = "application/json"; } const fetchOptions = { method, headers }; if (options.body) { fetchOptions.body = options.body; } else if (options.data) { fetchOptions.body = JSON.stringify(options.data); } return fetch(url.href, fetchOptions).then(async (response) => { if (!response.ok) { return { code: response.status, message: response.statusText }; } if (isJson) { const result = await response.json(); const isArray = Array.isArray(result); if (isArray) { return { code: 200, data: { list: result } }; } else if (result && typeof result === "object" && !("code" in result)) { return { code: 200, data: result }; } return result; } return response; }); } } // src/meta/base.ts class MetaBases { query; constructor(options) { this.query = options?.query; } async list(workspaceId) { return this.query.makeRequest(`/api/v2/meta/workspaces/${workspaceId}/bases`, { method: "GET" }); } async create(data) { return this.query.makeRequest("/api/v2/meta/bases", { method: "POST", data }); } async get(baseId) { return this.query.makeRequest(`/api/v2/meta/bases/${baseId}`, { method: "GET" }); } } // src/meta/tables.ts class MetaTables { query; constructor(options) { this.query = options?.query; } async list(baseId) { return this.query.makeRequest(`/api/v2/meta/bases/${baseId}/tables`, { method: "GET" }); } async createTable(baseId, data) { return this.query.makeRequest(`/api/v2/meta/bases/${baseId}/tables`, { method: "POST", data }); } async getTableMeta(tableId) { return this.query.makeRequest(`/api/v2/meta/tables/${tableId}`, { method: "GET" }); } async createColumn(tableId, data) { return this.query.makeRequest(`/api/v2/meta/tables/${tableId}/columns`, { method: "POST", data }); } } // src/meta/webhook.ts class Webhook { query; constructor(options) { this.query = options?.query; } listTableWebhooks(tableId) { return this.query.makeRequest(`/api/v2/meta/tables/${tableId}/hooks`, { method: "GET" }); } createTableWebhook(tableId, data) { return this.query.makeRequest(`/api/v2/meta/tables/${tableId}/hooks`, { method: "POST", data: { version: "v3", event: "manual", ...data } }); } updateTableWebhook(hookId, data) { return this.query.makeRequest(`/api/v2/meta/hooks/${hookId}`, { method: "PUT", data }); } deleteTableWebhook(hookId) { return this.query.makeRequest(`/api/v2/meta/hooks/${hookId}`, { method: "DELETE" }); } } // src/meta/index.ts class Meta { query; bases; tables; webhooks; constructor(options) { 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 }); } } // src/data/upload.ts class Upload { query; constructor(query) { this.query = query; } async createUpload(opts) { const formData = new FormData; const { path, mimeType, file, size, title, url } = opts; if (url) { formData.append("url", url); } if (file) { formData.append("file", file, title); } if (path) { formData.append("path", path); } if (mimeType) { formData.append("mimetype", mimeType); } if (size) { formData.append("size", size.toString()); } if (title) { formData.append("title", title); } return await this.query.makeRequest("/api/v2/storage/upload", { method: "POST", body: formData, isFromData: true }); } } // src/main.ts class NocoApi { query; record; meta; upload; constructor(options) { const table = options?.table; const token = options?.token; const baseURL = options?.baseURL; this.query = new Query({ baseURL, token }); this.meta = new Meta({ query: this.query }); 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) { this.query.baseURL = url; } async getTableByName(table, baseId) { const res = await this.meta.tables.list(baseId); if (res.code === 200) { const tableMeta = res.data.list.find((t) => t.table_name === table); return tableMeta; } return null; } async createExampleTable(baseId, data) { 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)) { columns.push(col); } } const res = await this.meta.tables.createTable(baseId, { title: data?.title || "基本表", description: data?.description || "", columns }); return res; } } // src/meta/api-token.ts class ApiToken { query; constructor(options) { this.query = options?.query; } getTokenList(data) { return this.query.makeRequest(`/api/v2/meta/bases/${data.baseId}/api-tokens`, { method: "GET" }); } createToken(data) { return this.query.makeRequest(`/api/v2/meta/bases/${data.baseId}/api-tokens`, { method: "POST", data }); } deleteToken(data) { return this.query.makeRequest(`/api/v2/meta/bases/${data.baseId}/api-tokens/${data.tokenId}`, { method: "DELETE" }); } } // src/meta/users.ts class Users { query; constructor(options) { this.query = options?.query; } async listUsers(baseId) { return this.query.makeRequest(`api/v1/db/meta/projects/${baseId}/users`, { method: "GET" }); } async createUser(baseId, data) { return this.query.makeRequest(`/api/v1/db/meta/projects/${baseId}/users`, { method: "POST", data }); } async deleteUser(userId) { return this.query.makeRequest(`/api/v1/users/${userId}`, { method: "DELETE", headers: { "xc-gui": "true" } }); } } export { Webhook, Users, Upload, Record, Query, NocoApi, MetaBases, Meta, ApiToken };