feat(documentation-directory): add typed markdown directory ingestion with author normalization and test coverage

This commit is contained in:
2026-05-02 09:43:51 +00:00
parent 179ccd3883
commit 58c786cbec
19 changed files with 7949 additions and 17889 deletions
+4 -4
View File
@@ -1,8 +1,8 @@
/**
* autocreated commitinfo by @pushrocks/commitinfo
* autocreated commitinfo by @push.rocks/commitinfo
*/
export const commitinfo = {
name: '@pushrocks/smartdocumentation',
version: '1.0.2',
description: 'a tool for mapping git directories to documentation sites'
name: '@push.rocks/smartdocumentation',
version: '1.1.0',
description: 'A tool for converting git directory structures into navigable documentation sites.'
}
+98
View File
@@ -0,0 +1,98 @@
import * as plugins from './plugins.js';
export interface IDocumentationDirectoryConstructorOptions {
pathArg: string;
}
/**
* a documentation directory maps to a directory with markdown documents
*/
export class DocumentationDirectory {
public options: IDocumentationDirectoryConstructorOptions;
public smartmarkdownInstance = new plugins.smartmarkdown.SmartMarkdown();
public articles: plugins.tsclass.content.IArticle[] = [];
constructor(optionsArg: IDocumentationDirectoryConstructorOptions) {
this.options = optionsArg;
}
/**
* reads a directory
*/
public async readDirectory() {
const smartfileFactory = plugins.smartfile.SmartFileFactory.nodeFs();
const virtualDirectory = await smartfileFactory.virtualDirectoryFromPath(this.options.pathArg);
const fileTreeComplete = virtualDirectory.listFiles();
const articles: plugins.tsclass.content.IArticle[] = [];
for (const markdownFile of fileTreeComplete.filter(
(fileArg) => fileArg.parsedPath.ext === '.md'
)) {
const parsedMarkdown = await this.smartmarkdownInstance.getMdParsedResultFromMarkdown(
markdownFile.contents.toString()
);
const frontmatterTitle = parsedMarkdown.frontmatterData.title;
articles.push({
title: typeof frontmatterTitle === 'string' ? frontmatterTitle : markdownFile.parsedPath.name,
author: this.normalizeAuthor(parsedMarkdown.frontmatterData.author),
content: parsedMarkdown.originalString,
timestamp: Date.now(),
tags: [`path:${markdownFile.path}`],
});
}
this.articles = articles;
}
private normalizeAuthor(authorArg: unknown): plugins.tsclass.content.IAuthor {
if (typeof authorArg === 'object' && authorArg !== null) {
const authorCandidate = authorArg as Partial<plugins.tsclass.content.IAuthor>;
if (
typeof authorCandidate.firstName === 'string' &&
typeof authorCandidate.surName === 'string' &&
authorCandidate.birthday &&
typeof authorCandidate.birthday.day === 'number' &&
typeof authorCandidate.birthday.month === 'number' &&
typeof authorCandidate.birthday.year === 'number'
) {
return {
firstName: authorCandidate.firstName,
surName: authorCandidate.surName,
birthday: authorCandidate.birthday,
articles: Array.isArray(authorCandidate.articles) ? authorCandidate.articles : [],
};
}
}
if (typeof authorArg === 'string' && authorArg.trim()) {
const [firstName, ...surNameParts] = authorArg.trim().split(/\s+/);
return {
firstName,
surName: surNameParts.join(' '),
birthday: {
day: 1,
month: 1,
year: 1970,
},
articles: [],
};
}
return {
firstName: 'Unknown',
surName: 'Author',
birthday: {
day: 1,
month: 1,
year: 1970,
},
articles: [],
};
}
public sendAsDocumentationSet(nameArg: string, targetArg: string): void {
void nameArg;
void targetArg;
}
public async processDirectoryForMkdocs() {}
}
+1 -3
View File
@@ -1,3 +1 @@
import * as plugins from './smartdocumentation.plugins.js';
export let demoExport = 'Hi there! :) This is an exported string';
export * from './classes.documentationdirectory.js';
+9
View File
@@ -0,0 +1,9 @@
import * as tsclass from '@tsclass/tsclass';
import * as smartfile from '@push.rocks/smartfile';
import * as smartmarkdown from '@push.rocks/smartmarkdown';
export {
tsclass,
smartfile,
smartmarkdown,
};
@@ -1,48 +0,0 @@
import * as plugins from './smartdocumentation.plugins.js';
export interface IDocumentationDirectoryConstructorOptions {
pathArg: string;
}
/**
* a documentation directory maps to a directory with markdown documents
*/
export class DocumentationDirectory {
public options: IDocumentationDirectoryConstructorOptions;
public smartmarkdownInstance = new plugins.smartmarkdown.SmartMarkdown();
public articles: plugins.tsclass.content.IArticle[];
constructor(optionsArg: IDocumentationDirectoryConstructorOptions) {
this.options = optionsArg;
}
/**
* reads a directory
*/
public async readDirectory() {
const fileTreeComplete = await plugins.smartfile.fs.fileTreeToObject(
this.options.pathArg,
'**/*'
);
const articles: plugins.tsclass.content.IArticle[] = [];
for (const markdownFile of fileTreeComplete.filter(
(fileArg) => fileArg.parsedPath.ext === '.md'
)) {
const parsedMarkdown = await this.smartmarkdownInstance.getMdParsedResultFromMarkdown(markdownFile.contents.toString())
articles.push({
title: parsedMarkdown.title,
author: parsedMarkdown.frontmatterData.author,
content: parsedMarkdown.originalString,
timestamp: Date.now(),
tags: [
`path:${markdownFile.path}`,
],
});
}
this.articles = articles;
}
sendAsDocumentationSet(nameArg: string, targetArg: string) {
}
}
-9
View File
@@ -1,9 +0,0 @@
import * as tsclass from '@tsclass/tsclass';
import * as smartfile from '@pushrocks/smartfile';
import * as smartmarkdown from '@pushrocks/smartmarkdown';
export {
tsclass,
smartfile,
smartmarkdown,
}