motionlink-cli
Version:
Making it easy to use Notion as a Content Management system for personal websites, portfolios, blogs, business homepages, and other kinds of static websites.
289 lines • 12.3 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __asyncValues = (this && this.__asyncValues) || function (o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TemplateRuleBuilder = exports.SecondaryDatabasesFetcher = exports.DatabaseFetcher = exports.BlockChildrenFetcher = exports.TemplateRuleOutputWriter = exports.CachingFileReader = exports.DatabaseAssociationFinder = exports.FileExtensionFinder = exports.newBuildService = void 0;
const notion_service_1 = __importDefault(require("./notion_service"));
const file_system_service_1 = __importDefault(require("./file_system_service"));
const mustache_service_1 = __importDefault(require("./mustache_service"));
const markdown_service_1 = __importStar(require("./markdown_service"));
const post_processing_service_1 = __importDefault(require("./post_processing_service"));
function newBuildService() {
return new BuildServiceImpl();
}
exports.newBuildService = newBuildService;
class BuildServiceImpl {
async build(templateRules, databaseAssociations) {
for (const rule of templateRules) {
await this.makeTemplateRuleBuilder().build(rule, databaseAssociations);
}
}
makeTemplateRuleBuilder() {
const fileExtensionFinder = new FileExtensionFinder();
const cachingFileReader = new CachingFileReader();
const templateRuleOutputWriter = new TemplateRuleOutputWriter()
.setFileExtensionFinder(fileExtensionFinder)
.setCachingFileReader(cachingFileReader);
const blockChildrenFetcher = new BlockChildrenFetcher();
const databaseFetcher = new DatabaseFetcher().setBlockChildrenFether(blockChildrenFetcher);
const databaseAssociationFinder = new DatabaseAssociationFinder();
const secondaryDatabasesFetcher = new SecondaryDatabasesFetcher()
.setDatabaseFetcher(databaseFetcher)
.setDatabaseAssociationFinder(databaseAssociationFinder);
return new TemplateRuleBuilder()
.setSecondaryDatabasesFetcher(secondaryDatabasesFetcher)
.setDatabaseFetcher(databaseFetcher)
.setTemplateRuleOutputWriter(templateRuleOutputWriter)
.setDatabaseAssociationFinder(databaseAssociationFinder);
}
}
class FileExtensionFinder {
findFileExtensionOf(path) {
const index = path.lastIndexOf('.');
if (index < 0)
return '';
return path.substring(index);
}
}
exports.FileExtensionFinder = FileExtensionFinder;
class DatabaseAssociationFinder {
findDatabaseAssociationFor(rule, databaseAssociations) {
const filtered = databaseAssociations.filter((association) => association.name === rule.database);
if (filtered.length === 0)
throw new Error(`The database association "${rule.database}" does not exist.`);
return filtered[0];
}
}
exports.DatabaseAssociationFinder = DatabaseAssociationFinder;
class CachingFileReader {
constructor() {
this.fileChache = new Map();
}
readAsString(path) {
if (this.fileChache.get(path))
return this.fileChache.get(path);
const text = file_system_service_1.default.instance.readFileAsString(path);
this.fileChache.set(path, text);
return text;
}
}
exports.CachingFileReader = CachingFileReader;
class TemplateRuleOutputWriter {
async write(page, pageTemplateRule) {
const templateFileContents = this.fileReader.readAsString(pageTemplateRule.template);
const out = mustache_service_1.default.instance.render(page, templateFileContents);
if (!file_system_service_1.default.instance.doesFolderExist(pageTemplateRule.outDir)) {
file_system_service_1.default.instance.createFolder(pageTemplateRule.outDir);
}
const outFilePath = pageTemplateRule.outDir +
'/' +
page._title +
this.fileExtensionFinder.findFileExtensionOf(pageTemplateRule.template);
post_processing_service_1.default.instance.submit(out, outFilePath, page.data.id);
}
setFileExtensionFinder(fileExtensionFinder) {
this.fileExtensionFinder = fileExtensionFinder;
return this;
}
setCachingFileReader(reader) {
this.fileReader = reader;
return this;
}
}
exports.TemplateRuleOutputWriter = TemplateRuleOutputWriter;
class BlockChildrenFetcher {
async fetchChildren(bId, notionToken) {
var e_1, _a;
const promises = new Array();
try {
for (var _b = __asyncValues(notion_service_1.default.instance.getBlockChildren({
blockId: bId,
withToken: notionToken,
})), _c; _c = await _b.next(), !_c.done;) {
const child = _c.value;
promises.push(this._parseBlock(child, notionToken));
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) await _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
return Promise.all(promises);
}
async _parseBlock(blockData, notionToken) {
if (blockData.has_children) {
return {
data: blockData,
children: await this.fetchChildren(blockData.id, notionToken),
};
}
else {
return {
data: blockData,
children: [],
};
}
}
}
exports.BlockChildrenFetcher = BlockChildrenFetcher;
class DatabaseFetcher {
async fetchDatabase(args) {
var e_2, _a;
const database = await notion_service_1.default.instance.getDatabase({
withId: args.association.notionDatabaseId,
withToken: args.association.notionIntegrationToken,
});
const pagesData = notion_service_1.default.instance.queryForDatabasePages({
databaseId: args.association.notionDatabaseId,
withToken: args.association.notionIntegrationToken,
takeOnly: args.databaseRule.takeOnly,
sort: args.databaseRule.sort,
filter: args.databaseRule.filter,
});
const promises = new Array();
const fetchPage = async (pageData) => {
let pageBlocks = [];
if (Boolean(args.databaseRule.fetchBlocks)) {
pageBlocks = await this.blockChildrenFetcher.fetchChildren(pageData.id, args.association.notionIntegrationToken);
}
let page = {
_title: pageData.id,
otherData: {},
data: pageData,
blocks: pageBlocks,
};
if (args.databaseRule.map) {
page = args.databaseRule.map(page, args.context);
}
await args.onPostPageMapping(page);
return page;
};
try {
for (var pagesData_1 = __asyncValues(pagesData), pagesData_1_1; pagesData_1_1 = await pagesData_1.next(), !pagesData_1_1.done;) {
const pageData = pagesData_1_1.value;
promises.push(fetchPage(pageData));
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (pagesData_1_1 && !pagesData_1_1.done && (_a = pagesData_1.return)) await _a.call(pagesData_1);
}
finally { if (e_2) throw e_2.error; }
}
const outPages = await Promise.all(promises);
return {
data: database,
pages: outPages,
};
}
setBlockChildrenFether(blockChildrenFetcher) {
this.blockChildrenFetcher = blockChildrenFetcher;
return this;
}
}
exports.DatabaseFetcher = DatabaseFetcher;
class SecondaryDatabasesFetcher {
async fetchAll(databaseRules, databaseAssociations, ctx) {
const others = {};
const promises = new Array();
for (const dbRule of databaseRules) {
const dbAssociation = this.databaseAssociationFinder.findDatabaseAssociationFor(dbRule, databaseAssociations);
promises.push(new Promise((resolve, reject) => {
this.databaseFetcher.fetchDatabase({
databaseRule: dbRule,
association: dbAssociation,
context: ctx,
onPostPageMapping: async (_) => ({}),
})
.then((database) => resolve({
rule: dbRule,
db: database,
}))
.catch((e) => reject(e));
}));
}
for (const value of await Promise.all(promises)) {
others[value.rule.database] = value.db;
}
return others;
}
setDatabaseFetcher(databaseFetcher) {
this.databaseFetcher = databaseFetcher;
return this;
}
setDatabaseAssociationFinder(finder) {
this.databaseAssociationFinder = finder;
return this;
}
}
exports.SecondaryDatabasesFetcher = SecondaryDatabasesFetcher;
class TemplateRuleBuilder {
async build(rule, databaseAssociations) {
var _a;
const ctx = {
others: {},
genMarkdownForBlocks: (blocks) => markdown_service_1.default.instance.genMarkdownForBlocks(blocks, rule),
fetchMedia: (fileObject) => (0, markdown_service_1.getMedia)(fileObject, rule),
};
ctx.others = await this.secondaryDatabasesFetcher.fetchAll(rule.alsoUses, databaseAssociations, ctx);
const primaryAssociation = this.databaseAssociationFinder.findDatabaseAssociationFor(rule.uses, databaseAssociations);
await ((_a = this.databaseFetcher) === null || _a === void 0 ? void 0 : _a.fetchDatabase({
databaseRule: rule.uses,
association: primaryAssociation,
context: ctx,
onPostPageMapping: async (notionPage) => {
await this.templateRuleOutputWriter.write(notionPage, rule);
return notionPage;
},
}));
}
setSecondaryDatabasesFetcher(secondaryDatabasesFetcher) {
this.secondaryDatabasesFetcher = secondaryDatabasesFetcher;
return this;
}
setDatabaseFetcher(databaseFetcher) {
this.databaseFetcher = databaseFetcher;
return this;
}
setTemplateRuleOutputWriter(writer) {
this.templateRuleOutputWriter = writer;
return this;
}
setDatabaseAssociationFinder(finder) {
this.databaseAssociationFinder = finder;
return this;
}
}
exports.TemplateRuleBuilder = TemplateRuleBuilder;
//# sourceMappingURL=build_service.js.map