@opinly/next 0.1.6 → 0.1.7
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/dist/components/author-page/_helpers/json-ld.cjs +2 -0
- package/dist/components/author-page/_helpers/json-ld.cjs.map +1 -0
- package/dist/components/author-page/_helpers/json-ld.d.cts +2 -0
- package/dist/components/author-page/_helpers/json-ld.d.ts +2 -0
- package/dist/components/author-page/_helpers/json-ld.js +1 -0
- package/dist/components/author-page/_helpers/json-ld.js.map +1 -0
- package/dist/components/author-page/index.cjs +84 -0
- package/dist/components/author-page/index.cjs.map +1 -0
- package/dist/components/author-page/index.d.cts +10 -0
- package/dist/components/author-page/index.d.ts +10 -0
- package/dist/components/author-page/index.js +50 -0
- package/dist/components/author-page/index.js.map +1 -0
- package/dist/components/authors-page/index.cjs +106 -0
- package/dist/components/authors-page/index.cjs.map +1 -0
- package/dist/components/authors-page/index.d.cts +10 -0
- package/dist/components/authors-page/index.d.ts +10 -0
- package/dist/components/authors-page/index.js +72 -0
- package/dist/components/authors-page/index.js.map +1 -0
- package/dist/components/blog-post/_components/content.cjs +130 -0
- package/dist/components/blog-post/_components/content.cjs.map +1 -0
- package/dist/components/blog-post/_components/content.d.cts +10 -0
- package/dist/components/blog-post/_components/content.d.ts +10 -0
- package/dist/components/blog-post/_components/content.js +96 -0
- package/dist/components/blog-post/_components/content.js.map +1 -0
- package/dist/components/blog-post/_components/faq.cjs +39 -0
- package/dist/components/blog-post/_components/faq.cjs.map +1 -0
- package/dist/components/blog-post/_components/faq.d.cts +9 -0
- package/dist/components/blog-post/_components/faq.d.ts +9 -0
- package/dist/components/blog-post/_components/faq.js +15 -0
- package/dist/components/blog-post/_components/faq.js.map +1 -0
- package/dist/components/blog-post/_components/share.cjs +100 -0
- package/dist/components/blog-post/_components/share.cjs.map +1 -0
- package/dist/components/blog-post/_components/share.d.cts +9 -0
- package/dist/components/blog-post/_components/share.d.ts +9 -0
- package/dist/components/blog-post/_components/share.js +66 -0
- package/dist/components/blog-post/_components/share.js.map +1 -0
- package/dist/components/blog-post/_components/table-of-contents.cjs +82 -0
- package/dist/components/blog-post/_components/table-of-contents.cjs.map +1 -0
- package/dist/components/blog-post/_components/table-of-contents.d.cts +13 -0
- package/dist/components/blog-post/_components/table-of-contents.d.ts +13 -0
- package/dist/components/blog-post/_components/table-of-contents.js +48 -0
- package/dist/components/blog-post/_components/table-of-contents.js.map +1 -0
- package/dist/components/blog-post/_helpers/calc-reading-time.cjs +2 -0
- package/dist/components/blog-post/_helpers/calc-reading-time.cjs.map +1 -0
- package/dist/components/blog-post/_helpers/calc-reading-time.d.cts +2 -0
- package/dist/components/blog-post/_helpers/calc-reading-time.d.ts +2 -0
- package/dist/components/blog-post/_helpers/calc-reading-time.js +1 -0
- package/dist/components/blog-post/_helpers/calc-reading-time.js.map +1 -0
- package/dist/components/blog-post/_helpers/extract-headings.cjs +44 -0
- package/dist/components/blog-post/_helpers/extract-headings.cjs.map +1 -0
- package/dist/components/blog-post/_helpers/extract-headings.d.cts +8 -0
- package/dist/components/blog-post/_helpers/extract-headings.d.ts +8 -0
- package/dist/components/blog-post/_helpers/extract-headings.js +20 -0
- package/dist/components/blog-post/_helpers/extract-headings.js.map +1 -0
- package/dist/components/blog-post/_helpers/json-ld.cjs +170 -0
- package/dist/components/blog-post/_helpers/json-ld.cjs.map +1 -0
- package/dist/components/blog-post/_helpers/json-ld.d.cts +11 -0
- package/dist/components/blog-post/_helpers/json-ld.d.ts +11 -0
- package/dist/components/blog-post/_helpers/json-ld.js +143 -0
- package/dist/components/blog-post/_helpers/json-ld.js.map +1 -0
- package/dist/components/blog-post/_helpers/reading-time.cjs +50 -0
- package/dist/components/blog-post/_helpers/reading-time.cjs.map +1 -0
- package/dist/components/blog-post/_helpers/reading-time.d.cts +6 -0
- package/dist/components/blog-post/_helpers/reading-time.d.ts +6 -0
- package/dist/components/blog-post/_helpers/reading-time.js +25 -0
- package/dist/components/blog-post/_helpers/reading-time.js.map +1 -0
- package/dist/components/blog-post/_types/blog-post.cjs +17 -0
- package/dist/components/blog-post/_types/blog-post.cjs.map +1 -0
- package/dist/components/blog-post/_types/blog-post.d.cts +7 -0
- package/dist/components/blog-post/_types/blog-post.d.ts +7 -0
- package/dist/components/blog-post/_types/blog-post.js +1 -0
- package/dist/components/blog-post/_types/blog-post.js.map +1 -0
- package/dist/components/blog-post/_types/class-names.cjs +17 -0
- package/dist/components/blog-post/_types/class-names.cjs.map +1 -0
- package/dist/components/blog-post/_types/class-names.d.cts +12 -0
- package/dist/components/blog-post/_types/class-names.d.ts +12 -0
- package/dist/components/blog-post/_types/class-names.js +1 -0
- package/dist/components/blog-post/_types/class-names.js.map +1 -0
- package/dist/components/blog-post/index.cjs +149 -0
- package/dist/components/blog-post/index.cjs.map +1 -0
- package/dist/components/blog-post/index.d.cts +13 -0
- package/dist/components/blog-post/index.d.ts +13 -0
- package/dist/components/blog-post/index.js +119 -0
- package/dist/components/blog-post/index.js.map +1 -0
- package/dist/components/bread-crumbs.cjs +60 -0
- package/dist/components/bread-crumbs.cjs.map +1 -0
- package/dist/components/bread-crumbs.d.cts +10 -0
- package/dist/components/bread-crumbs.d.ts +10 -0
- package/dist/components/bread-crumbs.js +26 -0
- package/dist/components/bread-crumbs.js.map +1 -0
- package/dist/components/folder-page/index.cjs +61 -0
- package/dist/components/folder-page/index.cjs.map +1 -0
- package/dist/components/folder-page/index.d.cts +10 -0
- package/dist/components/folder-page/index.d.ts +10 -0
- package/dist/components/folder-page/index.js +37 -0
- package/dist/components/folder-page/index.js.map +1 -0
- package/dist/components/home-page.cjs +71 -0
- package/dist/components/home-page.cjs.map +1 -0
- package/dist/components/home-page.d.cts +12 -0
- package/dist/components/home-page.d.ts +12 -0
- package/dist/components/home-page.js +37 -0
- package/dist/components/home-page.js.map +1 -0
- package/dist/components/not-found.cjs +60 -0
- package/dist/components/not-found.cjs.map +1 -0
- package/dist/components/not-found.d.cts +5 -0
- package/dist/components/not-found.d.ts +5 -0
- package/dist/components/not-found.js +26 -0
- package/dist/components/not-found.js.map +1 -0
- package/dist/components/opinly-blog.cjs +56 -0
- package/dist/components/opinly-blog.cjs.map +1 -0
- package/dist/components/opinly-blog.d.cts +9 -0
- package/dist/components/opinly-blog.d.ts +9 -0
- package/dist/components/opinly-blog.js +32 -0
- package/dist/components/opinly-blog.js.map +1 -0
- package/dist/components/post-preview.cjs +93 -0
- package/dist/components/post-preview.cjs.map +1 -0
- package/dist/components/post-preview.d.cts +10 -0
- package/dist/components/post-preview.d.ts +10 -0
- package/dist/components/post-preview.js +59 -0
- package/dist/components/post-preview.js.map +1 -0
- package/dist/index.d.cts +4 -17
- package/dist/index.d.ts +4 -17
- package/package.json +21 -2
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var extract_headings_exports = {};
|
|
20
|
+
__export(extract_headings_exports, {
|
|
21
|
+
extractHeadings: () => extractHeadings
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(extract_headings_exports);
|
|
24
|
+
function extractHeadings(content) {
|
|
25
|
+
const headings = [];
|
|
26
|
+
if (!content?.content) return headings;
|
|
27
|
+
const walk = (nodes) => {
|
|
28
|
+
for (const node of nodes) {
|
|
29
|
+
if (node.type === "heading" && node.content?.[0]?.text) {
|
|
30
|
+
const text = node.content[0].text;
|
|
31
|
+
const slug = text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
32
|
+
headings.push({ text, slug });
|
|
33
|
+
}
|
|
34
|
+
if (node.content) walk(node.content);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
walk(content.content);
|
|
38
|
+
return headings;
|
|
39
|
+
}
|
|
40
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
41
|
+
0 && (module.exports = {
|
|
42
|
+
extractHeadings
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=extract-headings.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/blog-post/_helpers/extract-headings.ts"],"sourcesContent":["import { JSONContent } from \"@tiptap/core\";\n\nexport function extractHeadings(\n content: JSONContent\n): { text: string; slug: string }[] {\n const headings: { text: string; slug: string }[] = [];\n if (!content?.content) return headings;\n\n const walk = (nodes: any[]) => {\n for (const node of nodes) {\n if (node.type === \"heading\" && node.content?.[0]?.text) {\n const text = node.content[0].text;\n const slug = text\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n headings.push({ text, slug });\n }\n if (node.content) walk(node.content);\n }\n };\n\n walk(content.content);\n return headings;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEO,SAAS,gBACd,SACkC;AAClC,QAAM,WAA6C,CAAC;AACpD,MAAI,CAAC,SAAS,QAAS,QAAO;AAE9B,QAAM,OAAO,CAAC,UAAiB;AAC7B,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,SAAS,aAAa,KAAK,UAAU,CAAC,GAAG,MAAM;AACtD,cAAM,OAAO,KAAK,QAAQ,CAAC,EAAE;AAC7B,cAAM,OAAO,KACV,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE;AACzB,iBAAS,KAAK,EAAE,MAAM,KAAK,CAAC;AAAA,MAC9B;AACA,UAAI,KAAK,QAAS,MAAK,KAAK,OAAO;AAAA,IACrC;AAAA,EACF;AAEA,OAAK,QAAQ,OAAO;AACpB,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
function extractHeadings(content) {
|
|
2
|
+
const headings = [];
|
|
3
|
+
if (!content?.content) return headings;
|
|
4
|
+
const walk = (nodes) => {
|
|
5
|
+
for (const node of nodes) {
|
|
6
|
+
if (node.type === "heading" && node.content?.[0]?.text) {
|
|
7
|
+
const text = node.content[0].text;
|
|
8
|
+
const slug = text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
9
|
+
headings.push({ text, slug });
|
|
10
|
+
}
|
|
11
|
+
if (node.content) walk(node.content);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
walk(content.content);
|
|
15
|
+
return headings;
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
extractHeadings
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=extract-headings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/blog-post/_helpers/extract-headings.ts"],"sourcesContent":["import { JSONContent } from \"@tiptap/core\";\n\nexport function extractHeadings(\n content: JSONContent\n): { text: string; slug: string }[] {\n const headings: { text: string; slug: string }[] = [];\n if (!content?.content) return headings;\n\n const walk = (nodes: any[]) => {\n for (const node of nodes) {\n if (node.type === \"heading\" && node.content?.[0]?.text) {\n const text = node.content[0].text;\n const slug = text\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n headings.push({ text, slug });\n }\n if (node.content) walk(node.content);\n }\n };\n\n walk(content.content);\n return headings;\n}\n"],"mappings":"AAEO,SAAS,gBACd,SACkC;AAClC,QAAM,WAA6C,CAAC;AACpD,MAAI,CAAC,SAAS,QAAS,QAAO;AAE9B,QAAM,OAAO,CAAC,UAAiB;AAC7B,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,SAAS,aAAa,KAAK,UAAU,CAAC,GAAG,MAAM;AACtD,cAAM,OAAO,KAAK,QAAQ,CAAC,EAAE;AAC7B,cAAM,OAAO,KACV,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE;AACzB,iBAAS,KAAK,EAAE,MAAM,KAAK,CAAC;AAAA,MAC9B;AACA,UAAI,KAAK,QAAS,MAAK,KAAK,OAAO;AAAA,IACrC;AAAA,EACF;AAEA,OAAK,QAAQ,OAAO;AACpB,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var json_ld_exports = {};
|
|
20
|
+
__export(json_ld_exports, {
|
|
21
|
+
genBlogPostingJSONLD: () => genBlogPostingJSONLD,
|
|
22
|
+
genBreadcrumbJSONLD: () => genBreadcrumbJSONLD,
|
|
23
|
+
genFaqJSONLD: () => genFaqJSONLD,
|
|
24
|
+
generateArticleBodyHtml: () => generateArticleBodyHtml
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(json_ld_exports);
|
|
27
|
+
var import_sdk_config = require("../../../sdk-config");
|
|
28
|
+
var import_images = require("../../../utils/images");
|
|
29
|
+
function generateArticleBodyHtml(content) {
|
|
30
|
+
if (!content?.content) return "";
|
|
31
|
+
let htmlString = "";
|
|
32
|
+
content.content.forEach((node) => {
|
|
33
|
+
switch (node.type) {
|
|
34
|
+
case "paragraph":
|
|
35
|
+
htmlString += `<p>${generateChildrenHtml(node.content)}</p>`;
|
|
36
|
+
break;
|
|
37
|
+
case "heading":
|
|
38
|
+
const headingLevel = node.attrs?.level || 1;
|
|
39
|
+
htmlString += `<h${headingLevel}>${generateChildrenHtml(node.content)}</h${headingLevel}>`;
|
|
40
|
+
break;
|
|
41
|
+
case "bulletList":
|
|
42
|
+
htmlString += `<ul>${generateChildrenHtml(node.content)}</ul>`;
|
|
43
|
+
break;
|
|
44
|
+
case "orderedList":
|
|
45
|
+
htmlString += `<ol>${generateChildrenHtml(node.content)}</ol>`;
|
|
46
|
+
break;
|
|
47
|
+
case "listItem":
|
|
48
|
+
htmlString += `<li>${generateChildrenHtml(node.content)}</li>`;
|
|
49
|
+
break;
|
|
50
|
+
// Add other node types if they contain text content relevant for articleBody
|
|
51
|
+
// For images, you might just skip them or include an <img> tag if semantic
|
|
52
|
+
// For example:
|
|
53
|
+
// case "image":
|
|
54
|
+
// if (node.attrs?.src) {
|
|
55
|
+
// htmlString += `<img src="${replaceImageHostname(node.attrs.src, opinlyConfig.imagesPrefix)}" alt="${node.attrs?.alt || ''}" />`;
|
|
56
|
+
// }
|
|
57
|
+
// break;
|
|
58
|
+
default:
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return htmlString;
|
|
63
|
+
}
|
|
64
|
+
function generateChildrenHtml(nodes) {
|
|
65
|
+
if (!nodes) return "";
|
|
66
|
+
let childrenHtml = "";
|
|
67
|
+
nodes.forEach((child) => {
|
|
68
|
+
if (child.type === "text") {
|
|
69
|
+
let text = child.text || "";
|
|
70
|
+
if (child.marks) {
|
|
71
|
+
child.marks.forEach((mark) => {
|
|
72
|
+
if (mark.type === "bold") text = `<strong>${text}</strong>`;
|
|
73
|
+
if (mark.type === "italic") text = `<em>${text}</em>`;
|
|
74
|
+
if (mark.type === "link" && mark.attrs?.href) {
|
|
75
|
+
text = `<a href="${mark.attrs.href}">${text}</a>`;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
childrenHtml += text;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
return childrenHtml;
|
|
83
|
+
}
|
|
84
|
+
const genFaqJSONLD = (faqs) => {
|
|
85
|
+
return {
|
|
86
|
+
"@context": "https://schema.org",
|
|
87
|
+
"@type": "FAQPage",
|
|
88
|
+
mainEntity: faqs.map((faq) => ({
|
|
89
|
+
"@type": "Question",
|
|
90
|
+
name: faq.question,
|
|
91
|
+
acceptedAnswer: {
|
|
92
|
+
"@type": "Answer",
|
|
93
|
+
text: faq.answer
|
|
94
|
+
}
|
|
95
|
+
}))
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
const genBlogPostingJSONLD = (post) => {
|
|
99
|
+
return {
|
|
100
|
+
"@context": "https://schema.org",
|
|
101
|
+
"@type": "BlogPosting",
|
|
102
|
+
headline: post.title,
|
|
103
|
+
description: post.description || void 0,
|
|
104
|
+
url: `${import_sdk_config.opinlyConfig.blogUrl}/${post.folder ? `${post.folder.slug + "/"}${post.slug}` : post.slug}`,
|
|
105
|
+
datePublished: post.firstPublishedAt || void 0,
|
|
106
|
+
dateModified: post.modifiedAt || void 0,
|
|
107
|
+
image: post.titleFile?.fileKey ? {
|
|
108
|
+
"@type": "ImageObject",
|
|
109
|
+
url: `${import_sdk_config.opinlyConfig.imagesUrl}/${(0, import_images.replaceImageNameSpace)(post.titleFile.fileKey)}`
|
|
110
|
+
} : void 0,
|
|
111
|
+
author: post.author ? {
|
|
112
|
+
"@type": "Person",
|
|
113
|
+
name: post.author.name,
|
|
114
|
+
url: `${import_sdk_config.opinlyConfig.blogUrl}/author/${post.author.slug}`,
|
|
115
|
+
description: post.author.bio || void 0
|
|
116
|
+
} : void 0,
|
|
117
|
+
isAccessibleForFree: true,
|
|
118
|
+
articleBody: generateArticleBodyHtml(post.content)
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
const genBreadcrumbJSONLD = (post) => {
|
|
122
|
+
const itemListElement = [
|
|
123
|
+
{
|
|
124
|
+
"@type": "ListItem",
|
|
125
|
+
position: 1,
|
|
126
|
+
name: "Company Name",
|
|
127
|
+
item: import_sdk_config.opinlyConfig.siteUrl
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"@type": "ListItem",
|
|
131
|
+
position: 2,
|
|
132
|
+
name: post.folder?.name || "Blog",
|
|
133
|
+
item: `${import_sdk_config.opinlyConfig.blogUrl}/blog`
|
|
134
|
+
}
|
|
135
|
+
];
|
|
136
|
+
if (post.folder) {
|
|
137
|
+
itemListElement.push({
|
|
138
|
+
"@type": "ListItem",
|
|
139
|
+
position: 3,
|
|
140
|
+
name: post.folder.name,
|
|
141
|
+
item: `${import_sdk_config.opinlyConfig.blogUrl}/blog/${post.folder.slug}`
|
|
142
|
+
});
|
|
143
|
+
itemListElement.push({
|
|
144
|
+
"@type": "ListItem",
|
|
145
|
+
position: 4,
|
|
146
|
+
name: post.title,
|
|
147
|
+
item: `${import_sdk_config.opinlyConfig.blogUrl}/blog/${post.folder.slug}/${post.slug}`
|
|
148
|
+
});
|
|
149
|
+
} else {
|
|
150
|
+
itemListElement.push({
|
|
151
|
+
"@type": "ListItem",
|
|
152
|
+
position: 3,
|
|
153
|
+
name: post.title,
|
|
154
|
+
item: `${import_sdk_config.opinlyConfig.blogUrl}/blog/${post.slug}`
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
"@context": "https://schema.org",
|
|
159
|
+
"@type": "BreadcrumbList",
|
|
160
|
+
itemListElement
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
164
|
+
0 && (module.exports = {
|
|
165
|
+
genBlogPostingJSONLD,
|
|
166
|
+
genBreadcrumbJSONLD,
|
|
167
|
+
genFaqJSONLD,
|
|
168
|
+
generateArticleBodyHtml
|
|
169
|
+
});
|
|
170
|
+
//# sourceMappingURL=json-ld.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/blog-post/_helpers/json-ld.ts"],"sourcesContent":["import {\n BlogPosting,\n BreadcrumbList,\n FAQPage,\n WithContext,\n ListItem,\n} from \"schema-dts\";\nimport { BlogPostRes } from \"../_types/blog-post\";\nimport { opinlyConfig } from \"../../../sdk-config\";\nimport { JSONContent } from \"@tiptap/core\";\nimport { replaceImageNameSpace } from \"../../../utils/images\";\n\n// Add this function somewhere in your BlogPost component file\nexport function generateArticleBodyHtml(content: JSONContent): string {\n if (!content?.content) return \"\";\n\n let htmlString = \"\";\n\n content.content.forEach((node) => {\n switch (node.type) {\n case \"paragraph\":\n htmlString += `<p>${generateChildrenHtml(node.content)}</p>`;\n break;\n case \"heading\":\n const headingLevel = node.attrs?.level || 1;\n htmlString += `<h${headingLevel}>${generateChildrenHtml(node.content)}</h${headingLevel}>`;\n break;\n case \"bulletList\":\n htmlString += `<ul>${generateChildrenHtml(node.content)}</ul>`;\n break;\n case \"orderedList\":\n htmlString += `<ol>${generateChildrenHtml(node.content)}</ol>`;\n break;\n case \"listItem\":\n htmlString += `<li>${generateChildrenHtml(node.content)}</li>`;\n break;\n // Add other node types if they contain text content relevant for articleBody\n // For images, you might just skip them or include an <img> tag if semantic\n // For example:\n // case \"image\":\n // if (node.attrs?.src) {\n // htmlString += `<img src=\"${replaceImageHostname(node.attrs.src, opinlyConfig.imagesPrefix)}\" alt=\"${node.attrs?.alt || ''}\" />`;\n // }\n // break;\n default:\n // Handle other block types or just ignore them for articleBody\n break;\n }\n });\n\n return htmlString;\n}\n\nfunction generateChildrenHtml(\n nodes: JSONContent[\"content\"] | undefined\n): string {\n if (!nodes) return \"\";\n\n let childrenHtml = \"\";\n nodes.forEach((child) => {\n if (child.type === \"text\") {\n let text = child.text || \"\";\n if (child.marks) {\n child.marks.forEach((mark) => {\n if (mark.type === \"bold\") text = `<strong>${text}</strong>`;\n if (mark.type === \"italic\") text = `<em>${text}</em>`;\n if (mark.type === \"link\" && mark.attrs?.href) {\n text = `<a href=\"${mark.attrs.href}\">${text}</a>`;\n }\n });\n }\n childrenHtml += text;\n }\n // If you have nested content within child nodes, you might need a recursive call here\n // For example, if a list item can contain paragraphs\n // if (child.content) {\n // childrenHtml += generateChildrenHtml(child.content);\n // }\n });\n return childrenHtml;\n}\n\nexport const genFaqJSONLD = (\n faqs: NonNullable<BlogPostRes[\"faqs\"]>\n): WithContext<FAQPage> => {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"FAQPage\",\n mainEntity: faqs.map((faq) => ({\n \"@type\": \"Question\",\n name: faq.question,\n acceptedAnswer: {\n \"@type\": \"Answer\",\n text: faq.answer,\n },\n })),\n };\n};\n\nexport const genBlogPostingJSONLD = (\n post: BlogPostRes\n): WithContext<BlogPosting> => {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BlogPosting\",\n headline: post.title,\n description: post.description || undefined,\n url: `${opinlyConfig.blogUrl}/${post.folder ? `${post.folder.slug + \"/\"}${post.slug}` : post.slug}`,\n datePublished: post.firstPublishedAt || undefined,\n dateModified: post.modifiedAt || undefined,\n image: post.titleFile?.fileKey\n ? {\n \"@type\": \"ImageObject\",\n url: `${opinlyConfig.imagesUrl}/${replaceImageNameSpace(post.titleFile.fileKey)}`,\n }\n : undefined,\n author: post.author\n ? {\n \"@type\": \"Person\",\n name: post.author.name,\n url: `${opinlyConfig.blogUrl}/author/${post.author.slug}`,\n description: post.author.bio || undefined,\n }\n : undefined,\n isAccessibleForFree: true,\n articleBody: generateArticleBodyHtml(post.content as JSONContent),\n };\n};\n\nexport const genBreadcrumbJSONLD = (\n post: BlogPostRes\n): WithContext<BreadcrumbList> => {\n const itemListElement = [\n {\n \"@type\": \"ListItem\",\n position: 1,\n name: \"Company Name\",\n item: opinlyConfig.siteUrl,\n },\n {\n \"@type\": \"ListItem\",\n position: 2,\n name: post.folder?.name || \"Blog\",\n item: `${opinlyConfig.blogUrl}/blog`,\n },\n ];\n\n if (post.folder) {\n itemListElement.push({\n \"@type\": \"ListItem\",\n position: 3,\n name: post.folder.name,\n item: `${opinlyConfig.blogUrl}/blog/${post.folder.slug}`,\n });\n\n itemListElement.push({\n \"@type\": \"ListItem\",\n position: 4,\n name: post.title,\n item: `${opinlyConfig.blogUrl}/blog/${post.folder.slug}/${post.slug}`,\n });\n } else {\n itemListElement.push({\n \"@type\": \"ListItem\",\n position: 3,\n name: post.title,\n item: `${opinlyConfig.blogUrl}/blog/${post.slug}`,\n });\n }\n\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BreadcrumbList\",\n itemListElement: itemListElement as ListItem[],\n };\n};\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { WithContext, FAQPage, BlogPosting, BreadcrumbList } from 'schema-dts';
|
|
2
|
+
import { BlogPostRes } from '../_types/blog-post.cjs';
|
|
3
|
+
import { JSONContent } from '@tiptap/core';
|
|
4
|
+
import '@opinly/backend';
|
|
5
|
+
|
|
6
|
+
declare function generateArticleBodyHtml(content: JSONContent): string;
|
|
7
|
+
declare const genFaqJSONLD: (faqs: NonNullable<BlogPostRes["faqs"]>) => WithContext<FAQPage>;
|
|
8
|
+
declare const genBlogPostingJSONLD: (post: BlogPostRes) => WithContext<BlogPosting>;
|
|
9
|
+
declare const genBreadcrumbJSONLD: (post: BlogPostRes) => WithContext<BreadcrumbList>;
|
|
10
|
+
|
|
11
|
+
export { genBlogPostingJSONLD, genBreadcrumbJSONLD, genFaqJSONLD, generateArticleBodyHtml };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { WithContext, FAQPage, BlogPosting, BreadcrumbList } from 'schema-dts';
|
|
2
|
+
import { BlogPostRes } from '../_types/blog-post.js';
|
|
3
|
+
import { JSONContent } from '@tiptap/core';
|
|
4
|
+
import '@opinly/backend';
|
|
5
|
+
|
|
6
|
+
declare function generateArticleBodyHtml(content: JSONContent): string;
|
|
7
|
+
declare const genFaqJSONLD: (faqs: NonNullable<BlogPostRes["faqs"]>) => WithContext<FAQPage>;
|
|
8
|
+
declare const genBlogPostingJSONLD: (post: BlogPostRes) => WithContext<BlogPosting>;
|
|
9
|
+
declare const genBreadcrumbJSONLD: (post: BlogPostRes) => WithContext<BreadcrumbList>;
|
|
10
|
+
|
|
11
|
+
export { genBlogPostingJSONLD, genBreadcrumbJSONLD, genFaqJSONLD, generateArticleBodyHtml };
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { opinlyConfig } from "../../../sdk-config";
|
|
2
|
+
import { replaceImageNameSpace } from "../../../utils/images";
|
|
3
|
+
function generateArticleBodyHtml(content) {
|
|
4
|
+
if (!content?.content) return "";
|
|
5
|
+
let htmlString = "";
|
|
6
|
+
content.content.forEach((node) => {
|
|
7
|
+
switch (node.type) {
|
|
8
|
+
case "paragraph":
|
|
9
|
+
htmlString += `<p>${generateChildrenHtml(node.content)}</p>`;
|
|
10
|
+
break;
|
|
11
|
+
case "heading":
|
|
12
|
+
const headingLevel = node.attrs?.level || 1;
|
|
13
|
+
htmlString += `<h${headingLevel}>${generateChildrenHtml(node.content)}</h${headingLevel}>`;
|
|
14
|
+
break;
|
|
15
|
+
case "bulletList":
|
|
16
|
+
htmlString += `<ul>${generateChildrenHtml(node.content)}</ul>`;
|
|
17
|
+
break;
|
|
18
|
+
case "orderedList":
|
|
19
|
+
htmlString += `<ol>${generateChildrenHtml(node.content)}</ol>`;
|
|
20
|
+
break;
|
|
21
|
+
case "listItem":
|
|
22
|
+
htmlString += `<li>${generateChildrenHtml(node.content)}</li>`;
|
|
23
|
+
break;
|
|
24
|
+
// Add other node types if they contain text content relevant for articleBody
|
|
25
|
+
// For images, you might just skip them or include an <img> tag if semantic
|
|
26
|
+
// For example:
|
|
27
|
+
// case "image":
|
|
28
|
+
// if (node.attrs?.src) {
|
|
29
|
+
// htmlString += `<img src="${replaceImageHostname(node.attrs.src, opinlyConfig.imagesPrefix)}" alt="${node.attrs?.alt || ''}" />`;
|
|
30
|
+
// }
|
|
31
|
+
// break;
|
|
32
|
+
default:
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return htmlString;
|
|
37
|
+
}
|
|
38
|
+
function generateChildrenHtml(nodes) {
|
|
39
|
+
if (!nodes) return "";
|
|
40
|
+
let childrenHtml = "";
|
|
41
|
+
nodes.forEach((child) => {
|
|
42
|
+
if (child.type === "text") {
|
|
43
|
+
let text = child.text || "";
|
|
44
|
+
if (child.marks) {
|
|
45
|
+
child.marks.forEach((mark) => {
|
|
46
|
+
if (mark.type === "bold") text = `<strong>${text}</strong>`;
|
|
47
|
+
if (mark.type === "italic") text = `<em>${text}</em>`;
|
|
48
|
+
if (mark.type === "link" && mark.attrs?.href) {
|
|
49
|
+
text = `<a href="${mark.attrs.href}">${text}</a>`;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
childrenHtml += text;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
return childrenHtml;
|
|
57
|
+
}
|
|
58
|
+
const genFaqJSONLD = (faqs) => {
|
|
59
|
+
return {
|
|
60
|
+
"@context": "https://schema.org",
|
|
61
|
+
"@type": "FAQPage",
|
|
62
|
+
mainEntity: faqs.map((faq) => ({
|
|
63
|
+
"@type": "Question",
|
|
64
|
+
name: faq.question,
|
|
65
|
+
acceptedAnswer: {
|
|
66
|
+
"@type": "Answer",
|
|
67
|
+
text: faq.answer
|
|
68
|
+
}
|
|
69
|
+
}))
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
const genBlogPostingJSONLD = (post) => {
|
|
73
|
+
return {
|
|
74
|
+
"@context": "https://schema.org",
|
|
75
|
+
"@type": "BlogPosting",
|
|
76
|
+
headline: post.title,
|
|
77
|
+
description: post.description || void 0,
|
|
78
|
+
url: `${opinlyConfig.blogUrl}/${post.folder ? `${post.folder.slug + "/"}${post.slug}` : post.slug}`,
|
|
79
|
+
datePublished: post.firstPublishedAt || void 0,
|
|
80
|
+
dateModified: post.modifiedAt || void 0,
|
|
81
|
+
image: post.titleFile?.fileKey ? {
|
|
82
|
+
"@type": "ImageObject",
|
|
83
|
+
url: `${opinlyConfig.imagesUrl}/${replaceImageNameSpace(post.titleFile.fileKey)}`
|
|
84
|
+
} : void 0,
|
|
85
|
+
author: post.author ? {
|
|
86
|
+
"@type": "Person",
|
|
87
|
+
name: post.author.name,
|
|
88
|
+
url: `${opinlyConfig.blogUrl}/author/${post.author.slug}`,
|
|
89
|
+
description: post.author.bio || void 0
|
|
90
|
+
} : void 0,
|
|
91
|
+
isAccessibleForFree: true,
|
|
92
|
+
articleBody: generateArticleBodyHtml(post.content)
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
const genBreadcrumbJSONLD = (post) => {
|
|
96
|
+
const itemListElement = [
|
|
97
|
+
{
|
|
98
|
+
"@type": "ListItem",
|
|
99
|
+
position: 1,
|
|
100
|
+
name: "Company Name",
|
|
101
|
+
item: opinlyConfig.siteUrl
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"@type": "ListItem",
|
|
105
|
+
position: 2,
|
|
106
|
+
name: post.folder?.name || "Blog",
|
|
107
|
+
item: `${opinlyConfig.blogUrl}/blog`
|
|
108
|
+
}
|
|
109
|
+
];
|
|
110
|
+
if (post.folder) {
|
|
111
|
+
itemListElement.push({
|
|
112
|
+
"@type": "ListItem",
|
|
113
|
+
position: 3,
|
|
114
|
+
name: post.folder.name,
|
|
115
|
+
item: `${opinlyConfig.blogUrl}/blog/${post.folder.slug}`
|
|
116
|
+
});
|
|
117
|
+
itemListElement.push({
|
|
118
|
+
"@type": "ListItem",
|
|
119
|
+
position: 4,
|
|
120
|
+
name: post.title,
|
|
121
|
+
item: `${opinlyConfig.blogUrl}/blog/${post.folder.slug}/${post.slug}`
|
|
122
|
+
});
|
|
123
|
+
} else {
|
|
124
|
+
itemListElement.push({
|
|
125
|
+
"@type": "ListItem",
|
|
126
|
+
position: 3,
|
|
127
|
+
name: post.title,
|
|
128
|
+
item: `${opinlyConfig.blogUrl}/blog/${post.slug}`
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
"@context": "https://schema.org",
|
|
133
|
+
"@type": "BreadcrumbList",
|
|
134
|
+
itemListElement
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
export {
|
|
138
|
+
genBlogPostingJSONLD,
|
|
139
|
+
genBreadcrumbJSONLD,
|
|
140
|
+
genFaqJSONLD,
|
|
141
|
+
generateArticleBodyHtml
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=json-ld.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/blog-post/_helpers/json-ld.ts"],"sourcesContent":["import {\n BlogPosting,\n BreadcrumbList,\n FAQPage,\n WithContext,\n ListItem,\n} from \"schema-dts\";\nimport { BlogPostRes } from \"../_types/blog-post\";\nimport { opinlyConfig } from \"../../../sdk-config\";\nimport { JSONContent } from \"@tiptap/core\";\nimport { replaceImageNameSpace } from \"../../../utils/images\";\n\n// Add this function somewhere in your BlogPost component file\nexport function generateArticleBodyHtml(content: JSONContent): string {\n if (!content?.content) return \"\";\n\n let htmlString = \"\";\n\n content.content.forEach((node) => {\n switch (node.type) {\n case \"paragraph\":\n htmlString += `<p>${generateChildrenHtml(node.content)}</p>`;\n break;\n case \"heading\":\n const headingLevel = node.attrs?.level || 1;\n htmlString += `<h${headingLevel}>${generateChildrenHtml(node.content)}</h${headingLevel}>`;\n break;\n case \"bulletList\":\n htmlString += `<ul>${generateChildrenHtml(node.content)}</ul>`;\n break;\n case \"orderedList\":\n htmlString += `<ol>${generateChildrenHtml(node.content)}</ol>`;\n break;\n case \"listItem\":\n htmlString += `<li>${generateChildrenHtml(node.content)}</li>`;\n break;\n // Add other node types if they contain text content relevant for articleBody\n // For images, you might just skip them or include an <img> tag if semantic\n // For example:\n // case \"image\":\n // if (node.attrs?.src) {\n // htmlString += `<img src=\"${replaceImageHostname(node.attrs.src, opinlyConfig.imagesPrefix)}\" alt=\"${node.attrs?.alt || ''}\" />`;\n // }\n // break;\n default:\n // Handle other block types or just ignore them for articleBody\n break;\n }\n });\n\n return htmlString;\n}\n\nfunction generateChildrenHtml(\n nodes: JSONContent[\"content\"] | undefined\n): string {\n if (!nodes) return \"\";\n\n let childrenHtml = \"\";\n nodes.forEach((child) => {\n if (child.type === \"text\") {\n let text = child.text || \"\";\n if (child.marks) {\n child.marks.forEach((mark) => {\n if (mark.type === \"bold\") text = `<strong>${text}</strong>`;\n if (mark.type === \"italic\") text = `<em>${text}</em>`;\n if (mark.type === \"link\" && mark.attrs?.href) {\n text = `<a href=\"${mark.attrs.href}\">${text}</a>`;\n }\n });\n }\n childrenHtml += text;\n }\n // If you have nested content within child nodes, you might need a recursive call here\n // For example, if a list item can contain paragraphs\n // if (child.content) {\n // childrenHtml += generateChildrenHtml(child.content);\n // }\n });\n return childrenHtml;\n}\n\nexport const genFaqJSONLD = (\n faqs: NonNullable<BlogPostRes[\"faqs\"]>\n): WithContext<FAQPage> => {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"FAQPage\",\n mainEntity: faqs.map((faq) => ({\n \"@type\": \"Question\",\n name: faq.question,\n acceptedAnswer: {\n \"@type\": \"Answer\",\n text: faq.answer,\n },\n })),\n };\n};\n\nexport const genBlogPostingJSONLD = (\n post: BlogPostRes\n): WithContext<BlogPosting> => {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BlogPosting\",\n headline: post.title,\n description: post.description || undefined,\n url: `${opinlyConfig.blogUrl}/${post.folder ? `${post.folder.slug + \"/\"}${post.slug}` : post.slug}`,\n datePublished: post.firstPublishedAt || undefined,\n dateModified: post.modifiedAt || undefined,\n image: post.titleFile?.fileKey\n ? {\n \"@type\": \"ImageObject\",\n url: `${opinlyConfig.imagesUrl}/${replaceImageNameSpace(post.titleFile.fileKey)}`,\n }\n : undefined,\n author: post.author\n ? {\n \"@type\": \"Person\",\n name: post.author.name,\n url: `${opinlyConfig.blogUrl}/author/${post.author.slug}`,\n description: post.author.bio || undefined,\n }\n : undefined,\n isAccessibleForFree: true,\n articleBody: generateArticleBodyHtml(post.content as JSONContent),\n };\n};\n\nexport const genBreadcrumbJSONLD = (\n post: BlogPostRes\n): WithContext<BreadcrumbList> => {\n const itemListElement = [\n {\n \"@type\": \"ListItem\",\n position: 1,\n name: \"Company Name\",\n item: opinlyConfig.siteUrl,\n },\n {\n \"@type\": \"ListItem\",\n position: 2,\n name: post.folder?.name || \"Blog\",\n item: `${opinlyConfig.blogUrl}/blog`,\n },\n ];\n\n if (post.folder) {\n itemListElement.push({\n \"@type\": \"ListItem\",\n position: 3,\n name: post.folder.name,\n item: `${opinlyConfig.blogUrl}/blog/${post.folder.slug}`,\n });\n\n itemListElement.push({\n \"@type\": \"ListItem\",\n position: 4,\n name: post.title,\n item: `${opinlyConfig.blogUrl}/blog/${post.folder.slug}/${post.slug}`,\n });\n } else {\n itemListElement.push({\n \"@type\": \"ListItem\",\n position: 3,\n name: post.title,\n item: `${opinlyConfig.blogUrl}/blog/${post.slug}`,\n });\n }\n\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BreadcrumbList\",\n itemListElement: itemListElement as ListItem[],\n };\n};\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var reading_time_exports = {};
|
|
20
|
+
__export(reading_time_exports, {
|
|
21
|
+
calculateReadingTime: () => calculateReadingTime,
|
|
22
|
+
countWords: () => countWords
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(reading_time_exports);
|
|
25
|
+
const countWords = (content) => {
|
|
26
|
+
if (!content?.content) return 0;
|
|
27
|
+
let wordCount = 0;
|
|
28
|
+
const countWords2 = (nodes) => {
|
|
29
|
+
for (const node of nodes) {
|
|
30
|
+
if (node.type === "text" && node.text) {
|
|
31
|
+
const words = node.text.trim().split(/\s+/).filter(Boolean);
|
|
32
|
+
wordCount += words.length;
|
|
33
|
+
}
|
|
34
|
+
if (node.content) countWords2(node.content);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
countWords2(content.content);
|
|
38
|
+
return wordCount;
|
|
39
|
+
};
|
|
40
|
+
function calculateReadingTime(content) {
|
|
41
|
+
const wordCount = countWords(content.content);
|
|
42
|
+
const readingTimeMinutes = Math.ceil(wordCount / 200);
|
|
43
|
+
return readingTimeMinutes;
|
|
44
|
+
}
|
|
45
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
46
|
+
0 && (module.exports = {
|
|
47
|
+
calculateReadingTime,
|
|
48
|
+
countWords
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=reading-time.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/blog-post/_helpers/reading-time.ts"],"sourcesContent":["import { JSONContent } from \"@tiptap/core\";\n\nexport const countWords = (content: JSONContent | undefined): number => {\n if (!content?.content) return 0;\n\n let wordCount = 0;\n\n const countWords = (nodes: any[]) => {\n for (const node of nodes) {\n if (node.type === \"text\" && node.text) {\n const words = node.text.trim().split(/\\s+/).filter(Boolean);\n wordCount += words.length;\n }\n if (node.content) countWords(node.content);\n }\n };\n\n countWords(content.content);\n\n return wordCount;\n};\n\nexport function calculateReadingTime(content: JSONContent): number {\n const wordCount = countWords(content.content);\n\n const readingTimeMinutes = Math.ceil(wordCount / 200);\n return readingTimeMinutes;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEO,MAAM,aAAa,CAAC,YAA6C;AACtE,MAAI,CAAC,SAAS,QAAS,QAAO;AAE9B,MAAI,YAAY;AAEhB,QAAMA,cAAa,CAAC,UAAiB;AACnC,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,SAAS,UAAU,KAAK,MAAM;AACrC,cAAM,QAAQ,KAAK,KAAK,KAAK,EAAE,MAAM,KAAK,EAAE,OAAO,OAAO;AAC1D,qBAAa,MAAM;AAAA,MACrB;AACA,UAAI,KAAK,QAAS,CAAAA,YAAW,KAAK,OAAO;AAAA,IAC3C;AAAA,EACF;AAEA,EAAAA,YAAW,QAAQ,OAAO;AAE1B,SAAO;AACT;AAEO,SAAS,qBAAqB,SAA8B;AACjE,QAAM,YAAY,WAAW,QAAQ,OAAO;AAE5C,QAAM,qBAAqB,KAAK,KAAK,YAAY,GAAG;AACpD,SAAO;AACT;","names":["countWords"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const countWords = (content) => {
|
|
2
|
+
if (!content?.content) return 0;
|
|
3
|
+
let wordCount = 0;
|
|
4
|
+
const countWords2 = (nodes) => {
|
|
5
|
+
for (const node of nodes) {
|
|
6
|
+
if (node.type === "text" && node.text) {
|
|
7
|
+
const words = node.text.trim().split(/\s+/).filter(Boolean);
|
|
8
|
+
wordCount += words.length;
|
|
9
|
+
}
|
|
10
|
+
if (node.content) countWords2(node.content);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
countWords2(content.content);
|
|
14
|
+
return wordCount;
|
|
15
|
+
};
|
|
16
|
+
function calculateReadingTime(content) {
|
|
17
|
+
const wordCount = countWords(content.content);
|
|
18
|
+
const readingTimeMinutes = Math.ceil(wordCount / 200);
|
|
19
|
+
return readingTimeMinutes;
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
calculateReadingTime,
|
|
23
|
+
countWords
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=reading-time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/blog-post/_helpers/reading-time.ts"],"sourcesContent":["import { JSONContent } from \"@tiptap/core\";\n\nexport const countWords = (content: JSONContent | undefined): number => {\n if (!content?.content) return 0;\n\n let wordCount = 0;\n\n const countWords = (nodes: any[]) => {\n for (const node of nodes) {\n if (node.type === \"text\" && node.text) {\n const words = node.text.trim().split(/\\s+/).filter(Boolean);\n wordCount += words.length;\n }\n if (node.content) countWords(node.content);\n }\n };\n\n countWords(content.content);\n\n return wordCount;\n};\n\nexport function calculateReadingTime(content: JSONContent): number {\n const wordCount = countWords(content.content);\n\n const readingTimeMinutes = Math.ceil(wordCount / 200);\n return readingTimeMinutes;\n}\n"],"mappings":"AAEO,MAAM,aAAa,CAAC,YAA6C;AACtE,MAAI,CAAC,SAAS,QAAS,QAAO;AAE9B,MAAI,YAAY;AAEhB,QAAMA,cAAa,CAAC,UAAiB;AACnC,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,SAAS,UAAU,KAAK,MAAM;AACrC,cAAM,QAAQ,KAAK,KAAK,KAAK,EAAE,MAAM,KAAK,EAAE,OAAO,OAAO;AAC1D,qBAAa,MAAM;AAAA,MACrB;AACA,UAAI,KAAK,QAAS,CAAAA,YAAW,KAAK,OAAO;AAAA,IAC3C;AAAA,EACF;AAEA,EAAAA,YAAW,QAAQ,OAAO;AAE1B,SAAO;AACT;AAEO,SAAS,qBAAqB,SAA8B;AACjE,QAAM,YAAY,WAAW,QAAQ,OAAO;AAE5C,QAAM,qBAAqB,KAAK,KAAK,YAAY,GAAG;AACpD,SAAO;AACT;","names":["countWords"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var blog_post_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(blog_post_exports);
|
|
17
|
+
//# sourceMappingURL=blog-post.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/blog-post/_types/blog-post.ts"],"sourcesContent":["import type { Opinly } from \"@opinly/backend\";\n\nexport type BlogPostRes = Extract<\n Awaited<ReturnType<Opinly[\"content\"][\"blog\"]>>,\n { type: \"post\" }\n>[\"data\"];\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=blog-post.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var class_names_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(class_names_exports);
|
|
17
|
+
//# sourceMappingURL=class-names.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/blog-post/_types/class-names.ts"],"sourcesContent":["export type BlogComponentClassNames = {\n paragraph?: string;\n heading?: string;\n image?: string;\n bulletList?: string;\n orderedList?: string;\n listItem?: string;\n link?: string;\n container?: string;\n};\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|