diff --git a/dist/index.d.ts b/dist/index.d.ts index 8a76cbf..e459fc4 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -69,9 +69,9 @@ interface Archetype { optional: Record; }; /** - * Name of parent archetype to inherit from. + * Name(s) of archetype(s) this archetype extends. */ - extends?: string; + extends?: string[]; } declare class ArchetypeLoadError extends Error { @@ -132,6 +132,13 @@ interface ValidationResult { errors: ValidationError[]; } +interface LoadOptions { + /** + * Override the cache setting for this load. If not provided, the default + * cache setting will be used. + */ + cache?: false; +} interface ArchetypeValidator { /** * The base archetype schema that all other archetypes must conform to @@ -140,15 +147,15 @@ interface ArchetypeValidator { /** * Load an archetype by name from the configured store */ - readonly loadArchetype: (name: string) => Promise; + readonly loadArchetype: (name: string, options?: LoadOptions) => Promise; /** * Validate an archetype definition against the base archetype schema */ readonly validateArchetype: (archetype: unknown) => Promise; /** - * Validate frontmatter against a named archetype + * Validate frontmatter */ - readonly validateFrontmatter: (frontmatter: unknown, defaultArchetypeName?: string) => Promise; + readonly validateFrontmatter: (frontmatter: unknown) => Promise; } interface ValidatorOptions { @@ -174,7 +181,7 @@ interface ValidatorOptions { * * @param options - Configuration options for the validator. * @param options.store - The data store used to load archetype schemas. - * @param options.cache - Determines whether to cache loaded archetypes. Defaults to `true`. + * @param options.cache - Determines whether to cache loaded archetypes. Defaults to `true` in test and production environments. * @param options.validation - Additional validation options to apply. Defaults to an empty object. * @returns A promise that resolves to an initialized ArchetypeValidator. * diff --git a/dist/index.js b/dist/index.js index b1e072b..6ec8731 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,6 +1,7 @@ import { readFile } from 'node:fs/promises'; import { join } from 'node:path'; import { parse } from 'yaml'; +import { DEV } from 'esm-env'; // Generated with esbuild @@ -327,7 +328,7 @@ var validateSchemaField = (value, field, path = []) => { var validate_schema_field_default = validateSchemaField; // src/lib/validation/validate-archetype.ts -var validateArchetype = (archetype, archetypeSchema, { strictMode = true, allowUnknownFields = false } = {}) => { +var validateArchetype = (archetype, archetypeSchema) => { const errors = []; for (const [fieldName, fieldSchema] of Object.entries(archetypeSchema.schema.required)) { const value = archetype && typeof archetype === "object" ? archetype[fieldName] : void 0; @@ -360,11 +361,43 @@ var validationError = (message, path = []) => ({ }); var validation_error_default = validationError; +// src/lib/validation/validate-frontmatter.ts +var validateFrontmatter = async (frontmatter, { loadArchetype }) => { + if (frontmatter === null || typeof frontmatter !== "object") { + return { + valid: false, + errors: [validation_error_default("Frontmatter must be an object")] + }; + } + const archetypeName = "type" in frontmatter && typeof frontmatter.type === "string" ? frontmatter.type : void 0; + if (archetypeName === void 0) { + return { + valid: false, + errors: [validation_error_default("Frontmatter must have a `type` field", ["type"])] + }; + } + const archetype = await loadArchetype(archetypeName); + return validate_archetype_default(frontmatter, archetype); +}; +var validate_frontmatter_default = validateFrontmatter; + +// src/lib/validator/extend-archetype.ts +var extendArchetype = (archetype, extensions) => extensions.reduce( + (prev, { schema: { required, optional } }) => ({ + ...prev, + schema: { + required: { ...prev.schema.required, ...required }, + optional: { ...prev.schema.optional, ...optional } + } + }), + archetype +); +var extend_archetype_default = extendArchetype; + // src/lib/validator/create-validator.ts var createValidator = async ({ - store, - cache = true, - validation = {} + cache = !DEV, + store }) => { const archetypeCache = cache ? /* @__PURE__ */ new Map() : void 0; const archetypeSchema = await store.load("archetype"); @@ -374,34 +407,32 @@ var createValidator = async ({ } const validator = { archetypeSchema, - loadArchetype: async (name) => { - if (archetypeCache?.has(name)) { + loadArchetype: async (name, { cache: cache2 } = {}) => { + if (cache2 !== false && archetypeCache?.has(name)) { return archetypeCache.get(name); } const archetype = await store.load(name); - archetypeCache?.set(name, archetype); - return archetype; - }, - validateArchetype: async (archetype) => { - return validate_archetype_default(archetype, archetypeSchema); - }, - validateFrontmatter: async (frontmatter, defaultArchetypeName) => { - if (frontmatter === null || typeof frontmatter !== "object") { - return { - valid: false, - errors: [validation_error_default("Frontmatter must be an object")] - }; - } - const archetypeName = "type" in frontmatter && typeof frontmatter.type === "string" ? frontmatter.type : defaultArchetypeName; - if (archetypeName === void 0) { - return { - valid: false, - errors: [validation_error_default("Frontmatter must have a `type` field", ["type"])] - }; + if (cache2 !== false) { + archetypeCache?.set(name, archetype); } - const archetype = await validator.loadArchetype(archetypeName); - return validate_archetype_default(frontmatter, archetype, validation); - } + const loadedArchetypes = /* @__PURE__ */ new Map(); + const loadArchetypeRecursive = async (names = []) => { + for (const name2 of names) { + if (loadedArchetypes.has(name2)) { + continue; + } + const archetype2 = await store.load(name2); + loadedArchetypes.set(name2, archetype2); + if (archetype2.extends) { + await loadArchetypeRecursive(archetype2.extends); + } + } + }; + await loadArchetypeRecursive(archetype.extends); + return extend_archetype_default(archetype, Array.from(loadedArchetypes.values())); + }, + validateArchetype: async (archetype) => validate_archetype_default(archetype, archetypeSchema), + validateFrontmatter: async (frontmatter) => validate_frontmatter_default(frontmatter, validator) }; return validator; }; diff --git a/dist/index.js.map b/dist/index.js.map index 96c6857..746d8e2 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/types/archetype-store.ts","../src/lib/store/archetype-from-yaml.ts","../src/lib/store/yaml-from-markdown.ts","../src/lib/store/create-local-store.ts","../src/lib/store/create-remote-store.ts","../src/lib/validation/validate-array-field.ts","../src/lib/validation/validate-boolean-field.ts","../src/lib/validation/date-format/iso8601.ts","../src/lib/validation/validate-date-field.ts","../src/lib/validation/validate-number-field.ts","../src/lib/validation/validate-object-field.ts","../src/lib/validation/validate-string-field.ts","../src/lib/validation/validators.ts","../src/lib/validation/validate-schema-field.ts","../src/lib/validation/validate-archetype.ts","../src/lib/validation/validation-error.ts","../src/lib/validator/create-validator.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { Archetype } from './archetype.js';\n\nclass ArchetypeLoadError extends Error {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(message);\n\t\tthis.name = 'ArchetypeLoadError';\n\t\tthis.cause = cause;\n\t}\n}\n\ninterface ArchetypeStore {\n\t/**\n\t * Load an archetype schema by name.\n\t *\n\t * @param name - The name of the archetype to load.\n\t * @returns A promise that resolves to the loaded archetype schema.\n\t *\n\t * @throws {ArchetypeLoadError} If the archetype schema could not be loaded\n\t *\n\t * @example\n\t * const archetype = await store.load('post');\n\t */\n\tload(name: string): Promise;\n}\n\nexport { ArchetypeLoadError, type ArchetypeStore };\n","import type { Archetype } from '$types/archetype.js';\nimport { parse } from 'yaml';\n\nconst archetypeFromYaml = (yaml: string): Archetype => parse(yaml);\n\nexport default archetypeFromYaml;\n","const yamlFromMarkdown = (markdown: string): string => {\n\tconst [, yaml] = markdown.split('---\\n');\n\n\tif (yaml) {\n\t\treturn yaml;\n\t}\n\n\tthrow new Error('YAML content is missing in the file');\n};\n\nexport default yamlFromMarkdown;\n","import { ArchetypeLoadError, type ArchetypeStore } from '$types/archetype-store.js';\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport archetypeFromYaml from './archetype-from-yaml.js';\nimport yamlFromMarkdown from './yaml-from-markdown.js';\n\n/**\n * Error thrown when a local archetype fails to load.\n */\nclass LocalArchetypeLoadError extends ArchetypeLoadError {\n\tconstructor(name: string, originalError: Error) {\n\t\tsuper(`Failed to load local archetype \"${name}\": ${originalError.message}`);\n\t\tthis.name = 'LocalArchetypeLoadError';\n\t\tthis.stack = originalError.stack;\n\t}\n}\n\n/**\n * Loads an archetype schema from a markdown file.\n *\n * @param name - The name of the archetype to load.\n * @param path - The path to the directory containing the archetype.\n * @returns A promise that resolves to the archetype schema.\n * @throws {LocalArchetypeLoadError} If the archetype schema could not be loaded\n */\nconst loadMarkdown: (name: string, path: string) => Promise = (name, path) =>\n\treadFile(join(path, `${name}.md`), 'utf-8').catch((error) => {\n\t\tthrow new LocalArchetypeLoadError(\n\t\t\tname,\n\t\t\terror instanceof Error ? error : new Error(String(error))\n\t\t);\n\t});\n\n/**\n * Creates a store that loads archetype schemas from local markdown files.\n *\n * @param root - The root directory containing the archetype schemas.\n * @returns A store that loads archetype schemas from local markdown files.\n * @throws {LocalArchetypeLoadError} If the archetype schema could not be loaded\n */\nconst createLocalStore: (root: string) => ArchetypeStore = (root) => ({\n\tload: (name) => loadMarkdown(name, root).then(yamlFromMarkdown).then(archetypeFromYaml)\n});\n\nexport { createLocalStore as default, LocalArchetypeLoadError };\n","import { ArchetypeLoadError, type ArchetypeStore } from '$types/archetype-store.js';\nimport archetypeFromYaml from './archetype-from-yaml.js';\nimport yamlFromMarkdown from './yaml-from-markdown.js';\n\n/**\n * Error thrown when a remote archetype fails to load.\n */\nclass RemoteArchetypeLoadError extends ArchetypeLoadError {\n\tconstructor(name: string, statusText: string) {\n\t\tsuper(`Failed to load remote archetype \"${name}\": ${statusText}`);\n\t\tthis.name = 'RemoteArchetypeLoadError';\n\t}\n}\n\n/**\n * Fetches an archetype schema from a remote markdown file.\n *\n * @param name - The name of the archetype to load.\n * @param baseUrl - The base URL to load the archetype from.\n * @returns A promise that resolves to the archetype schema.\n * @throws {RemoteArchetypeLoadError} If the archetype schema could not be loaded\n */\nconst fetchMarkdown: (name: string, baseUrl: string | URL) => Promise = async (\n\tname,\n\tbaseUrl\n) => {\n\ttry {\n\t\tconst url = new URL(`${name}.md`, baseUrl);\n\t\tconst res = await fetch(url);\n\n\t\tif (res.ok) {\n\t\t\treturn res.text();\n\t\t} else {\n\t\t\tthrow new RemoteArchetypeLoadError(name, res.statusText);\n\t\t}\n\t} catch (error) {\n\t\tthrow error instanceof RemoteArchetypeLoadError ? error : new ArchetypeLoadError(name, error);\n\t}\n};\n\n/**\n * Creates a store that loads archetype schemas from remote markdown files.\n *\n * @param baseUrl - The base URL to load the archetype from.\n * @returns A store that loads archetype schemas from remote markdown files.\n * @throws {RemoteArchetypeLoadError} If the archetype schema could not be loaded\n */\nconst createRemoteStore: (baseUrl: string | URL) => ArchetypeStore = (baseUrl) => ({\n\tload: (name) => fetchMarkdown(name, baseUrl).then(yamlFromMarkdown).then(archetypeFromYaml)\n});\n\nexport { createRemoteStore as default, RemoteArchetypeLoadError };\n","import type { ArrayField } from '$types/schema-field.js';\nimport type { ValidationError } from 'src/types/validation-error.js';\nimport validateSchemaField from './validate-schema-field.js';\n\nconst validateArrayField = (\n\tvalue: unknown,\n\tfield: ArrayField,\n\tpath: string[] = []\n): ValidationError[] => {\n\tconst errors: ValidationError[] = [];\n\n\tif (!Array.isArray(value)) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\tmessage: `Expected array, got ${typeof value}`\n\t\t\t}\n\t\t];\n\t}\n\n\tif (field.minItems !== undefined && value.length < field.minItems) {\n\t\terrors.push({\n\t\t\tpath,\n\t\t\tmessage: `Array must contain at least ${field.minItems} items`\n\t\t});\n\t}\n\n\tif (field.maxItems !== undefined && value.length > field.maxItems) {\n\t\terrors.push({\n\t\t\tpath,\n\t\t\tmessage: `Array must contain at most ${field.maxItems} items`\n\t\t});\n\t}\n\n\tvalue.forEach((item, index) => {\n\t\terrors.push(...validateSchemaField(item, field.items, [...path, index.toString()]));\n\t});\n\n\treturn errors;\n};\n\nexport default validateArrayField;\n","import type { BooleanField } from '$types/schema-field.js';\nimport type { ValidationError } from 'src/types/validation-error.js';\n\nconst validateBooleanField = (\n\tvalue: unknown,\n\tfield: BooleanField,\n\tpath: string[] = []\n): ValidationError[] => {\n\tconst errors: ValidationError[] = [];\n\n\tif (typeof value !== 'boolean') {\n\t\treturn [\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\tmessage: `Expected boolean, got ${typeof value}`\n\t\t\t}\n\t\t];\n\t}\n\n\tvoid field;\n\n\treturn errors;\n};\n\nexport default validateBooleanField;\n","const ISO8601_FORMATS = {\n\tCALENDAR:\n\t\t/^(\\d{4})-([01]\\d)-([0-3]\\d)(?:T([012]\\d):([0-5]\\d):([0-5]\\d)(?:\\.(\\d+))?(Z|([+-])([01]\\d):([0-5]\\d))?)?$/,\n\tORDINAL: /^(\\d{4})-(\\d{3})$/,\n\tWEEK: /^(\\d{4})-W([0-5]\\d)(?:-([1-7]))?$/\n};\n\nconst parseWeekDate: (year: number, week: number, day?: number) => Date = (year, week, day = 1) => {\n\t// January 4th is always in week 1 per ISO-8601\n\tconst jan4th = new Date(year, 0, 4);\n\tconst startOfWeek1 = new Date(jan4th);\n\n\tstartOfWeek1.setDate(jan4th.getDate() - jan4th.getDay() + 1);\n\n\t// Calculate target date\n\tconst targetDate = new Date(startOfWeek1);\n\n\ttargetDate.setDate(startOfWeek1.getDate() + (week - 1) * 7 + (day - 1));\n\n\t// Validate the resulting year is correct\n\tif (targetDate.getFullYear() !== year) {\n\t\tthrow new Error('Invalid week date');\n\t}\n\n\treturn targetDate;\n};\n\nconst parseOrdinalDate: (year: number, ordinalDay: number) => Date = (year, ordinalDay) => {\n\tconst date = new Date(year, 0, 1);\n\n\tdate.setDate(ordinalDay);\n\n\t// Validate the resulting year is correct\n\tif (date.getFullYear() !== year) {\n\t\tthrow new Error('Invalid ordinal date');\n\t}\n\n\treturn date;\n};\n\nconst parseDate: (dateString: string) => Date = (dateString) => {\n\tconst dateMatch = dateString.match(ISO8601_FORMATS.CALENDAR);\n\n\tif (dateMatch) {\n\t\tconst [, y, m, d, h, min, s, ms, tz, o, hoff, minoff] = dateMatch;\n\n\t\tvoid tz;\n\n\t\tconst year = Number(y);\n\t\tconst month = Number(m);\n\t\tconst day = Number(d);\n\t\tconst hour = h ? Number(h) : 0;\n\t\tconst minute = min ? Number(min) : 0;\n\t\tconst second = s ? Number(s) : 0;\n\t\tconst millisecond = ms ? Number(ms) : 0;\n\t\tconst hourOffset = hoff ? Number(`${o}${hoff}`) : 0;\n\t\tconst minuteOffset = minoff ? Number(`${o}${minoff}`) : 0;\n\n\t\tconst date = new Date(dateString);\n\n\t\tif (date instanceof Date === false) {\n\t\t\tthrow new Error('Invalid calendar date');\n\t\t} else if (\n\t\t\tdate.getFullYear() !== year ||\n\t\t\tdate.getMonth() + 1 !== month ||\n\t\t\tdate.getDate() !== day ||\n\t\t\tdate.getHours() !== hour - hourOffset ||\n\t\t\tdate.getMinutes() !== minute - minuteOffset ||\n\t\t\tdate.getSeconds() !== second ||\n\t\t\tdate.getMilliseconds() !== millisecond\n\t\t) {\n\t\t\tthrow new Error('Invalid calendar date');\n\t\t} else {\n\t\t\treturn date;\n\t\t}\n\t}\n\n\tconst weekMatch = dateString.match(ISO8601_FORMATS.WEEK);\n\n\tif (weekMatch) {\n\t\tconst [, y, w, d] = weekMatch;\n\n\t\tconst year = Number(y);\n\t\tconst week = Number(w);\n\t\tconst day = d ? Number(d) : 1;\n\n\t\tif (week < 1 || week > 53) {\n\t\t\tthrow new Error('Invalid week number');\n\t\t}\n\n\t\tif (week === 53) {\n\t\t\tconst dec31 = new Date(year, 11, 31);\n\n\t\t\tconst lastWeek =\n\t\t\t\tMath.floor((dec31.getTime() - new Date(year, 0, 1).getTime()) / (86400000 * 7)) + 1;\n\n\t\t\tif (lastWeek !== 53) {\n\t\t\t\tthrow new Error('Invalid week number');\n\t\t\t}\n\t\t}\n\n\t\treturn parseWeekDate(year, week, day);\n\t}\n\n\tconst ordinalMatch = dateString.match(ISO8601_FORMATS.ORDINAL);\n\n\tif (ordinalMatch) {\n\t\tconst [, y, od] = ordinalMatch;\n\n\t\tconst year = Number(y);\n\t\tconst ordinalDay = Number(od);\n\n\t\t// Validate ordinal day number\n\t\tconst isLeapYear = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n\t\tconst maxDays = isLeapYear ? 366 : 365;\n\n\t\tif (ordinalDay < 1 || ordinalDay > maxDays) {\n\t\t\tthrow new Error('Invalid ordinal day number');\n\t\t}\n\n\t\treturn parseOrdinalDate(year, ordinalDay);\n\t}\n\n\tthrow new Error('Invalid ISO-8601 date format');\n};\n\nconst isValidDate: (dateString: string) => boolean = (date) => {\n\ttry {\n\t\treturn parseDate(date) instanceof Date;\n\t} catch {\n\t\treturn false;\n\t}\n};\n\nexport { isValidDate, parseDate };\n","import type { DateField } from '$types/schema-field.js';\nimport type { ValidationError } from 'src/types/validation-error.js';\nimport { isValidDate } from './date-format/iso8601.js';\n\nconst validateDateField = (\n\tvalue: unknown,\n\tfield: DateField,\n\tpath: string[] = []\n): ValidationError[] => {\n\tconst errors: ValidationError[] = [];\n\n\tif (typeof value !== 'string' || isNaN(Date.parse(value))) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\tmessage: 'Invalid date format'\n\t\t\t}\n\t\t];\n\t}\n\n\tif (field.format === 'ISO-8601' && isValidDate(value) === false) {\n\t\terrors.push({\n\t\t\tpath,\n\t\t\tmessage: 'Date must be in ISO-8601 format'\n\t\t});\n\t}\n\n\treturn errors;\n};\n\nexport default validateDateField;\n","import type { NumberField } from '$types/schema-field.js';\nimport type { ValidationError } from 'src/types/validation-error.js';\n\nconst validateNumberField = (\n\tvalue: unknown,\n\tfield: NumberField,\n\tpath: string[] = []\n): ValidationError[] => {\n\tconst errors: ValidationError[] = [];\n\n\tif (typeof value !== 'number') {\n\t\treturn [\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\tmessage: `Expected number, got ${typeof value}`\n\t\t\t}\n\t\t];\n\t}\n\n\tif (field.min !== undefined && value < field.min) {\n\t\terrors.push({\n\t\t\tpath,\n\t\t\tmessage: `Value must be >= ${field.min}`\n\t\t});\n\t}\n\n\tif (field.max !== undefined && value > field.max) {\n\t\terrors.push({\n\t\t\tpath,\n\t\t\tmessage: `Value must be <= ${field.max}`\n\t\t});\n\t}\n\n\treturn errors;\n};\n\nexport default validateNumberField;\n","import type { ObjectField } from '$types/schema-field.js';\nimport type { ValidationError } from 'src/types/validation-error.js';\nimport validateSchemaField from './validate-schema-field.js';\n\nconst validateObjectField = (\n\tvalue: unknown,\n\tfield: ObjectField,\n\tpath: string[] = []\n): ValidationError[] => {\n\tconst errors: ValidationError[] = [];\n\n\tif (typeof value !== 'object' || value === null) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\tmessage: `Expected object, got ${typeof value}`\n\t\t\t}\n\t\t];\n\t}\n\n\tconst valueObj = value as Record;\n\n\tfield.required?.forEach((requiredProp) => {\n\t\tif (!(requiredProp in valueObj)) {\n\t\t\terrors.push({\n\t\t\t\tpath: [...path, requiredProp],\n\t\t\t\tmessage: 'Required property missing'\n\t\t\t});\n\t\t}\n\t});\n\n\tif (field.properties) {\n\t\tObject.entries(field.properties).forEach(([key, propSchema]) => {\n\t\t\tif (key in valueObj) {\n\t\t\t\terrors.push(...validateSchemaField(valueObj[key], propSchema, [...path, key]));\n\t\t\t}\n\t\t});\n\t}\n\n\treturn errors;\n};\n\nexport default validateObjectField;\n","import type { StringField } from '$types/schema-field.js';\nimport type { ValidationError } from 'src/types/validation-error.js';\n\nconst validateStringField = (\n\tvalue: unknown,\n\tfield: StringField,\n\tpath: string[] = []\n): ValidationError[] => {\n\tconst errors: ValidationError[] = [];\n\n\tif (typeof value !== 'string') {\n\t\treturn [\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\tmessage: `Expected string, got ${typeof value}`\n\t\t\t}\n\t\t];\n\t}\n\n\tif (field.enum && !field.enum.includes(value as string)) {\n\t\terrors.push({\n\t\t\tpath,\n\t\t\tmessage: `Value must be one of: ${field.enum.join(', ')}`\n\t\t});\n\t}\n\n\tif (field.pattern && !new RegExp(field.pattern).test(value as string)) {\n\t\terrors.push({\n\t\t\tpath,\n\t\t\tmessage: `Value does not match pattern: ${field.pattern}`\n\t\t});\n\t}\n\n\treturn errors;\n};\n\nexport default validateStringField;\n","import type { SchemaFieldMap } from '$types/schema-field.js';\nimport type { ValidationError } from '$types/validation-error.js';\nimport validateArrayField from './validate-array-field.js';\nimport validateBooleanField from './validate-boolean-field.js';\nimport validateDateField from './validate-date-field.js';\nimport validateNumberField from './validate-number-field.js';\nimport validateObjectField from './validate-object-field.js';\nimport validateStringField from './validate-string-field.js';\n\ntype Validators = {\n\t[K in keyof SchemaFieldMap]: (\n\t\tvalue: unknown,\n\t\tfield: SchemaFieldMap[K],\n\t\tpath: string[]\n\t) => ValidationError[];\n};\n\nconst validators: Validators = {\n\tArray: validateArrayField,\n\tBoolean: validateBooleanField,\n\tDate: validateDateField,\n\tNumber: validateNumberField,\n\tObject: validateObjectField,\n\tString: validateStringField\n};\n\nexport default validators;\n","import type { SchemaField } from '$types/schema-field.js';\nimport type { ValidationError } from '$types/validation-error.js';\nimport validators from './validators.js';\n\nconst validateSchemaField: (\n\tvalue: unknown,\n\tfield: SchemaField,\n\tpath?: string[]\n) => ValidationError[] = (value, field, path = []) => {\n\tconst validator = validators[field.type];\n\n\tif (validator) {\n\t\treturn validator(value, field as never, path);\n\t}\n\n\tthrow new Error(`No validator found for type: ${field.type}`);\n};\n\nexport default validateSchemaField;\n","import type { Archetype } from '$types/archetype.js';\nimport type { SchemaField } from '$types/schema-field.js';\nimport type { ValidationResult } from '$types/validation-result.js';\nimport type { ValidatorOptions } from '$types/validator-options.js';\nimport type { ValidationError } from 'src/types/validation-error.js';\nimport validateSchemaField from './validate-schema-field.js';\n\nconst validateArchetype: (\n\tarchetype: unknown,\n\tarchetypeSchema: Archetype,\n\toptions?: ValidatorOptions['validation']\n) => ValidationResult = (\n\tarchetype,\n\tarchetypeSchema,\n\t{ strictMode = true, allowUnknownFields = false } = {}\n) => {\n\tconst errors: ValidationError[] = [];\n\n\tvoid strictMode;\n\tvoid allowUnknownFields;\n\n\tfor (const [fieldName, fieldSchema] of Object.entries(archetypeSchema.schema.required) as [\n\t\tstring,\n\t\tSchemaField\n\t][]) {\n\t\tconst value =\n\t\t\tarchetype && typeof archetype === 'object'\n\t\t\t\t? (archetype as Record)[fieldName]\n\t\t\t\t: undefined;\n\n\t\tif (value === undefined) {\n\t\t\terrors.push({\n\t\t\t\tpath: [fieldName],\n\t\t\t\tmessage: 'Required field missing'\n\t\t\t});\n\t\t} else {\n\t\t\terrors.push(...validateSchemaField(value, fieldSchema, [fieldName]));\n\t\t}\n\t}\n\n\t// Then validate optional fields if present\n\tfor (const [fieldName, fieldSchema] of Object.entries(archetypeSchema.schema.optional) as [\n\t\tstring,\n\t\tSchemaField\n\t][]) {\n\t\tconst value =\n\t\t\tarchetype && typeof archetype === 'object'\n\t\t\t\t? (archetype as Record)[fieldName]\n\t\t\t\t: undefined;\n\n\t\tif (value !== undefined) {\n\t\t\terrors.push(...validateSchemaField(value, fieldSchema, [fieldName]));\n\t\t}\n\t}\n\n\treturn {\n\t\tvalid: errors.length === 0,\n\t\terrors\n\t};\n};\n\nexport default validateArchetype;\n","import type { ValidationError } from '$types/validation-error.js';\n\nconst validationError: (message: string, path?: string[]) => ValidationError = (\n\tmessage,\n\tpath = []\n) => ({\n\tmessage,\n\tpath\n});\n\nexport default validationError;\n","import validateArchetype from '$lib/validation/validate-archetype.js';\nimport validationError from '$lib/validation/validation-error.js';\nimport type { ArchetypeValidator } from '$types/archetype-validator.js';\nimport type { Archetype } from '$types/archetype.js';\nimport type { ValidatorOptions } from '$types/validator-options.js';\n\n/**\n * Creates and initializes an ArchetypeValidator instance.\n *\n * @param options - Configuration options for the validator.\n * @param options.store - The data store used to load archetype schemas.\n * @param options.cache - Determines whether to cache loaded archetypes. Defaults to `true`.\n * @param options.validation - Additional validation options to apply. Defaults to an empty object.\n * @returns A promise that resolves to an initialized ArchetypeValidator.\n *\n * @throws {Error} If the initial archetype schema is invalid.\n *\n * @example\n * const validator = await createValidator({\n * store: createLocalStore(path.join(process.cwd(), 'data', 'archetypes')),\n * });\n */\nconst createValidator: (options: ValidatorOptions) => Promise = async ({\n\tstore,\n\tcache = true,\n\tvalidation = {}\n}) => {\n\tconst archetypeCache = cache ? new Map() : undefined;\n\n\tconst archetypeSchema = await store.load('archetype');\n\n\tconst { errors, valid } = validateArchetype(archetypeSchema, archetypeSchema);\n\n\tif (!valid) {\n\t\tthrow new Error('Invalid archetype schema', { cause: errors });\n\t}\n\n\tconst validator: ArchetypeValidator = {\n\t\tarchetypeSchema,\n\n\t\tloadArchetype: async (name) => {\n\t\t\tif (archetypeCache?.has(name)) {\n\t\t\t\treturn archetypeCache.get(name)!;\n\t\t\t}\n\n\t\t\tconst archetype = await store.load(name);\n\n\t\t\tarchetypeCache?.set(name, archetype);\n\n\t\t\treturn archetype;\n\t\t},\n\n\t\tvalidateArchetype: async (archetype) => {\n\t\t\treturn validateArchetype(archetype, archetypeSchema);\n\t\t},\n\n\t\tvalidateFrontmatter: async (frontmatter, defaultArchetypeName) => {\n\t\t\tif (frontmatter === null || typeof frontmatter !== 'object') {\n\t\t\t\treturn {\n\t\t\t\t\tvalid: false,\n\t\t\t\t\terrors: [validationError('Frontmatter must be an object')]\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst archetypeName =\n\t\t\t\t'type' in frontmatter && typeof frontmatter.type === 'string'\n\t\t\t\t\t? frontmatter.type\n\t\t\t\t\t: defaultArchetypeName;\n\n\t\t\tif (archetypeName === undefined) {\n\t\t\t\treturn {\n\t\t\t\t\tvalid: false,\n\t\t\t\t\terrors: [validationError('Frontmatter must have a `type` field', ['type'])]\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst archetype = await validator.loadArchetype(archetypeName);\n\n\t\t\treturn validateArchetype(frontmatter, archetype, validation);\n\t\t}\n\t};\n\n\treturn validator;\n};\n\nexport default createValidator;\n"]} \ No newline at end of file +{"version":3,"sources":["../src/types/archetype-store.ts","../src/lib/store/archetype-from-yaml.ts","../src/lib/store/yaml-from-markdown.ts","../src/lib/store/create-local-store.ts","../src/lib/store/create-remote-store.ts","../src/lib/validation/validate-array-field.ts","../src/lib/validation/validate-boolean-field.ts","../src/lib/validation/date-format/iso8601.ts","../src/lib/validation/validate-date-field.ts","../src/lib/validation/validate-number-field.ts","../src/lib/validation/validate-object-field.ts","../src/lib/validation/validate-string-field.ts","../src/lib/validation/validators.ts","../src/lib/validation/validate-schema-field.ts","../src/lib/validation/validate-archetype.ts","../src/lib/validation/validation-error.ts","../src/lib/validation/validate-frontmatter.ts","../src/lib/validator/extend-archetype.ts","../src/lib/validator/create-validator.ts"],"names":["cache","name","archetype"],"mappings":"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","file":"index.js","sourcesContent":["import type { Archetype } from './archetype.js';\n\nclass ArchetypeLoadError extends Error {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(message);\n\t\tthis.name = 'ArchetypeLoadError';\n\t\tthis.cause = cause;\n\t}\n}\n\ninterface ArchetypeStore {\n\t/**\n\t * Load an archetype schema by name.\n\t *\n\t * @param name - The name of the archetype to load.\n\t * @returns A promise that resolves to the loaded archetype schema.\n\t *\n\t * @throws {ArchetypeLoadError} If the archetype schema could not be loaded\n\t *\n\t * @example\n\t * const archetype = await store.load('post');\n\t */\n\tload(name: string): Promise;\n}\n\nexport { ArchetypeLoadError, type ArchetypeStore };\n","import type { Archetype } from '$types/archetype.js';\nimport { parse } from 'yaml';\n\nconst archetypeFromYaml = (yaml: string): Archetype => parse(yaml);\n\nexport default archetypeFromYaml;\n","const yamlFromMarkdown = (markdown: string): string => {\n\tconst [, yaml] = markdown.split('---\\n');\n\n\tif (yaml) {\n\t\treturn yaml;\n\t}\n\n\tthrow new Error('YAML content is missing in the file');\n};\n\nexport default yamlFromMarkdown;\n","import { ArchetypeLoadError, type ArchetypeStore } from '$types/archetype-store.js';\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport archetypeFromYaml from './archetype-from-yaml.js';\nimport yamlFromMarkdown from './yaml-from-markdown.js';\n\n/**\n * Error thrown when a local archetype fails to load.\n */\nclass LocalArchetypeLoadError extends ArchetypeLoadError {\n\tconstructor(name: string, originalError: Error) {\n\t\tsuper(`Failed to load local archetype \"${name}\": ${originalError.message}`);\n\t\tthis.name = 'LocalArchetypeLoadError';\n\t\tthis.stack = originalError.stack;\n\t}\n}\n\n/**\n * Loads an archetype schema from a markdown file.\n *\n * @param name - The name of the archetype to load.\n * @param path - The path to the directory containing the archetype.\n * @returns A promise that resolves to the archetype schema.\n * @throws {LocalArchetypeLoadError} If the archetype schema could not be loaded\n */\nconst loadMarkdown: (name: string, path: string) => Promise = (name, path) =>\n\treadFile(join(path, `${name}.md`), 'utf-8').catch((error) => {\n\t\tthrow new LocalArchetypeLoadError(\n\t\t\tname,\n\t\t\terror instanceof Error ? error : new Error(String(error))\n\t\t);\n\t});\n\n/**\n * Creates a store that loads archetype schemas from local markdown files.\n *\n * @param root - The root directory containing the archetype schemas.\n * @returns A store that loads archetype schemas from local markdown files.\n * @throws {LocalArchetypeLoadError} If the archetype schema could not be loaded\n */\nconst createLocalStore: (root: string) => ArchetypeStore = (root) => ({\n\tload: (name) => loadMarkdown(name, root).then(yamlFromMarkdown).then(archetypeFromYaml)\n});\n\nexport { createLocalStore as default, LocalArchetypeLoadError };\n","import { ArchetypeLoadError, type ArchetypeStore } from '$types/archetype-store.js';\nimport archetypeFromYaml from './archetype-from-yaml.js';\nimport yamlFromMarkdown from './yaml-from-markdown.js';\n\n/**\n * Error thrown when a remote archetype fails to load.\n */\nclass RemoteArchetypeLoadError extends ArchetypeLoadError {\n\tconstructor(name: string, statusText: string) {\n\t\tsuper(`Failed to load remote archetype \"${name}\": ${statusText}`);\n\t\tthis.name = 'RemoteArchetypeLoadError';\n\t}\n}\n\n/**\n * Fetches an archetype schema from a remote markdown file.\n *\n * @param name - The name of the archetype to load.\n * @param baseUrl - The base URL to load the archetype from.\n * @returns A promise that resolves to the archetype schema.\n * @throws {RemoteArchetypeLoadError} If the archetype schema could not be loaded\n */\nconst fetchMarkdown: (name: string, baseUrl: string | URL) => Promise = async (\n\tname,\n\tbaseUrl\n) => {\n\ttry {\n\t\tconst url = new URL(`${name}.md`, baseUrl);\n\t\tconst res = await fetch(url);\n\n\t\tif (res.ok) {\n\t\t\treturn res.text();\n\t\t} else {\n\t\t\tthrow new RemoteArchetypeLoadError(name, res.statusText);\n\t\t}\n\t} catch (error) {\n\t\tthrow error instanceof RemoteArchetypeLoadError ? error : new ArchetypeLoadError(name, error);\n\t}\n};\n\n/**\n * Creates a store that loads archetype schemas from remote markdown files.\n *\n * @param baseUrl - The base URL to load the archetype from.\n * @returns A store that loads archetype schemas from remote markdown files.\n * @throws {RemoteArchetypeLoadError} If the archetype schema could not be loaded\n */\nconst createRemoteStore: (baseUrl: string | URL) => ArchetypeStore = (baseUrl) => ({\n\tload: (name) => fetchMarkdown(name, baseUrl).then(yamlFromMarkdown).then(archetypeFromYaml)\n});\n\nexport { createRemoteStore as default, RemoteArchetypeLoadError };\n","import type { ArrayField } from '$types/schema-field.js';\nimport type { ValidationError } from 'src/types/validation-error.js';\nimport validateSchemaField from './validate-schema-field.js';\n\nconst validateArrayField = (\n\tvalue: unknown,\n\tfield: ArrayField,\n\tpath: string[] = []\n): ValidationError[] => {\n\tconst errors: ValidationError[] = [];\n\n\tif (!Array.isArray(value)) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\tmessage: `Expected array, got ${typeof value}`\n\t\t\t}\n\t\t];\n\t}\n\n\tif (field.minItems !== undefined && value.length < field.minItems) {\n\t\terrors.push({\n\t\t\tpath,\n\t\t\tmessage: `Array must contain at least ${field.minItems} items`\n\t\t});\n\t}\n\n\tif (field.maxItems !== undefined && value.length > field.maxItems) {\n\t\terrors.push({\n\t\t\tpath,\n\t\t\tmessage: `Array must contain at most ${field.maxItems} items`\n\t\t});\n\t}\n\n\tvalue.forEach((item, index) => {\n\t\terrors.push(...validateSchemaField(item, field.items, [...path, index.toString()]));\n\t});\n\n\treturn errors;\n};\n\nexport default validateArrayField;\n","import type { BooleanField } from '$types/schema-field.js';\nimport type { ValidationError } from 'src/types/validation-error.js';\n\nconst validateBooleanField = (\n\tvalue: unknown,\n\tfield: BooleanField,\n\tpath: string[] = []\n): ValidationError[] => {\n\tconst errors: ValidationError[] = [];\n\n\tif (typeof value !== 'boolean') {\n\t\treturn [\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\tmessage: `Expected boolean, got ${typeof value}`\n\t\t\t}\n\t\t];\n\t}\n\n\tvoid field;\n\n\treturn errors;\n};\n\nexport default validateBooleanField;\n","const ISO8601_FORMATS = {\n\tCALENDAR:\n\t\t/^(\\d{4})-([01]\\d)-([0-3]\\d)(?:T([012]\\d):([0-5]\\d):([0-5]\\d)(?:\\.(\\d+))?(Z|([+-])([01]\\d):([0-5]\\d))?)?$/,\n\tORDINAL: /^(\\d{4})-(\\d{3})$/,\n\tWEEK: /^(\\d{4})-W([0-5]\\d)(?:-([1-7]))?$/\n};\n\nconst parseWeekDate: (year: number, week: number, day?: number) => Date = (year, week, day = 1) => {\n\t// January 4th is always in week 1 per ISO-8601\n\tconst jan4th = new Date(year, 0, 4);\n\tconst startOfWeek1 = new Date(jan4th);\n\n\tstartOfWeek1.setDate(jan4th.getDate() - jan4th.getDay() + 1);\n\n\t// Calculate target date\n\tconst targetDate = new Date(startOfWeek1);\n\n\ttargetDate.setDate(startOfWeek1.getDate() + (week - 1) * 7 + (day - 1));\n\n\t// Validate the resulting year is correct\n\tif (targetDate.getFullYear() !== year) {\n\t\tthrow new Error('Invalid week date');\n\t}\n\n\treturn targetDate;\n};\n\nconst parseOrdinalDate: (year: number, ordinalDay: number) => Date = (year, ordinalDay) => {\n\tconst date = new Date(year, 0, 1);\n\n\tdate.setDate(ordinalDay);\n\n\t// Validate the resulting year is correct\n\tif (date.getFullYear() !== year) {\n\t\tthrow new Error('Invalid ordinal date');\n\t}\n\n\treturn date;\n};\n\nconst parseDate: (dateString: string) => Date = (dateString) => {\n\tconst dateMatch = dateString.match(ISO8601_FORMATS.CALENDAR);\n\n\tif (dateMatch) {\n\t\tconst [, y, m, d, h, min, s, ms, tz, o, hoff, minoff] = dateMatch;\n\n\t\tvoid tz;\n\n\t\tconst year = Number(y);\n\t\tconst month = Number(m);\n\t\tconst day = Number(d);\n\t\tconst hour = h ? Number(h) : 0;\n\t\tconst minute = min ? Number(min) : 0;\n\t\tconst second = s ? Number(s) : 0;\n\t\tconst millisecond = ms ? Number(ms) : 0;\n\t\tconst hourOffset = hoff ? Number(`${o}${hoff}`) : 0;\n\t\tconst minuteOffset = minoff ? Number(`${o}${minoff}`) : 0;\n\n\t\tconst date = new Date(dateString);\n\n\t\tif (date instanceof Date === false) {\n\t\t\tthrow new Error('Invalid calendar date');\n\t\t} else if (\n\t\t\tdate.getFullYear() !== year ||\n\t\t\tdate.getMonth() + 1 !== month ||\n\t\t\tdate.getDate() !== day ||\n\t\t\tdate.getHours() !== hour - hourOffset ||\n\t\t\tdate.getMinutes() !== minute - minuteOffset ||\n\t\t\tdate.getSeconds() !== second ||\n\t\t\tdate.getMilliseconds() !== millisecond\n\t\t) {\n\t\t\tthrow new Error('Invalid calendar date');\n\t\t} else {\n\t\t\treturn date;\n\t\t}\n\t}\n\n\tconst weekMatch = dateString.match(ISO8601_FORMATS.WEEK);\n\n\tif (weekMatch) {\n\t\tconst [, y, w, d] = weekMatch;\n\n\t\tconst year = Number(y);\n\t\tconst week = Number(w);\n\t\tconst day = d ? Number(d) : 1;\n\n\t\tif (week < 1 || week > 53) {\n\t\t\tthrow new Error('Invalid week number');\n\t\t}\n\n\t\tif (week === 53) {\n\t\t\tconst dec31 = new Date(year, 11, 31);\n\n\t\t\tconst lastWeek =\n\t\t\t\tMath.floor((dec31.getTime() - new Date(year, 0, 1).getTime()) / (86400000 * 7)) + 1;\n\n\t\t\tif (lastWeek !== 53) {\n\t\t\t\tthrow new Error('Invalid week number');\n\t\t\t}\n\t\t}\n\n\t\treturn parseWeekDate(year, week, day);\n\t}\n\n\tconst ordinalMatch = dateString.match(ISO8601_FORMATS.ORDINAL);\n\n\tif (ordinalMatch) {\n\t\tconst [, y, od] = ordinalMatch;\n\n\t\tconst year = Number(y);\n\t\tconst ordinalDay = Number(od);\n\n\t\t// Validate ordinal day number\n\t\tconst isLeapYear = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n\t\tconst maxDays = isLeapYear ? 366 : 365;\n\n\t\tif (ordinalDay < 1 || ordinalDay > maxDays) {\n\t\t\tthrow new Error('Invalid ordinal day number');\n\t\t}\n\n\t\treturn parseOrdinalDate(year, ordinalDay);\n\t}\n\n\tthrow new Error('Invalid ISO-8601 date format');\n};\n\nconst isValidDate: (dateString: string) => boolean = (date) => {\n\ttry {\n\t\treturn parseDate(date) instanceof Date;\n\t} catch {\n\t\treturn false;\n\t}\n};\n\nexport { isValidDate, parseDate };\n","import type { DateField } from '$types/schema-field.js';\nimport type { ValidationError } from 'src/types/validation-error.js';\nimport { isValidDate } from './date-format/iso8601.js';\n\nconst validateDateField = (\n\tvalue: unknown,\n\tfield: DateField,\n\tpath: string[] = []\n): ValidationError[] => {\n\tconst errors: ValidationError[] = [];\n\n\tif (typeof value !== 'string' || isNaN(Date.parse(value))) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\tmessage: 'Invalid date format'\n\t\t\t}\n\t\t];\n\t}\n\n\tif (field.format === 'ISO-8601' && isValidDate(value) === false) {\n\t\terrors.push({\n\t\t\tpath,\n\t\t\tmessage: 'Date must be in ISO-8601 format'\n\t\t});\n\t}\n\n\treturn errors;\n};\n\nexport default validateDateField;\n","import type { NumberField } from '$types/schema-field.js';\nimport type { ValidationError } from 'src/types/validation-error.js';\n\nconst validateNumberField = (\n\tvalue: unknown,\n\tfield: NumberField,\n\tpath: string[] = []\n): ValidationError[] => {\n\tconst errors: ValidationError[] = [];\n\n\tif (typeof value !== 'number') {\n\t\treturn [\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\tmessage: `Expected number, got ${typeof value}`\n\t\t\t}\n\t\t];\n\t}\n\n\tif (field.min !== undefined && value < field.min) {\n\t\terrors.push({\n\t\t\tpath,\n\t\t\tmessage: `Value must be >= ${field.min}`\n\t\t});\n\t}\n\n\tif (field.max !== undefined && value > field.max) {\n\t\terrors.push({\n\t\t\tpath,\n\t\t\tmessage: `Value must be <= ${field.max}`\n\t\t});\n\t}\n\n\treturn errors;\n};\n\nexport default validateNumberField;\n","import type { ObjectField } from '$types/schema-field.js';\nimport type { ValidationError } from 'src/types/validation-error.js';\nimport validateSchemaField from './validate-schema-field.js';\n\nconst validateObjectField = (\n\tvalue: unknown,\n\tfield: ObjectField,\n\tpath: string[] = []\n): ValidationError[] => {\n\tconst errors: ValidationError[] = [];\n\n\tif (typeof value !== 'object' || value === null) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\tmessage: `Expected object, got ${typeof value}`\n\t\t\t}\n\t\t];\n\t}\n\n\tconst valueObj = value as Record;\n\n\tfield.required?.forEach((requiredProp) => {\n\t\tif (!(requiredProp in valueObj)) {\n\t\t\terrors.push({\n\t\t\t\tpath: [...path, requiredProp],\n\t\t\t\tmessage: 'Required property missing'\n\t\t\t});\n\t\t}\n\t});\n\n\tif (field.properties) {\n\t\tObject.entries(field.properties).forEach(([key, propSchema]) => {\n\t\t\tif (key in valueObj) {\n\t\t\t\terrors.push(...validateSchemaField(valueObj[key], propSchema, [...path, key]));\n\t\t\t}\n\t\t});\n\t}\n\n\treturn errors;\n};\n\nexport default validateObjectField;\n","import type { StringField } from '$types/schema-field.js';\nimport type { ValidationError } from 'src/types/validation-error.js';\n\nconst validateStringField = (\n\tvalue: unknown,\n\tfield: StringField,\n\tpath: string[] = []\n): ValidationError[] => {\n\tconst errors: ValidationError[] = [];\n\n\tif (typeof value !== 'string') {\n\t\treturn [\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\tmessage: `Expected string, got ${typeof value}`\n\t\t\t}\n\t\t];\n\t}\n\n\tif (field.enum && !field.enum.includes(value as string)) {\n\t\terrors.push({\n\t\t\tpath,\n\t\t\tmessage: `Value must be one of: ${field.enum.join(', ')}`\n\t\t});\n\t}\n\n\tif (field.pattern && !new RegExp(field.pattern).test(value as string)) {\n\t\terrors.push({\n\t\t\tpath,\n\t\t\tmessage: `Value does not match pattern: ${field.pattern}`\n\t\t});\n\t}\n\n\treturn errors;\n};\n\nexport default validateStringField;\n","import type { SchemaFieldMap } from '$types/schema-field.js';\nimport type { ValidationError } from '$types/validation-error.js';\nimport validateArrayField from './validate-array-field.js';\nimport validateBooleanField from './validate-boolean-field.js';\nimport validateDateField from './validate-date-field.js';\nimport validateNumberField from './validate-number-field.js';\nimport validateObjectField from './validate-object-field.js';\nimport validateStringField from './validate-string-field.js';\n\ntype Validators = {\n\t[K in keyof SchemaFieldMap]: (\n\t\tvalue: unknown,\n\t\tfield: SchemaFieldMap[K],\n\t\tpath: string[]\n\t) => ValidationError[];\n};\n\nconst validators: Validators = {\n\tArray: validateArrayField,\n\tBoolean: validateBooleanField,\n\tDate: validateDateField,\n\tNumber: validateNumberField,\n\tObject: validateObjectField,\n\tString: validateStringField\n};\n\nexport default validators;\n","import type { SchemaField } from '$types/schema-field.js';\nimport type { ValidationError } from '$types/validation-error.js';\nimport validators from './validators.js';\n\nconst validateSchemaField: (\n\tvalue: unknown,\n\tfield: SchemaField,\n\tpath?: string[]\n) => ValidationError[] = (value, field, path = []) => {\n\tconst validator = validators[field.type];\n\n\tif (validator) {\n\t\treturn validator(value, field as never, path);\n\t}\n\n\tthrow new Error(`No validator found for type: ${field.type}`);\n};\n\nexport default validateSchemaField;\n","import type { Archetype } from '$types/archetype.js';\nimport type { SchemaField } from '$types/schema-field.js';\nimport type { ValidationResult } from '$types/validation-result.js';\nimport type { ValidationError } from 'src/types/validation-error.js';\nimport validateSchemaField from './validate-schema-field.js';\n\nconst validateArchetype: (archetype: unknown, archetypeSchema: Archetype) => ValidationResult = (\n\tarchetype,\n\tarchetypeSchema\n) => {\n\tconst errors: ValidationError[] = [];\n\n\tfor (const [fieldName, fieldSchema] of Object.entries(archetypeSchema.schema.required) as [\n\t\tstring,\n\t\tSchemaField\n\t][]) {\n\t\tconst value =\n\t\t\tarchetype && typeof archetype === 'object'\n\t\t\t\t? (archetype as Record)[fieldName]\n\t\t\t\t: undefined;\n\n\t\tif (value === undefined) {\n\t\t\terrors.push({\n\t\t\t\tpath: [fieldName],\n\t\t\t\tmessage: 'Required field missing'\n\t\t\t});\n\t\t} else {\n\t\t\terrors.push(...validateSchemaField(value, fieldSchema, [fieldName]));\n\t\t}\n\t}\n\n\t// Then validate optional fields if present\n\tfor (const [fieldName, fieldSchema] of Object.entries(archetypeSchema.schema.optional) as [\n\t\tstring,\n\t\tSchemaField\n\t][]) {\n\t\tconst value =\n\t\t\tarchetype && typeof archetype === 'object'\n\t\t\t\t? (archetype as Record)[fieldName]\n\t\t\t\t: undefined;\n\n\t\tif (value !== undefined) {\n\t\t\terrors.push(...validateSchemaField(value, fieldSchema, [fieldName]));\n\t\t}\n\t}\n\n\treturn {\n\t\tvalid: errors.length === 0,\n\t\terrors\n\t};\n};\n\nexport default validateArchetype;\n","import type { ValidationError } from '$types/validation-error.js';\n\nconst validationError: (message: string, path?: string[]) => ValidationError = (\n\tmessage,\n\tpath = []\n) => ({\n\tmessage,\n\tpath\n});\n\nexport default validationError;\n","import type { ArchetypeValidator } from '$types/archetype-validator.js';\nimport type { ValidationResult } from '$types/validation-result.js';\nimport validateArchetype from './validate-archetype.js';\nimport validationError from './validation-error.js';\n\nconst validateFrontmatter: (\n\tfrontmatter: unknown,\n\tvalidator: ArchetypeValidator\n) => Promise = async (frontmatter, { loadArchetype }) => {\n\tif (frontmatter === null || typeof frontmatter !== 'object') {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\terrors: [validationError('Frontmatter must be an object')]\n\t\t};\n\t}\n\n\tconst archetypeName =\n\t\t'type' in frontmatter && typeof frontmatter.type === 'string' ? frontmatter.type : undefined;\n\n\tif (archetypeName === undefined) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\terrors: [validationError('Frontmatter must have a `type` field', ['type'])]\n\t\t};\n\t}\n\n\tconst archetype = await loadArchetype(archetypeName);\n\n\treturn validateArchetype(frontmatter, archetype);\n};\n\nexport default validateFrontmatter;\n","import type { Archetype } from '$types/archetype.js';\n\nconst extendArchetype: (archetype: Archetype, extensions: Archetype[]) => Archetype = (\n\tarchetype,\n\textensions\n) =>\n\textensions.reduce(\n\t\t(prev, { schema: { required, optional } }) => ({\n\t\t\t...prev,\n\t\t\tschema: {\n\t\t\t\trequired: { ...prev.schema.required, ...required },\n\t\t\t\toptional: { ...prev.schema.optional, ...optional }\n\t\t\t}\n\t\t}),\n\t\tarchetype\n\t);\n\nexport default extendArchetype;\n","import validateArchetype from '$lib/validation/validate-archetype.js';\nimport validateFrontmatter from '$lib/validation/validate-frontmatter.js';\nimport type { ArchetypeValidator } from '$types/archetype-validator.js';\nimport type { Archetype } from '$types/archetype.js';\nimport type { ValidatorOptions } from '$types/validator-options.js';\nimport { DEV } from 'esm-env';\nimport extendArchetype from './extend-archetype.js';\n\n/**\n * Creates and initializes an ArchetypeValidator instance.\n *\n * @param options - Configuration options for the validator.\n * @param options.store - The data store used to load archetype schemas.\n * @param options.cache - Determines whether to cache loaded archetypes. Defaults to `true` in test and production environments.\n * @param options.validation - Additional validation options to apply. Defaults to an empty object.\n * @returns A promise that resolves to an initialized ArchetypeValidator.\n *\n * @throws {Error} If the initial archetype schema is invalid.\n *\n * @example\n * const validator = await createValidator({\n * store: createLocalStore(path.join(process.cwd(), 'data', 'archetypes')),\n * });\n */\nconst createValidator: (options: ValidatorOptions) => Promise = async ({\n\tcache = !DEV,\n\tstore\n}) => {\n\tconst archetypeCache = cache ? new Map() : undefined;\n\n\tconst archetypeSchema = await store.load('archetype');\n\n\tconst { errors, valid } = validateArchetype(archetypeSchema, archetypeSchema);\n\n\tif (!valid) {\n\t\tthrow new Error('Invalid archetype schema', { cause: errors });\n\t}\n\n\tconst validator: ArchetypeValidator = {\n\t\tarchetypeSchema,\n\n\t\tloadArchetype: async (name, { cache } = {}) => {\n\t\t\tif (cache !== false && archetypeCache?.has(name)) {\n\t\t\t\treturn archetypeCache.get(name)!;\n\t\t\t}\n\n\t\t\tconst archetype = await store.load(name);\n\n\t\t\tif (cache !== false) {\n\t\t\t\tarchetypeCache?.set(name, archetype);\n\t\t\t}\n\n\t\t\tconst loadedArchetypes = new Map();\n\n\t\t\tconst loadArchetypeRecursive = async (names: string[] = []) => {\n\t\t\t\tfor (const name of names) {\n\t\t\t\t\tif (loadedArchetypes.has(name)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst archetype = await store.load(name);\n\n\t\t\t\t\tloadedArchetypes.set(name, archetype);\n\n\t\t\t\t\tif (archetype.extends) {\n\t\t\t\t\t\tawait loadArchetypeRecursive(archetype.extends);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tawait loadArchetypeRecursive(archetype.extends);\n\n\t\t\treturn extendArchetype(archetype, Array.from(loadedArchetypes.values()));\n\t\t},\n\n\t\tvalidateArchetype: async (archetype) => validateArchetype(archetype, archetypeSchema),\n\n\t\tvalidateFrontmatter: async (frontmatter) => validateFrontmatter(frontmatter, validator)\n\t};\n\n\treturn validator;\n};\n\nexport default createValidator;\n"]} \ No newline at end of file diff --git a/package.json b/package.json index a696bd8..245913b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@typematter/archetype", - "version": "0.0.1-next.7", + "version": "0.0.1-next.8", "description": "Archetype system for validating frontmatter.", "private": false, "type": "module",