Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add configuration with include/exclude options #97

Merged
merged 4 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/rude-pants-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"mddb": minor
---

- Add configuration with include/exclude options
8 changes: 8 additions & 0 deletions markdowndb.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default {
computedFields: [], // Array of functions to computed fields
schemas: {
// Add zod schemas
},
include: [], // Pattern for files to be included
exclude: [] // Patten for files to be excluded
};
20 changes: 17 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@
"types": "./dist/src/index.d.ts",
"dependencies": {
"@portaljs/remark-wiki-link": "^1.0.4",
"@types/micromatch": "^4.0.6",
"chokidar": "^3.5.3",
"gray-matter": "^4.0.3",
"knex": "^2.4.2",
"micromatch": "^4.0.5",
"react-markdown": "^9.0.1",
"remark-gfm": "^3.0.1",
"remark-parse": "^10.0.1",
Expand Down
25 changes: 18 additions & 7 deletions src/bin/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
#!/usr/bin/env node

import { MarkdownDB } from "../lib/markdowndb.js";

// TODO get these from markdowndb.config.js or something
const dbPath = "markdown.db";
const ignorePatterns = [/Excalidraw/, /\.obsidian/, /DS_Store/];
const [contentPath, watchFlag] = process.argv.slice(2);

if (!contentPath) {
throw new Error("Invalid/Missing path to markdown content folder");
let watchFlag;
const args = process.argv.slice(2);

// Check for the watch flag and its position
const watchIndex = args.indexOf('--watch');
if (watchIndex !== -1) {
watchFlag = args[watchIndex];
args.splice(watchIndex, 1); // Remove the watch flag from the array
}

const watchEnabled = watchFlag && watchFlag === "--watch";
// Assign values to contentPath and configFilePath based on their positions
const [contentPath, configFilePath] = args;

if (!contentPath) {
console.error('Invalid/Missing path to markdown content folder');
process.exit(1);
}

const client = new MarkdownDB({
client: "sqlite3",
Expand All @@ -25,9 +35,10 @@ await client.init();
await client.indexFolder({
folderPath: contentPath,
ignorePatterns: ignorePatterns,
watch: watchEnabled,
watch: watchFlag,
configFilePath: configFilePath
});

if (!watchEnabled) {
if (!watchFlag) {
process.exit();
}
2 changes: 2 additions & 0 deletions src/lib/CustomConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
import { Root } from "remark-parse/lib/index.js";
import { ZodObject } from "zod";

type ComputedFields = ((fileInfo: FileInfo, ast: Root) => any)[];

Check warning on line 5 in src/lib/CustomConfig.ts

View workflow job for this annotation

GitHub Actions / Lint & format check

Unexpected any. Specify a different type
type Schemas = { [index: string]: ZodObject<any> };

Check warning on line 6 in src/lib/CustomConfig.ts

View workflow job for this annotation

GitHub Actions / Lint & format check

Unexpected any. Specify a different type

export interface CustomConfig {
computedFields?: ComputedFields;
schemas?: Schemas;
include?: string[];
exclude?: string[];
}
57 changes: 49 additions & 8 deletions src/lib/indexFolder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ZodError } from "zod";
import { CustomConfig } from "./CustomConfig.js";
import { FileInfo, processFile } from "./process.js";
import { recursiveWalkDir } from "./recursiveWalkDir.js";
import micromatch from "micromatch";

export function indexFolder(
folderPath: string,
Expand All @@ -11,7 +12,12 @@ export function indexFolder(
) {
const filePathsToIndex = recursiveWalkDir(folderPath);
const filteredFilePathsToIndex = filePathsToIndex.filter((filePath) =>
shouldIncludeFile(filePath, ignorePatterns)
shouldIncludeFile({
filePath,
ignorePatterns,
includeGlob: config.include,
excludeGlob: config.exclude,
})
);
const files: FileInfo[] = [];
const computedFields = config.computedFields || [];
Expand Down Expand Up @@ -56,11 +62,46 @@ export function indexFolder(
return files;
}

export function shouldIncludeFile(
filePath: string,
ignorePatterns?: RegExp[]
): boolean {
return !(
ignorePatterns && ignorePatterns.some((pattern) => pattern.test(filePath))
);
export function shouldIncludeFile({
filePath,
ignorePatterns,
includeGlob,
excludeGlob,
}: {
filePath: string;
ignorePatterns?: RegExp[];
includeGlob?: string[];
excludeGlob?: string[];
}): boolean {
const normalizedFilePath = filePath.replace(/\\/g, "/");

if (
ignorePatterns &&
ignorePatterns.some((pattern) => pattern.test(normalizedFilePath))
) {
return false;
}

// Check if the file should be included based on includeGlob
if (
includeGlob &&
includeGlob.length > 0 &&
!includeGlob.some((pattern) =>
micromatch.isMatch(normalizedFilePath, pattern)
)
) {
return false;
}

// Check if the file should be excluded based on excludeGlob
if (
excludeGlob &&
excludeGlob.some((pattern) =>
micromatch.isMatch(normalizedFilePath, pattern)
)
) {
return false;
}

return true;
}
18 changes: 18 additions & 0 deletions src/lib/loadConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as path from "path";

export async function loadConfig(configFilePath?: string) {
const normalizedPath = path.resolve(configFilePath || "markdowndb.config.js");
const fileUrl = new URL(`file://${normalizedPath}`);

try {
// Import the module using the file URL
const configModule = await import(fileUrl.href);
return configModule.default;
} catch (error) {
if (configFilePath) {
throw new Error(
`Error loading configuration file from ${normalizedPath}`
);
}
}
}
19 changes: 15 additions & 4 deletions src/lib/markdowndb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { CustomConfig } from "./CustomConfig.js";
import { FileInfo, processFile } from "./process.js";
import chokidar from "chokidar";
import { recursiveWalkDir } from "./recursiveWalkDir.js";
import { loadConfig } from "./loadConfig.js";

const defaultFilePathToUrl = (filePath: string) => {
let url = filePath
Expand Down Expand Up @@ -77,19 +78,22 @@ export class MarkdownDB {
// TODO support glob patterns
ignorePatterns = [],
pathToUrlResolver = defaultFilePathToUrl,
customConfig = {},
customConfig,
watch = false,
configFilePath,
}: {
folderPath: string;
ignorePatterns?: RegExp[];
pathToUrlResolver?: (filePath: string) => string;
customConfig?: CustomConfig;
watch?: boolean;
configFilePath?: string;
}) {
const config = customConfig || (await loadConfig(configFilePath)) || {};
const fileObjects = indexFolder(
folderPath,
pathToUrlResolver,
customConfig,
config,
ignorePatterns
);
await this.saveDataToDisk(fileObjects);
Expand All @@ -100,10 +104,17 @@ export class MarkdownDB {
});

const filePathsToIndex = recursiveWalkDir(folderPath);
const computedFields = customConfig.computedFields || [];
const computedFields = config.computedFields || [];

const handleFileEvent = (event: string, filePath: string) => {
if (!shouldIncludeFile(filePath, ignorePatterns)) {
if (
!shouldIncludeFile({
filePath,
ignorePatterns,
includeGlob: config.include,
excludeGlob: config.exclude,
})
) {
return;
}

Expand Down
Loading