diff --git a/package-lock.json b/package-lock.json index 46b2853..285faf0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,8 @@ "remark-gfm": "^3.0.1", "remark-parse": "^10.0.1", "sqlite3": "^5.1.6", - "unist-util-select": "^4.0.3" + "unist-util-select": "^4.0.3", + "zod": "^3.22.4" }, "bin": { "mddb": "dist/src/bin/index.js" @@ -11325,6 +11326,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index 61400be..8082c49 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,8 @@ "remark-gfm": "^3.0.1", "remark-parse": "^10.0.1", "sqlite3": "^5.1.6", - "unist-util-select": "^4.0.3" + "unist-util-select": "^4.0.3", + "zod": "^3.22.4" }, "devDependencies": { "@changesets/changelog-github": "^0.4.8", diff --git a/src/lib/CustomConfig.ts b/src/lib/CustomConfig.ts index a92ae92..32ca29d 100644 --- a/src/lib/CustomConfig.ts +++ b/src/lib/CustomConfig.ts @@ -1,6 +1,11 @@ import { FileInfo } from "./process.js"; import { Root } from "remark-parse/lib/index.js"; +import { ZodObject } from "zod"; + +type ComputedFields = ((fileInfo: FileInfo, ast: Root) => any)[]; +type Schemas = { [index: string]: ZodObject }; export interface CustomConfig { - computedFields?: ((fileInfo: FileInfo, ast: Root) => any)[]; + computedFields?: ComputedFields; + schemas?: Schemas; } diff --git a/src/lib/indexFolder.ts b/src/lib/indexFolder.ts index cccc331..52a839d 100644 --- a/src/lib/indexFolder.ts +++ b/src/lib/indexFolder.ts @@ -1,3 +1,4 @@ +import { ZodError } from "zod"; import { CustomConfig } from "./CustomConfig.js"; import { FileInfo, processFile } from "./process.js"; import { recursiveWalkDir } from "./recursiveWalkDir.js"; @@ -14,6 +15,7 @@ export function indexFolder( ); const files: FileInfo[] = []; const computedFields = config.computedFields || []; + const schemas = config.schemas; for (const filePath of filteredFilePathsToIndex) { const fileObject = processFile( folderPath, @@ -22,6 +24,33 @@ export function indexFolder( filePathsToIndex, computedFields ); + const urlPath = fileObject?.url_path ?? ""; + // This is temporary. + // Note: Subject to change pending agreement on the final structure of document types. + const flattenedFileObject = { + ...fileObject, + ...fileObject.metadata, + tags: fileObject.tags, // Don't override the tags + }; + const documentType = urlPath.split("/")[0]; + + if (schemas && schemas[documentType]) { + const result = schemas[documentType].safeParse(flattenedFileObject); + + if (!result.success) { + const error: ZodError = (result as any).error; + + error.errors.forEach((err) => { + const errorMessage = `Error: In ${ + fileObject.file_path + } for the ${documentType} schema. \n In "${err.path.join( + "," + )}" field: ${err.message}`; + console.error(errorMessage); + }); + } + } + files.push(fileObject); } return files;