From eeb3bcec19b15e6b7d30f983c8f613dedb1a9b32 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sat, 22 Oct 2022 20:06:01 +0300 Subject: refactor: separate Nginx adapter --- src/lib/nginxAdapter.ts | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/types.ts | 15 +++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/lib/nginxAdapter.ts create mode 100644 src/lib/types.ts (limited to 'src/lib') diff --git a/src/lib/nginxAdapter.ts b/src/lib/nginxAdapter.ts new file mode 100644 index 0000000..fdadd87 --- /dev/null +++ b/src/lib/nginxAdapter.ts @@ -0,0 +1,50 @@ +import _ from 'lodash'; +import Bluebird from 'bluebird'; +import axios from 'axios'; +import mem from 'mem'; +import { Adapter } from './types'; + +const listNginxDirectory = async (path: string): Promise => { + const basePath = _.trimEnd(path.match('http[s]?://(.*?)/')?.[0], '/'); + const response = await axios(path); + const [_thisDir, ...results] = response.data + .match(/href='(.*)'/g) + .map((s: string) => s.match(/'(.*)'/)?.[1]) + .map((s: string) => basePath + s); + return results; +} + +const deepListNginxDirectory = async (path: string): Promise => { + const objects = await listNginxDirectory(path); + const fileUrls = objects.filter(url => !url.endsWith('/')); + const dirUrls = objects.filter(url => url.endsWith('/')); + const deepFileUrls = await Bluebird.map(dirUrls, deepListNginxDirectory); + return _.flattenDeep([fileUrls, deepFileUrls]); +} + +const memoizedDeepListNginxDirectory = mem(deepListNginxDirectory, { maxAge: 60000 }); + + +// An adapter to fetch markdown & images from Nginx server with enabled directory view +const nginxAdapter: Adapter = { + async getStaticMarkdownPaths(cdn) { + const urls = await memoizedDeepListNginxDirectory(cdn); + const markdownPaths = _.compact(urls.map(globalPath => globalPath.match(`${cdn}/(.*)\.md`)?.[1])); + + return markdownPaths + .map(path => path.split('/')) + .map(path => ({ params: { path } })); + }, + + async getMarkdownSource(cdn, path) { + const { data: markdownSource } = await axios(`${cdn}/${path?.join('/')}.md`); + return markdownSource; + }, + + async getEmojiFileNames(cdn) { + const urls = await memoizedDeepListNginxDirectory(cdn); + return _.compact(urls.map((s: string) => s.match(/emoji\/(.*)/)?.[1])); + }, +} + +export default nginxAdapter; diff --git a/src/lib/types.ts b/src/lib/types.ts new file mode 100644 index 0000000..8bbf5bb --- /dev/null +++ b/src/lib/types.ts @@ -0,0 +1,15 @@ +import { GetStaticPathsResult } from 'next'; + +/* Collection of methods to fetch data & metadata from CDN */ +export interface Adapter { + getStaticMarkdownPaths: (cdn: string) => Promise; + getMarkdownSource: (cdn: string, path: string[]) => Promise; + getEmojiFileNames: (cdn: string) => Promise; +} + +export interface BenzinConfig { + CDN: string; + adapter: Adapter; +} + + -- cgit v1.2.3