@pagenote/notion-database
Version:
make notion as a real-database for server
303 lines • 12.2 kB
JavaScript
"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