@haroonwaves/blog-kit-core 0.0.4

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 ADDED
@@ -0,0 +1,35 @@
1
+ # @haroonwaves/blog-kit-core
2
+
3
+ Core utilities for parsing markdown blog files with frontmatter. Extract metadata, calculate reading
4
+ time, and manage blog content in Node and React applications.
5
+
6
+ ## Installation
7
+
8
+ ```bash
9
+ npm install @haroonwaves/blog-kit-core
10
+ # or
11
+ pnpm add @haroonwaves/blog-kit-core
12
+ # or
13
+ yarn add @haroonwaves/blog-kit-core
14
+ ```
15
+
16
+ ## Documentation
17
+
18
+ For complete documentation, API reference, and examples, please visit the
19
+ [main documentation](https://github.com/haroonwaves/blog-kit).
20
+
21
+ ## Quick Links
22
+
23
+ - [Core Package Usage](https://github.com/haroonwaves/blog-kit#core-package)
24
+ - [API Reference](https://github.com/haroonwaves/blog-kit#api-reference)
25
+ - [Blog File Format](https://github.com/haroonwaves/blog-kit#blog-file-format)
26
+ - [Type Definitions](https://github.com/haroonwaves/blog-kit#types)
27
+
28
+ ## Related Packages
29
+
30
+ - [@haroonwaves/blog-kit-react](https://www.npmjs.com/package/@haroonwaves/blog-kit-react) - React
31
+ components for rendering blogs
32
+
33
+ ## License
34
+
35
+ ISC
package/dist/index.cjs ADDED
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ extractBlog: () => extractBlog,
34
+ extractBlogMeta: () => extractBlogMeta,
35
+ getAllBlogsMeta: () => getAllBlogsMeta,
36
+ getBlog: () => getBlog
37
+ });
38
+ module.exports = __toCommonJS(src_exports);
39
+
40
+ // src/parser.ts
41
+ var import_fs = __toESM(require("fs"), 1);
42
+ var import_path = __toESM(require("path"), 1);
43
+ var import_gray_matter = __toESM(require("gray-matter"), 1);
44
+ var import_reading_time = __toESM(require("reading-time"), 1);
45
+ function extractBlogMeta(content, slug) {
46
+ const { data, content: markdownContent } = (0, import_gray_matter.default)(content);
47
+ const readingTimeText = (0, import_reading_time.default)(markdownContent).text;
48
+ return {
49
+ slug,
50
+ ...data,
51
+ readingTime: readingTimeText
52
+ };
53
+ }
54
+ function extractBlog(content, slug) {
55
+ const { data, content: markdownContent } = (0, import_gray_matter.default)(content);
56
+ const readingTimeText = (0, import_reading_time.default)(markdownContent).text;
57
+ return {
58
+ metadata: {
59
+ ...data,
60
+ slug,
61
+ readingTime: readingTimeText
62
+ },
63
+ content: markdownContent,
64
+ readingTime: readingTimeText
65
+ };
66
+ }
67
+ function getAllBlogsMeta(config) {
68
+ const blogDirectory = import_path.default.join(config.contentDirectory, config.blogSubdirectory || "blog");
69
+ if (!import_fs.default.existsSync(blogDirectory)) {
70
+ console.warn(`Blog directory not found: ${blogDirectory}`);
71
+ return [];
72
+ }
73
+ const files = import_fs.default.readdirSync(blogDirectory);
74
+ const blogs = files.filter((file) => file.endsWith(".md")).map((file) => {
75
+ const slug = file.replace(".md", "");
76
+ const filePath = import_path.default.join(blogDirectory, file);
77
+ const fileContent = import_fs.default.readFileSync(filePath, "utf8");
78
+ const { data, content } = (0, import_gray_matter.default)(fileContent);
79
+ const readingTimeText = (0, import_reading_time.default)(content).text;
80
+ return {
81
+ slug,
82
+ ...data,
83
+ readingTime: readingTimeText
84
+ };
85
+ }).sort((a, b) => {
86
+ return new Date(b.date).getTime() - new Date(a.date).getTime();
87
+ });
88
+ return blogs;
89
+ }
90
+ function getBlog(slug, config) {
91
+ const blogDirectory = import_path.default.join(config.contentDirectory, config.blogSubdirectory || "blog");
92
+ const filePath = import_path.default.join(blogDirectory, `${slug}.md`);
93
+ if (!import_fs.default.existsSync(filePath)) {
94
+ return null;
95
+ }
96
+ const fileContent = import_fs.default.readFileSync(filePath, "utf8");
97
+ const { data, content } = (0, import_gray_matter.default)(fileContent);
98
+ const readingTimeText = (0, import_reading_time.default)(content).text;
99
+ return {
100
+ metadata: {
101
+ ...data,
102
+ slug
103
+ },
104
+ content,
105
+ readingTime: readingTimeText
106
+ };
107
+ }
108
+ // Annotate the CommonJS export names for ESM import in node:
109
+ 0 && (module.exports = {
110
+ extractBlog,
111
+ extractBlogMeta,
112
+ getAllBlogsMeta,
113
+ getBlog
114
+ });
@@ -0,0 +1,59 @@
1
+ interface BlogMeta {
2
+ title: string;
3
+ description: string;
4
+ date: string;
5
+ category?: string;
6
+ slug: string;
7
+ readingTime: string;
8
+ }
9
+ interface Blog {
10
+ metadata: BlogMeta;
11
+ content: string;
12
+ readingTime: string;
13
+ }
14
+ interface BlogConfig {
15
+ contentDirectory: string;
16
+ blogSubdirectory?: string;
17
+ }
18
+
19
+ /**
20
+ * Client-side compatible: Extract blog metadata from raw markdown content.
21
+ * This function works in browser environments (pure React) where you have
22
+ * the markdown content as a string (e.g., fetched from an API or imported).
23
+ *
24
+ * @param content - Raw markdown content string
25
+ * @param slug - Blog post slug/identifier
26
+ * @returns Parsed blog metadata
27
+ */
28
+ declare function extractBlogMeta(content: string, slug: string): BlogMeta;
29
+ /**
30
+ * Client-side compatible: Extract blog data from raw markdown content.
31
+ * This function works in browser environments (pure React) where you have
32
+ * the markdown content as a string (e.g., fetched from an API or imported).
33
+ *
34
+ * @param content - Raw markdown content string
35
+ * @param slug - Blog post slug/identifier
36
+ * @returns Parsed blog data with metadata and content
37
+ */
38
+ declare function extractBlog(content: string, slug: string): Blog;
39
+ /**
40
+ * SSR and SSG only: Get all blogs metadata from the filesystem.
41
+ * This function requires Node.js fs module and only works in server environments
42
+ * (Next.js SSR/SSG, Node.js scripts, etc.).
43
+ *
44
+ * @param config - Blog kit configuration
45
+ * @returns Array of blog metadata
46
+ */
47
+ declare function getAllBlogsMeta(config: BlogConfig): BlogMeta[];
48
+ /**
49
+ * SSR and SSG only: Get blog from the filesystem.
50
+ * This function requires Node.js fs module and only works in server environments
51
+ * (Next.js SSR/SSG, Node.js scripts, etc.).
52
+ *
53
+ * @param slug - Blog post slug/identifier
54
+ * @param config - Blog kit configuration
55
+ * @returns Blog data or null if not found
56
+ */
57
+ declare function getBlog(slug: string, config: BlogConfig): Blog | null;
58
+
59
+ export { type Blog, type BlogConfig, type BlogMeta, extractBlog, extractBlogMeta, getAllBlogsMeta, getBlog };
@@ -0,0 +1,59 @@
1
+ interface BlogMeta {
2
+ title: string;
3
+ description: string;
4
+ date: string;
5
+ category?: string;
6
+ slug: string;
7
+ readingTime: string;
8
+ }
9
+ interface Blog {
10
+ metadata: BlogMeta;
11
+ content: string;
12
+ readingTime: string;
13
+ }
14
+ interface BlogConfig {
15
+ contentDirectory: string;
16
+ blogSubdirectory?: string;
17
+ }
18
+
19
+ /**
20
+ * Client-side compatible: Extract blog metadata from raw markdown content.
21
+ * This function works in browser environments (pure React) where you have
22
+ * the markdown content as a string (e.g., fetched from an API or imported).
23
+ *
24
+ * @param content - Raw markdown content string
25
+ * @param slug - Blog post slug/identifier
26
+ * @returns Parsed blog metadata
27
+ */
28
+ declare function extractBlogMeta(content: string, slug: string): BlogMeta;
29
+ /**
30
+ * Client-side compatible: Extract blog data from raw markdown content.
31
+ * This function works in browser environments (pure React) where you have
32
+ * the markdown content as a string (e.g., fetched from an API or imported).
33
+ *
34
+ * @param content - Raw markdown content string
35
+ * @param slug - Blog post slug/identifier
36
+ * @returns Parsed blog data with metadata and content
37
+ */
38
+ declare function extractBlog(content: string, slug: string): Blog;
39
+ /**
40
+ * SSR and SSG only: Get all blogs metadata from the filesystem.
41
+ * This function requires Node.js fs module and only works in server environments
42
+ * (Next.js SSR/SSG, Node.js scripts, etc.).
43
+ *
44
+ * @param config - Blog kit configuration
45
+ * @returns Array of blog metadata
46
+ */
47
+ declare function getAllBlogsMeta(config: BlogConfig): BlogMeta[];
48
+ /**
49
+ * SSR and SSG only: Get blog from the filesystem.
50
+ * This function requires Node.js fs module and only works in server environments
51
+ * (Next.js SSR/SSG, Node.js scripts, etc.).
52
+ *
53
+ * @param slug - Blog post slug/identifier
54
+ * @param config - Blog kit configuration
55
+ * @returns Blog data or null if not found
56
+ */
57
+ declare function getBlog(slug: string, config: BlogConfig): Blog | null;
58
+
59
+ export { type Blog, type BlogConfig, type BlogMeta, extractBlog, extractBlogMeta, getAllBlogsMeta, getBlog };
package/dist/index.js ADDED
@@ -0,0 +1,74 @@
1
+ // src/parser.ts
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import matter from "gray-matter";
5
+ import readingTime from "reading-time";
6
+ function extractBlogMeta(content, slug) {
7
+ const { data, content: markdownContent } = matter(content);
8
+ const readingTimeText = readingTime(markdownContent).text;
9
+ return {
10
+ slug,
11
+ ...data,
12
+ readingTime: readingTimeText
13
+ };
14
+ }
15
+ function extractBlog(content, slug) {
16
+ const { data, content: markdownContent } = matter(content);
17
+ const readingTimeText = readingTime(markdownContent).text;
18
+ return {
19
+ metadata: {
20
+ ...data,
21
+ slug,
22
+ readingTime: readingTimeText
23
+ },
24
+ content: markdownContent,
25
+ readingTime: readingTimeText
26
+ };
27
+ }
28
+ function getAllBlogsMeta(config) {
29
+ const blogDirectory = path.join(config.contentDirectory, config.blogSubdirectory || "blog");
30
+ if (!fs.existsSync(blogDirectory)) {
31
+ console.warn(`Blog directory not found: ${blogDirectory}`);
32
+ return [];
33
+ }
34
+ const files = fs.readdirSync(blogDirectory);
35
+ const blogs = files.filter((file) => file.endsWith(".md")).map((file) => {
36
+ const slug = file.replace(".md", "");
37
+ const filePath = path.join(blogDirectory, file);
38
+ const fileContent = fs.readFileSync(filePath, "utf8");
39
+ const { data, content } = matter(fileContent);
40
+ const readingTimeText = readingTime(content).text;
41
+ return {
42
+ slug,
43
+ ...data,
44
+ readingTime: readingTimeText
45
+ };
46
+ }).sort((a, b) => {
47
+ return new Date(b.date).getTime() - new Date(a.date).getTime();
48
+ });
49
+ return blogs;
50
+ }
51
+ function getBlog(slug, config) {
52
+ const blogDirectory = path.join(config.contentDirectory, config.blogSubdirectory || "blog");
53
+ const filePath = path.join(blogDirectory, `${slug}.md`);
54
+ if (!fs.existsSync(filePath)) {
55
+ return null;
56
+ }
57
+ const fileContent = fs.readFileSync(filePath, "utf8");
58
+ const { data, content } = matter(fileContent);
59
+ const readingTimeText = readingTime(content).text;
60
+ return {
61
+ metadata: {
62
+ ...data,
63
+ slug
64
+ },
65
+ content,
66
+ readingTime: readingTimeText
67
+ };
68
+ }
69
+ export {
70
+ extractBlog,
71
+ extractBlogMeta,
72
+ getAllBlogsMeta,
73
+ getBlog
74
+ };
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@haroonwaves/blog-kit-core",
3
+ "version": "0.0.4",
4
+ "main": "dist/index.js",
5
+ "module": "dist/index.mjs",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "dependencies": {
12
+ "gray-matter": "^4.0.3",
13
+ "reading-time": "^1.5.0"
14
+ },
15
+ "devDependencies": {
16
+ "tsup": "^7.2.0"
17
+ },
18
+ "scripts": {
19
+ "build": "tsup src/index.ts --format cjs,esm --dts",
20
+ "type-check": "tsc --noEmit"
21
+ }
22
+ }