UNPKG

@pagenote/notion-database

Version:

make notion as a real-database for server

303 lines 12.2 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const client_1 = require("@notionhq/client"); const utils_1 = require("./common/utils"); const util_1 = require("./transformer/util"); const const_1 = require("./common/const"); const table_1 = require("./notion-helper/table"); const page_1 = require("./notion-helper/page"); class Table { constructor(option) { this.demoPropertiesSchema = {}; this.demoData = null; this.option = option; this.shortDatabaseId = (0, utils_1.simpleFyId)(option.database_id); this.parentPageId = (0, utils_1.simpleFyId)(option.parentPageId || ''); this.notion = option.notion || new client_1.Client({ auth: option.token }); this.cloudPropertiesSchema = option.cloudDescribe; this.connected = false; this._setDemoData(option.demoData); this.onError = option.onError; } _reformatCloudPropertiesByDemoData(data) { return this._formatCloudProperties((0, util_1.defineNotionPropertySchemaByData)(data, false)); } // 格式化字段 _formatCloudProperties(tablePropertiesDesc) { return this.notion.databases .update({ database_id: this.shortDatabaseId, properties: tablePropertiesDesc }) .then(res => { this.cloudPropertiesSchema = res.properties; }); } _syncProperties() { return this.notion.databases .retrieve({ database_id: this.shortDatabaseId }) .then(res => { var _a; this.connected = true; this.cloudPropertiesSchema = res.properties; // @ts-ignore this.parentPageId = (_a = res === null || res === void 0 ? void 0 : res.parent) === null || _a === void 0 ? void 0 : _a.page_id; }); } _setDemoData(data) { this.demoData = data || this.demoData; if (this.demoData) { this.demoPropertiesSchema = (0, util_1.defineNotionPropertySchemaByData)(this.demoData, true); } } _getValidDataBySchema(data, forceAddByModifyTable) { var _a; return __awaiter(this, void 0, void 0, function* () { if (!this.cloudPropertiesSchema) { yield this.ready(); // 尝试一次重新拉取后,仍然没有表信息,则报错 if (!this.cloudPropertiesSchema) { return Promise.reject('无法获取远端表信息,请重试'); } } const properties = (0, table_1.dataToNotionProperties)(data, this.cloudPropertiesSchema, this.demoPropertiesSchema); const updatePropertyMap = (0, util_1.defineNotionPropertySchemaByData)({}, false); for (let key in properties) { // 当前表中不存在的字段需要新增 const tempData = this.cloudPropertiesSchema[key]; if (!tempData) { // 强制添加数据 if (forceAddByModifyTable && this.demoPropertiesSchema && this.demoPropertiesSchema[key]) { updatePropertyMap[key] = this.demoPropertiesSchema[key]; } else { console.warn(`远端字段 ${key} 不存在,将被过滤。如需强制添加,请定义本地表结构 demoData`, forceAddByModifyTable, this.demoPropertiesSchema); delete properties[key]; } // @ts-ignore 可能不存在 type } else if ((tempData === null || tempData === void 0 ? void 0 : tempData.type) !== ((_a = properties[key]) === null || _a === void 0 ? void 0 : _a.type)) { console.error('数据类型不一致,可能异常', key, properties[key]); } } if (Object.keys(updatePropertyMap).length > 0) { console.warn('本次添加有未知字段,将修改表结构', updatePropertyMap); yield this._formatCloudProperties(updatePropertyMap); } return properties; }); } _commentError(error, pageId) { this.onError && this.onError(this.shortDatabaseId, error); const errorMsg = error.toString() + `:[${new Date().toLocaleTimeString()}]`; if (pageId) { (0, page_1.updatePageInfo)(this.notion, pageId, { icon: const_1.TableEmoji.error }); } else { (0, page_1.updateTableInfo)(this.notion, this.shortDatabaseId, { description: errorMsg, emoji: const_1.TableEmoji.error }); } } ready() { if (this.connected) { return Promise.resolve(this); } else { return this._syncProperties().then(() => { return this; }); } } add(data, forceAddByModifyTable = false) { return __awaiter(this, void 0, void 0, function* () { const properties = yield this._getValidDataBySchema(data, forceAddByModifyTable); const iconString = (data.icon || '').toString(); const icon = /^http/.test(iconString) ? { type: 'external', external: { url: iconString } } : { emoji: '✅', type: 'emoji' }; return this.notion.pages .create({ parent: { database_id: this.shortDatabaseId, type: 'database_id' }, icon: icon, properties: properties }) .then(function (response) { const res = response; return (0, page_1.formatNotionPageDocument)(res); }) .catch(reason => { this._commentError.call(this, reason); throw reason; }); }); } // 批注错误信息 // TODO 分页器优化 query(data, sorts, pagination, filterProperty) { return __awaiter(this, void 0, void 0, function* () { const properties = (0, table_1.dataToNotionFilter)(data, this.cloudPropertiesSchema || this.demoPropertiesSchema); return this.notion.databases .query({ database_id: this.shortDatabaseId, sorts: sorts || [], filter: properties, archived: false, page_size: (pagination === null || pagination === void 0 ? void 0 : pagination.page_size) || const_1.QUERY_LIMIT_MAX, start_cursor: pagination === null || pagination === void 0 ? void 0 : pagination.start_cursor, filter_properties: filterProperty }) .then(function (res) { const dataList = (res.results || []).map(function (item) { const temp = item; return (0, page_1.formatNotionPageDocument)(temp); }); res._list = dataList; return res; }) .catch(reason => { this._commentError.call(this, reason); throw reason; }); }); } queryAll(finder) { return __awaiter(this, void 0, void 0, function* () { const that = this; function query(list, startCursor) { var _a; return __awaiter(this, void 0, void 0, function* () { const result = yield that.query(finder.filter, finder.sorts, { page_size: ((_a = finder.pagination) === null || _a === void 0 ? void 0 : _a.page_size) || const_1.QUERY_LIMIT_MAX, start_cursor: startCursor }); result._list = [...list, ...(result._list || [])]; if (result.has_more) { return query(result._list, result.next_cursor || undefined); } return result; }); } return query([]); }); } delete(query) { var _a; return __awaiter(this, void 0, void 0, function* () { let ids = []; if (Array.isArray(query)) { ids = query; } else { const res = yield this.query(query); ids = (_a = res.results) === null || _a === void 0 ? void 0 : _a.map(function (item) { return item.id; }); } const tasks = []; ids.forEach(item => { tasks.push(this.notion.pages .update({ page_id: item, archived: true }) .catch(reason => { this._commentError(reason, item); throw reason; })); }); const result = (yield Promise.all(tasks)); let count = 0; result.forEach(function (res) { if (res === null || res === void 0 ? void 0 : res.archived) { count++; } }); return count; }); } deleteOne(pageId) { return __awaiter(this, void 0, void 0, function* () { return this.notion.pages .update({ page_id: pageId, archived: true }) .then(function (res) { return res.archived; }); }); } batchUpdate(query, data, option) { return __awaiter(this, void 0, void 0, function* () { const list = yield this.query(query); const tasks = []; // TODO 等待官方批量更新接口,目前仅能循环调用 list.results.forEach(item => { tasks.push(this.updateOne(item.id, data)); }); if (list.results.length === 0 && (option === null || option === void 0 ? void 0 : option.upsert) === true) { return this.add(data, true).then(function (res) { return [res]; }); } return Promise.all(tasks).then(function (res) { return res; }); }); } updateOne(pageId, data) { return __awaiter(this, void 0, void 0, function* () { const properties = (yield this._getValidDataBySchema(data, false)); return this.notion.pages .update({ page_id: pageId, properties: properties, icon: { type: 'emoji', emoji: const_1.TableEmoji.success } }) .then(function (item) { return (0, page_1.formatNotionPageDocument)(item); }) .catch(reason => { this._commentError(reason, pageId); throw reason; }); }); } } exports.default = Table; //# sourceMappingURL=Table.js.map