vowel 0.1.46 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -20
- package/bin.js +2 -78
- package/docs-source/$features/cards.md +7 -0
- package/docs-source/$features/editing.md +7 -0
- package/docs-source/$features/emoji.md +7 -0
- package/docs-source/$features/frontmatter.md +7 -0
- package/docs-source/$features/lists.md +7 -0
- package/docs-source/$features/navigation.md +7 -0
- package/docs-source/$features/rich-previews.md +7 -0
- package/docs-source/$features/robots.md +7 -0
- package/docs-source/$features/rss.md +7 -0
- package/docs-source/$features/sitemap.md +7 -0
- package/docs-source/$features/speed.md +7 -0
- package/docs-source/$features/static.md +7 -0
- package/docs-source/$features/taxonomies.md +7 -0
- package/docs-source/.cache.json +9 -0
- package/docs-source/.obsidian/app.json +3 -0
- package/docs-source/.obsidian/appearance.json +3 -0
- package/docs-source/.obsidian/core-plugins-migration.json +30 -0
- package/docs-source/.obsidian/core-plugins.json +20 -0
- package/docs-source/.obsidian/workspace.json +168 -0
- package/docs-source/.stackblitzrc +3 -0
- package/docs-source/.vercel/README.txt +11 -0
- package/docs-source/.vercel/project.json +1 -0
- package/docs-source/about.md +3 -0
- package/docs-source/assets/styles.css +51 -0
- package/docs-source/blog/home.md +5 -0
- package/docs-source/blog/url-ui.md +21 -0
- package/docs-source/docs/.votive.db +0 -0
- package/docs-source/docs/deploy.md +67 -0
- package/docs-source/docs/file-structure.md +31 -0
- package/docs-source/docs/folder-settings.md +23 -0
- package/docs-source/docs/home.md +55 -0
- package/docs-source/docs/images.md +10 -0
- package/docs-source/docs/items.md +13 -0
- package/docs-source/docs/pages.md +141 -0
- package/docs-source/docs/settings.md +4 -0
- package/docs-source/docs/styling.md +34 -0
- package/docs-source/docs/taxonomies.md +37 -0
- package/docs-source/home.md +42 -0
- package/docs-source/roadmap.md +98 -0
- package/docs-source/settings.md +12 -0
- package/extractDate.js +83 -0
- package/getMetadata.js +41 -0
- package/index.js +669 -0
- package/jsconfig.json +9 -17
- package/package.json +61 -63
- package/regex.js +36 -0
- package/{src/lib/components → stylesheets}/DefaultStyles.css +5 -5
- package/utils.js +10 -0
- package/.cache.json +0 -1
- package/.prettierrc +0 -8
- package/.vscode/settings.json +0 -3
- package/CHANGELOG.md +0 -79
- package/server.js +0 -87
- package/src/app.d.ts +0 -12
- package/src/app.html +0 -13
- package/src/lib/components/Breadcrumbs.svelte +0 -19
- package/src/lib/components/ConditionalWrapper.svelte +0 -10
- package/src/lib/components/DefaultStyles.svelte +0 -11
- package/src/lib/components/FrontMatterTaxonomy.svelte +0 -48
- package/src/lib/components/Frontmatter.svelte +0 -56
- package/src/lib/components/FrontmatterProperty.svelte +0 -78
- package/src/lib/components/Markdown/Image.svelte +0 -50
- package/src/lib/components/Markdown/Link.svelte +0 -19
- package/src/lib/components/Markdown/LinkPreview.svelte +0 -45
- package/src/lib/components/Markdown/Text.svelte +0 -6
- package/src/lib/components/Markdown/index.svelte +0 -147
- package/src/lib/components/Markdown/validators.js +0 -29
- package/src/lib/components/Nav.svelte +0 -40
- package/src/lib/components/NoStyles.svelte +0 -5
- package/src/lib/components/Page.svelte +0 -90
- package/src/lib/components/ResetStyles.svelte +0 -7
- package/src/lib/components/Sitemap.svelte +0 -38
- package/src/lib/components/TypographyStyles.svelte +0 -10
- package/src/lib/components/index.js +0 -12
- package/src/lib/index.js +0 -1
- package/src/lib/utilities/buildURL.js +0 -18
- package/src/lib/utilities/checkFileExists.js +0 -16
- package/src/lib/utilities/createFolderClass.js +0 -4
- package/src/lib/utilities/createPageClass.js +0 -6
- package/src/lib/utilities/getFileLabel.js +0 -35
- package/src/lib/utilities/getFolder.js +0 -16
- package/src/lib/utilities/getFolderLabel.js +0 -12
- package/src/lib/utilities/getMetadata.js +0 -46
- package/src/lib/utilities/getPage.js +0 -25
- package/src/lib/utilities/getPagesByFolder.js +0 -95
- package/src/lib/utilities/index.js +0 -22
- package/src/lib/utilities/isActiveLink.js +0 -12
- package/src/lib/utilities/isObject.js +0 -8
- package/src/lib/utilities/loadCache.js +0 -28
- package/src/lib/utilities/mutateMarkdownAST.js +0 -68
- package/src/lib/utilities/mutateMarkdownFrontmatter.js +0 -113
- package/src/lib/utilities/parseDate.js +0 -43
- package/src/lib/utilities/processMarkdownFiles.js +0 -243
- package/src/lib/utilities/readMarkdownFile.js +0 -188
- package/src/lib/utilities/regexPatterns.js +0 -12
- package/src/lib/utilities/resolveHomeDirPath.js +0 -5
- package/src/lib/utilities/sendWebmention.js +0 -34
- package/src/lib/utilities/writeCache.js +0 -14
- package/src/routes/$vowel/published.json/+server.js +0 -54
- package/src/routes/+error.svelte +0 -110
- package/src/routes/[...path]/+layout.server.js +0 -78
- package/src/routes/[...path]/+page.server.js +0 -42
- package/src/routes/[...path]/+page.svelte +0 -186
- package/src/routes/feed.xml/+server.js +0 -120
- package/src/routes/robots.txt/+server.js +0 -54
- package/src/routes/sitemap.xml/+server.js +0 -68
- package/static/favicon.png +0 -0
- package/static/styles.css +0 -0
- package/svelte.config.js +0 -30
- package/vercel.json +0 -5
- package/vite.config.js +0 -84
- /package/{src/lib/components → stylesheets}/ResetStyles.css +0 -0
- /package/{src/lib/components → stylesheets}/TypographyStyles.css +0 -0
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export default function getFolder(website, path) {
|
|
2
|
-
const dotPath = path
|
|
3
|
-
.replace(/^\//, '') // Remove preceding slash
|
|
4
|
-
.replace(/\/$/, '') // Remove trailing slash
|
|
5
|
-
.replaceAll('/', '.'); // Convert to dots
|
|
6
|
-
|
|
7
|
-
let drill = website;
|
|
8
|
-
|
|
9
|
-
dotPath.split('.').forEach((segment) => {
|
|
10
|
-
if (segment) {
|
|
11
|
-
drill = drill[segment];
|
|
12
|
-
}
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
return drill;
|
|
16
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { getFileLabel } from '.';
|
|
2
|
-
|
|
3
|
-
const fallBackLabel = 'Untitled';
|
|
4
|
-
|
|
5
|
-
export default function getFolderLabel(folder, shorter, date) {
|
|
6
|
-
if (typeof folder !== 'object') return 'Untitled';
|
|
7
|
-
return (
|
|
8
|
-
getFileLabel(folder['_'], shorter, date) ||
|
|
9
|
-
getFileLabel(folder['$'], shorter, date) ||
|
|
10
|
-
fallBackLabel
|
|
11
|
-
);
|
|
12
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { XMLParser } from "fast-xml-parser"
|
|
2
|
-
import urlMetadata from 'url-metadata';
|
|
3
|
-
|
|
4
|
-
export default async function getMetadata({ cache, url }) {
|
|
5
|
-
if (!cache[url]) {
|
|
6
|
-
try {
|
|
7
|
-
const urlObject = new URL(url);
|
|
8
|
-
const allMetadata = await urlMetadata(urlObject.href, {
|
|
9
|
-
includeResponseBody: true,
|
|
10
|
-
ensureSecureImageRequest: true
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
const parser = new XMLParser({
|
|
14
|
-
unpairedTags: ["!doctype", "meta", "link", "hr", "br", "img"],
|
|
15
|
-
ignoreAttributes: false,
|
|
16
|
-
stopNodes: ["*.pre", "*.script"],
|
|
17
|
-
processEntities: true,
|
|
18
|
-
htmlEntities: true
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
let parsedData = parser.parse(allMetadata.responseBody)
|
|
22
|
-
const webmentionEndpoint = parsedData?.html?.head?.link?.find(link => {
|
|
23
|
-
return link["@_rel"] === "webmention"
|
|
24
|
-
})?.["@_href"]
|
|
25
|
-
|
|
26
|
-
const metadata = {
|
|
27
|
-
image: allMetadata['og:image'],
|
|
28
|
-
ogURL: allMetadata['og:url'],
|
|
29
|
-
canonicalURL: allMetadata.canonical,
|
|
30
|
-
title: allMetadata.title,
|
|
31
|
-
ogTitle: allMetadata['og:title'],
|
|
32
|
-
author: allMetadata.author,
|
|
33
|
-
description: allMetadata.description,
|
|
34
|
-
webmentionEndpoint
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
cache[url] = metadata;
|
|
38
|
-
|
|
39
|
-
return { metadata }
|
|
40
|
-
} catch (error) {
|
|
41
|
-
console.log({ fetchingMetadataError: error })
|
|
42
|
-
return { metadata: undefined }
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return { metadata: cache[url] }
|
|
46
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
// import objectPath from 'object-path';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Takes a file URL and a website object and returns the file object.
|
|
5
|
-
* @param {import('./processMarkdownFiles').Directory} website - A website object.
|
|
6
|
-
* @param {string} path - A `/`-delimited filepath.
|
|
7
|
-
* @returns {import('./processMarkdownFiles').MarkdownFile}
|
|
8
|
-
*/
|
|
9
|
-
export default function getPage(website, path) {
|
|
10
|
-
let page = website;
|
|
11
|
-
|
|
12
|
-
// const dotPath = path.replace(/^\//, '').replaceAll('/', '.') + (path ? '.' : '') + '$';
|
|
13
|
-
|
|
14
|
-
const segments = path
|
|
15
|
-
.replace(/^\//, '')
|
|
16
|
-
.concat(path ? '/$' : '$')
|
|
17
|
-
.split('/');
|
|
18
|
-
|
|
19
|
-
segments.forEach((segment) => {
|
|
20
|
-
if (segment === '_') return page[segment];
|
|
21
|
-
if (typeof page === 'object' && page !== null) page = page[segment];
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
return page;
|
|
25
|
-
}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
// @ts-ignore
|
|
2
|
-
import { getFolder, getFileLabel } from '.';
|
|
3
|
-
|
|
4
|
-
// @ts-ignore
|
|
5
|
-
const excludedFileNames = ['_'];
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Traverse a folder to get all of the pages.
|
|
9
|
-
* @param {import('./processMarkdownFiles').Directory} folder - The path to the folder to retrieve.
|
|
10
|
-
* @param {boolean} root - Whether this is the root of the recursion.
|
|
11
|
-
* @returns {Array<Page>}
|
|
12
|
-
*/
|
|
13
|
-
function traverseFolder(folder, root = false, property = '.') {
|
|
14
|
-
let propertyKey = (property || '.').split('.')[0];
|
|
15
|
-
let propertyValue = (property || '.').split('.')[1];
|
|
16
|
-
|
|
17
|
-
let pages = [];
|
|
18
|
-
|
|
19
|
-
for (let key in folder) {
|
|
20
|
-
if (!key.startsWith('$') || key.length === 1) {
|
|
21
|
-
if (key === '$') {
|
|
22
|
-
if (!root) {
|
|
23
|
-
if (propertyKey) {
|
|
24
|
-
if (
|
|
25
|
-
folder[key].hasOwnProperty(propertyKey) &&
|
|
26
|
-
folder[key][propertyKey] === propertyValue
|
|
27
|
-
) {
|
|
28
|
-
pages.push(folder[key]);
|
|
29
|
-
}
|
|
30
|
-
} else {
|
|
31
|
-
pages.push(folder[key]);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
// if (
|
|
35
|
-
// !root &&
|
|
36
|
-
// folder[key].$?.hasOwnProperty(propertyKey) &&
|
|
37
|
-
// folder[key][propertyKey] === propertyValue
|
|
38
|
-
// )
|
|
39
|
-
// pages.push(folder[key]);
|
|
40
|
-
} else if (key !== '_') {
|
|
41
|
-
const child = folder[key];
|
|
42
|
-
|
|
43
|
-
// @ts-ignore
|
|
44
|
-
pages.push(...traverseFolder(child, false, property));
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// @ts-ignore
|
|
50
|
-
return pages;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Description
|
|
55
|
-
* @param {Page} a
|
|
56
|
-
* @param {Page} b
|
|
57
|
-
* @returns {number}
|
|
58
|
-
*/
|
|
59
|
-
function sortPage(a, b) {
|
|
60
|
-
if (a.hasOwnProperty('date') && !b.hasOwnProperty('date')) return -1;
|
|
61
|
-
else if (!a.hasOwnProperty('date') && b.hasOwnProperty('date')) return 1;
|
|
62
|
-
else if (a.date && b.date) {
|
|
63
|
-
const aDate = Number(new Date(a.date.output));
|
|
64
|
-
const bDate = Number(new Date(b.date.output));
|
|
65
|
-
return bDate - aDate;
|
|
66
|
-
} else if (getFileLabel(a) > getFileLabel(b)) return 1;
|
|
67
|
-
return -1;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* @typedef {import('./processMarkdownFiles').MarkdownFile} Page
|
|
72
|
-
*/
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Recursively get all of the pages in a folder.
|
|
76
|
-
* @param {import('./processMarkdownFiles').Directory} website - The entire website.
|
|
77
|
-
* @param {string} path - The path to the folder to retrieve.
|
|
78
|
-
* @param {number | undefined} count - Number of pages to return.
|
|
79
|
-
* @returns {Array<Page>}
|
|
80
|
-
*/
|
|
81
|
-
export default function getPagesByFolder(
|
|
82
|
-
website,
|
|
83
|
-
path,
|
|
84
|
-
excludeRoot = true,
|
|
85
|
-
count = undefined,
|
|
86
|
-
property
|
|
87
|
-
) {
|
|
88
|
-
const folder = getFolder(website, path);
|
|
89
|
-
|
|
90
|
-
const pages = traverseFolder(folder, excludeRoot, property);
|
|
91
|
-
|
|
92
|
-
pages.sort(sortPage);
|
|
93
|
-
|
|
94
|
-
return pages.slice(0, count);
|
|
95
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export { default as getPage } from './getPage';
|
|
2
|
-
export { default as getFileLabel } from './getFileLabel';
|
|
3
|
-
export { default as getFolderLabel } from './getFolderLabel';
|
|
4
|
-
export { default as getFolder } from './getFolder';
|
|
5
|
-
export { default as getPagesByFolder } from './getPagesByFolder';
|
|
6
|
-
export { default as buildURL } from './buildURL';
|
|
7
|
-
export { default as checkFileExists } from './checkFileExists';
|
|
8
|
-
export { default as writeCache } from './writeCache';
|
|
9
|
-
export { default as readMarkdownFile } from './readMarkdownFile';
|
|
10
|
-
export { default as processMarkdownFiles } from './processMarkdownFiles';
|
|
11
|
-
export { default as loadCache } from './loadCache';
|
|
12
|
-
export { default as mutateMarkdownFrontmatter } from './mutateMarkdownFrontmatter';
|
|
13
|
-
export { default as isObject } from './isObject';
|
|
14
|
-
export { default as regexPatterns } from './regexPatterns';
|
|
15
|
-
export { default as mutateMarkdownAST } from './mutateMarkdownAST';
|
|
16
|
-
export { default as parseDate } from './parseDate';
|
|
17
|
-
export { default as resolveHomeDirPath } from './resolveHomeDirPath';
|
|
18
|
-
export { default as createPageClass } from './createPageClass';
|
|
19
|
-
export { default as createFolderClass } from './createFolderClass';
|
|
20
|
-
export { default as isActiveLink } from './isActiveLink';
|
|
21
|
-
export { default as sendWebmention } from "./sendWebmention"
|
|
22
|
-
export { default as getMetadata } from "./getMetadata"
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export default function isActiveLink(segments, key) {
|
|
2
|
-
if (!segments?.[0] && !key) {
|
|
3
|
-
return 'page';
|
|
4
|
-
}
|
|
5
|
-
if (segments.length === 1 && segments[0] === key) {
|
|
6
|
-
return 'page';
|
|
7
|
-
}
|
|
8
|
-
if (segments.length > 1 && segments[0] === key) {
|
|
9
|
-
return 'true';
|
|
10
|
-
}
|
|
11
|
-
return undefined;
|
|
12
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
2
|
-
import resolveHomeDirPath from './resolveHomeDirPath';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @typedef {Object<string, object>} Cache
|
|
6
|
-
* @description A map of URLs to their metadata.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Load a cache of URLs
|
|
11
|
-
* @returns {Promise<Cache>}
|
|
12
|
-
*/
|
|
13
|
-
export default async function loadCache(homeDir) {
|
|
14
|
-
const cachePath = resolveHomeDirPath('.cache.json', homeDir);
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
let data = await fs.readFile(cachePath);
|
|
18
|
-
return JSON.parse(data);
|
|
19
|
-
} catch (error) {
|
|
20
|
-
if (error.code === 'ENOENT') {
|
|
21
|
-
await fs.writeFile(cachePath, '{}', 'utf8');
|
|
22
|
-
console.log('.cache.json created');
|
|
23
|
-
} else {
|
|
24
|
-
throw error;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
return {};
|
|
28
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { sendWebmention, getMetadata } from './';
|
|
2
|
-
|
|
3
|
-
function isURL(string) {
|
|
4
|
-
try {
|
|
5
|
-
new URL(string)
|
|
6
|
-
return true
|
|
7
|
-
} catch (e) {
|
|
8
|
-
return false
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export default async function mutateMarkdownAST(ast, cache, webmentions, pageURL) {
|
|
15
|
-
const promises = ast.map(async (node) => {
|
|
16
|
-
// TODO: Improve this URL regex
|
|
17
|
-
if (node.type === 'paragraph') {
|
|
18
|
-
|
|
19
|
-
// URLs
|
|
20
|
-
if (
|
|
21
|
-
node.children?.length === 1 &&
|
|
22
|
-
node.children?.[0]?.type === "link" &&
|
|
23
|
-
node.children?.[0]?.children?.length === 1
|
|
24
|
-
) {
|
|
25
|
-
node.type = 'url';
|
|
26
|
-
const { url } = node.children[0];
|
|
27
|
-
node.url = url
|
|
28
|
-
|
|
29
|
-
const { metadata } = await getMetadata({ cache, url })
|
|
30
|
-
|
|
31
|
-
node.metadata = metadata;
|
|
32
|
-
node.value = url;
|
|
33
|
-
delete node.children;
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
console.log("Looking for webmentions")
|
|
37
|
-
if (webmentions && !webmentions.find(webmention => webmention.target === url)) {
|
|
38
|
-
console.log("Found new page")
|
|
39
|
-
webmentions.push({
|
|
40
|
-
target: url,
|
|
41
|
-
status: "new"
|
|
42
|
-
})
|
|
43
|
-
} else if (webmentions) {
|
|
44
|
-
console.log("Found new webmention")
|
|
45
|
-
const webmention = webmentions.find(webmention => webmention.target === url)
|
|
46
|
-
if (webmention.status === "new" || webmention.status === "failure" || webmention.status === "429") {
|
|
47
|
-
console.log("Sending webmention")
|
|
48
|
-
webmention.status = await sendWebmention({ endpoint: metadata.webmentionEndpoint, target: webmention.target, source: pageURL })
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
} catch (error) {
|
|
52
|
-
console.log({ webmentionError: error })
|
|
53
|
-
}
|
|
54
|
-
} else if (node.children[0].type === 'image') {
|
|
55
|
-
node.type = 'figure';
|
|
56
|
-
if (node?.children[1]?.type === 'text') {
|
|
57
|
-
node.children[1].type = 'figcaption';
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (node.children) {
|
|
63
|
-
await mutateMarkdownAST(node.children, cache);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
await Promise.all(promises);
|
|
68
|
-
}
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import urlMetadata from 'url-metadata';
|
|
2
|
-
import { regexPatterns, isObject, parseDate, sendWebmention, getMetadata } from '.';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Description
|
|
6
|
-
* @param {any} value - Any frontmatter value
|
|
7
|
-
* @returns {any}
|
|
8
|
-
*/
|
|
9
|
-
function imputeType(value) {
|
|
10
|
-
if (value === null || value === undefined || Number.isNaN(value)) return 'nullish';
|
|
11
|
-
if (typeof value === 'boolean') return 'boolean';
|
|
12
|
-
if (typeof value === 'number') return 'number';
|
|
13
|
-
if (parseDate(value)) return 'date';
|
|
14
|
-
if (isObject(value)) return 'object';
|
|
15
|
-
if (Array.isArray(value)) return 'array';
|
|
16
|
-
if (typeof value === 'string') {
|
|
17
|
-
if (value.match(regexPatterns.img)) return 'image';
|
|
18
|
-
if (value.match(regexPatterns.pdf)) return 'pdf';
|
|
19
|
-
if (value.match(regexPatterns.url)) return 'url';
|
|
20
|
-
if (value.match(regexPatterns.path)) return 'path';
|
|
21
|
-
return 'string';
|
|
22
|
-
}
|
|
23
|
-
console.error('Unknown frontmatter data type: ' + value);
|
|
24
|
-
return 'other';
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export default async function mutateMarkdownFrontmatter(frontmatter, cache, webmentions, pageURL) {
|
|
28
|
-
const keys = Object.keys(frontmatter);
|
|
29
|
-
|
|
30
|
-
const promises = keys.map(async (key) => {
|
|
31
|
-
const input = frontmatter[key];
|
|
32
|
-
|
|
33
|
-
const type = imputeType(input);
|
|
34
|
-
|
|
35
|
-
switch (type) {
|
|
36
|
-
case 'object': {
|
|
37
|
-
await mutateMarkdownFrontmatter(input, cache);
|
|
38
|
-
frontmatter[key] = {
|
|
39
|
-
type: 'object',
|
|
40
|
-
output: input
|
|
41
|
-
};
|
|
42
|
-
break;
|
|
43
|
-
}
|
|
44
|
-
case 'array': {
|
|
45
|
-
await mutateMarkdownFrontmatter(input, cache);
|
|
46
|
-
frontmatter[key] = {
|
|
47
|
-
type: 'array',
|
|
48
|
-
output: input
|
|
49
|
-
};
|
|
50
|
-
break;
|
|
51
|
-
}
|
|
52
|
-
case 'date': {
|
|
53
|
-
frontmatter[key] = {
|
|
54
|
-
type: 'date',
|
|
55
|
-
output: parseDate(input),
|
|
56
|
-
input
|
|
57
|
-
};
|
|
58
|
-
break;
|
|
59
|
-
}
|
|
60
|
-
case 'image': {
|
|
61
|
-
frontmatter[key] = {
|
|
62
|
-
type: 'image',
|
|
63
|
-
output: input,
|
|
64
|
-
input
|
|
65
|
-
};
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
case 'pdf': {
|
|
69
|
-
frontmatter[key] = {
|
|
70
|
-
type: 'pdf',
|
|
71
|
-
output: input,
|
|
72
|
-
input
|
|
73
|
-
};
|
|
74
|
-
break;
|
|
75
|
-
}
|
|
76
|
-
case 'url': {
|
|
77
|
-
const { metadata } = await getMetadata({
|
|
78
|
-
cache,
|
|
79
|
-
url: input
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
frontmatter[key] = {
|
|
83
|
-
type: 'url',
|
|
84
|
-
output: metadata || input,
|
|
85
|
-
input
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
if (webmentions && !webmentions.find(webmention => webmention.target === input)) {
|
|
90
|
-
webmentions.push({
|
|
91
|
-
target: input,
|
|
92
|
-
status: "new"
|
|
93
|
-
})
|
|
94
|
-
} else if (webmentions) {
|
|
95
|
-
const webmention = webmentions.find(webmention => webmention.target === input)
|
|
96
|
-
if (webmention.status === "new") {
|
|
97
|
-
webmention.status = await sendWebmention({ endpoint: metadata.webmentionEndpoint, target: webmention.target, source: pageURL })
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
} catch (error) {
|
|
102
|
-
console.log({ webmentionsError: error })
|
|
103
|
-
}
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
case 'nullish': {
|
|
107
|
-
frontmatter[key] = undefined;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
await Promise.all(promises);
|
|
113
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import dates from 'any-date-parser';
|
|
2
|
-
import ago from 'any-date-parser/src/formats/ago/ago.js';
|
|
3
|
-
import chinese from 'any-date-parser/src/formats/chinese/chinese.js';
|
|
4
|
-
import dayMonth from 'any-date-parser/src/formats/dayMonth/dayMonth.js';
|
|
5
|
-
import dayMonthname from 'any-date-parser/src/formats/dayMonthname/dayMonthname.js';
|
|
6
|
-
import monthDay from 'any-date-parser/src/formats/monthDay/monthDay.js';
|
|
7
|
-
import monthnameDay from 'any-date-parser/src/formats/monthnameDay/monthnameDay.js';
|
|
8
|
-
import today from 'any-date-parser/src/formats/today/today.js';
|
|
9
|
-
|
|
10
|
-
dates.removeFormat(ago);
|
|
11
|
-
dates.removeFormat(chinese);
|
|
12
|
-
dates.removeFormat(dayMonth);
|
|
13
|
-
dates.removeFormat(dayMonthname);
|
|
14
|
-
dates.removeFormat(monthDay);
|
|
15
|
-
dates.removeFormat(monthnameDay);
|
|
16
|
-
dates.removeFormat(today);
|
|
17
|
-
|
|
18
|
-
/*
|
|
19
|
-
Left in the following formats:
|
|
20
|
-
|
|
21
|
-
microsoftJson
|
|
22
|
-
dayMonthYear
|
|
23
|
-
dayMonthnameYear
|
|
24
|
-
monthDayYear
|
|
25
|
-
monthnameDayYear
|
|
26
|
-
twitter
|
|
27
|
-
yearMonthDay
|
|
28
|
-
atSeconds
|
|
29
|
-
time12Hours
|
|
30
|
-
time24Hours
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
export default function parseDate(maybeDate) {
|
|
34
|
-
if (!maybeDate) return false;
|
|
35
|
-
if (maybeDate instanceof Date) return maybeDate;
|
|
36
|
-
if (typeof maybeDate === 'number') return false;
|
|
37
|
-
if (typeof maybeDate === 'string' && maybeDate.match(/^\d+$/)) return false;
|
|
38
|
-
const parsedDate = dates.attempt(maybeDate);
|
|
39
|
-
if (parsedDate.invalid) return false;
|
|
40
|
-
const { month, day, year } = parsedDate;
|
|
41
|
-
const date = new Date(`${year}-${month}-${day}`);
|
|
42
|
-
return date;
|
|
43
|
-
}
|