Skip to content
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
3 changes: 3 additions & 0 deletions docs/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,13 @@ fieldtest validate \
export default {
contentGlob: "content/**/*.md",
schemaGlob: "schemas/**/*.ts",
exclude: ["archive/**"],
validateLLMS: true
}
```

`exclude` accepts glob patterns for files or directories that FieldTest should ignore when scanning.

---

## Open Questions
Expand Down
7 changes: 4 additions & 3 deletions packages/integrations/mcp/fkit-mcp-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
"watch": "tsc --watch",
"inspector": "npx @modelcontextprotocol/inspector build/index.js"
},
"dependencies": {
"@modelcontextprotocol/sdk": "1.11.4"
},
"dependencies": {
"@modelcontextprotocol/sdk": "1.11.4",
"@fieldtest/shared": "file:../../../shared"
},
"devDependencies": {
"@types/node": "^20.11.24",
"typescript": "^5.3.3"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import path from "path";
import {
FieldTestDocument,
parseMarkdown,
serializeMarkdown,
FieldTestDocument,
parseMarkdown,
serializeMarkdown,
} from "@fieldtest/core"; // Assuming FieldTestDocument is a relevant type
import fs from "fs/promises";
import { shouldExcludeFile } from "@fieldtest/shared";

// This structure reflects the user's info: schema['~standard'].validate
// The DEFAULT_FIELDTEST_SCHEMA provides a default validator if no specific schema is loaded.
Expand Down Expand Up @@ -57,24 +58,27 @@ const DEFAULT_FIELDTEST_SCHEMA = {
},
};

export async function scanFiles(directory: string): Promise<string[]> {
const allFiles: string[] = [];
try {
const entries = await fs.readdir(directory, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(directory, entry.name);
if (entry.isDirectory()) {
if (entry.name.toLowerCase() === "archive") continue; // Skip archive directory
allFiles.push(...(await scanFiles(fullPath)));
} else if (entry.isFile() && entry.name.endsWith(".md")) {
allFiles.push(fullPath);
}
}
} catch (error) {
// Log error or handle appropriately if directory is not accessible
console.warn(`Could not scan directory ${directory}:`, error);
}
return allFiles;
export async function scanFiles(
directory: string,
excludePatterns: string[] = [],
): Promise<string[]> {
const allFiles: string[] = [];
try {
const entries = await fs.readdir(directory, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(directory, entry.name);
if (shouldExcludeFile(fullPath, excludePatterns)) continue;
if (entry.isDirectory()) {
allFiles.push(...(await scanFiles(fullPath, excludePatterns)));
} else if (entry.isFile() && entry.name.endsWith(".md")) {
allFiles.push(fullPath);
}
}
} catch (error) {
// Log error or handle appropriately if directory is not accessible
console.warn(`Could not scan directory ${directory}:`, error);
}
return allFiles;
}

export async function readFrontmatter(filePath: string): Promise<any> {
Expand Down
12 changes: 8 additions & 4 deletions packages/registry/loadUserSchema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ export interface FieldTestConfig {
* Default schema to use when not specified
*/
defaultSchema?: string;
/**
* Custom configuration options
*/
options?: Record<string, unknown>;
/**
* Custom configuration options
*/
options?: Record<string, unknown>;
/**
* Glob patterns for files or directories to exclude
*/
exclude?: string[];
}
/**
* Load user-defined schemas from configuration file
Expand Down
28 changes: 16 additions & 12 deletions packages/registry/loadUserSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,22 @@ const DEFAULT_CONFIG_FILE = "fieldtest.config.ts";
* Interface for fieldtest user configuration
*/
export interface FieldTestConfig {
/**
* Custom schema definitions or paths to schema files
*/
schemas?: Record<string, string | StandardSchemaV1>;
/**
* Default schema to use when not specified
*/
defaultSchema?: string;
/**
* Custom configuration options
*/
options?: Record<string, unknown>;
/**
* Custom schema definitions or paths to schema files
*/
schemas?: Record<string, string | StandardSchemaV1>;
/**
* Default schema to use when not specified
*/
defaultSchema?: string;
/**
* Custom configuration options
*/
options?: Record<string, unknown>;
/**
* Glob patterns for files or directories to exclude
*/
exclude?: string[];
}

/**
Expand Down
7 changes: 4 additions & 3 deletions packages/shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
"test": "vitest run",
"clean": "rimraf dist"
},
"dependencies": {
"zod": "^3.22.4"
},
"dependencies": {
"minimatch": "^9.0.5",
"zod": "^3.22.4"
},
"devDependencies": {
"@types/node": "^20.10.0",
"eslint": "^8.56.0",
Expand Down
10 changes: 10 additions & 0 deletions packages/shared/src/fileFilter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { minimatch } from "minimatch";

/**
* Determine if a file path should be excluded based on glob patterns
*/
export function shouldExcludeFile(filePath: string, patterns: string[] = []): boolean {
return patterns.some((pattern) => minimatch(filePath, pattern, { nocase: true }));
}

export default shouldExcludeFile;
1 change: 1 addition & 0 deletions packages/shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
export * from "./types";
export * from "./utils";
export * from "./constants";
export * from "./fileFilter";
Loading
Loading