fix(config): support uri formats in schema validation

This commit is contained in:
Peter Steinberger
2026-03-27 02:25:28 +00:00
parent 0b94382930
commit 465f830bcd
3 changed files with 90 additions and 0 deletions

View File

@@ -231,4 +231,43 @@ describe("schema validator", () => {
expect(issue?.text).not.toContain("\x1b");
}
});
it("supports uri-formatted string schemas", () => {
const valid = validateJsonSchemaValue({
cacheKey: "schema-validator.test.uri.valid",
schema: {
type: "object",
properties: {
apiRoot: {
type: "string",
format: "uri",
},
},
required: ["apiRoot"],
},
value: { apiRoot: "https://api.telegram.org" },
});
expect(valid.ok).toBe(true);
const invalid = validateJsonSchemaValue({
cacheKey: "schema-validator.test.uri.invalid",
schema: {
type: "object",
properties: {
apiRoot: {
type: "string",
format: "uri",
},
},
required: ["apiRoot"],
},
value: { apiRoot: "not a uri" },
});
expect(invalid.ok).toBe(false);
if (!invalid.ok) {
expect(invalid.errors.find((entry) => entry.path === "apiRoot")?.message).toContain(
"must match format",
);
}
});
});

View File

@@ -5,6 +5,15 @@ import { sanitizeTerminalText } from "../terminal/safe-text.js";
const require = createRequire(import.meta.url);
type AjvLike = {
addFormat: (
name: string,
format:
| RegExp
| {
type?: string;
validate: (value: string) => boolean;
},
) => AjvLike;
compile: (schema: Record<string, unknown>) => ValidateFunction;
};
const ajvSingletons = new Map<"default" | "defaults", AjvLike>();
@@ -25,6 +34,19 @@ function getAjv(mode: "default" | "defaults"): AjvLike {
removeAdditional: false,
...(mode === "defaults" ? { useDefaults: true } : {}),
});
instance.addFormat("uri", {
type: "string",
validate: (value: string) => {
try {
// Accept absolute URIs so generated config schemas can keep JSON Schema
// `format: "uri"` without noisy AJV warnings during validation/build.
new URL(value);
return true;
} catch {
return false;
}
},
});
ajvSingletons.set(mode, instance);
return instance;
}