@genkit-ai/core
Version:
Genkit AI framework core libraries.
261 lines (256 loc) • 8.83 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var schema_exports = {};
__export(schema_exports, {
ValidationError: () => ValidationError,
annotateSchema: () => annotateSchema,
defineJsonSchema: () => defineJsonSchema,
defineSchema: () => defineSchema,
parseSchema: () => parseSchema,
toJsonSchema: () => toJsonSchema,
validateSchema: () => validateSchema,
z: () => import_zod.z
});
module.exports = __toCommonJS(schema_exports);
var import_json_schema = require("@cfworker/json-schema");
var import_ajv = __toESM(require("ajv"));
var import_ajv_formats = __toESM(require("ajv-formats"));
var import_zod = require("zod");
var import_zod_to_json_schema = __toESM(require("zod-to-json-schema"));
var import_config = require("./config.js");
var import_error = require("./error.js");
const ajv = new import_ajv.default();
(0, import_ajv_formats.default)(ajv);
const jsonSchemas = /* @__PURE__ */ new WeakMap();
const ajvValidators = /* @__PURE__ */ new WeakMap();
const cfWorkerValidators = /* @__PURE__ */ new WeakMap();
const schemaAnnotations = /* @__PURE__ */ new WeakMap();
function annotateSchema(schema, annotations) {
const current = schemaAnnotations.get(schema) || {};
schemaAnnotations.set(schema, { ...current, ...annotations });
return schema;
}
class ValidationError extends import_error.GenkitError {
constructor({
data,
errors,
schema
}) {
super({
status: "INVALID_ARGUMENT",
message: `Schema validation failed. Parse Errors:
${errors.map((e) => `- ${e.path}: ${e.message}`).join("\n")}
Provided data:
${JSON.stringify(data, null, 2)}
Required JSON schema:
${JSON.stringify(schema, null, 2)}`,
detail: { errors, schema }
});
}
}
function toJsonSchema({
jsonSchema,
schema
}) {
if (!jsonSchema && !schema) return null;
if (jsonSchema) return jsonSchema;
if (jsonSchemas.has(schema)) return jsonSchemas.get(schema);
const outSchema = (0, import_zod_to_json_schema.default)(schema, {
removeAdditionalStrategy: "strict"
});
const annotatedSchema = applyAnnotations(schema, outSchema);
jsonSchemas.set(schema, annotatedSchema);
return annotatedSchema;
}
function applyAnnotations(schema, json) {
if (!json || typeof json !== "object") return json;
const annotationsToApply = [];
let current = schema;
while (current) {
const ann = schemaAnnotations.get(current);
if (ann) annotationsToApply.push(ann);
if (current instanceof import_zod.z.ZodOptional || current instanceof import_zod.z.ZodNullable || current instanceof import_zod.z.ZodDefault || current instanceof import_zod.z.ZodEffects) {
current = current._def.innerType || current._def.schema;
} else {
break;
}
}
const resolvedAnnotations = {};
for (let i = annotationsToApply.length - 1; i >= 0; i--) {
Object.assign(resolvedAnnotations, annotationsToApply[i]);
}
for (const key in resolvedAnnotations) {
if (Object.prototype.hasOwnProperty.call(json, key)) {
console.warn(
`Annotation key "${key}" conflicts with existing JSON schema property and will be ignored.`
);
continue;
}
json[key] = resolvedAnnotations[key];
}
const inner = current;
if (inner instanceof import_zod.z.ZodObject && json.properties) {
for (const key in inner.shape) {
if (json.properties[key]) {
applyAnnotations(inner.shape[key], json.properties[key]);
}
}
} else if (inner instanceof import_zod.z.ZodArray && json.items) {
applyAnnotations(inner.element, json.items);
} else if (inner instanceof import_zod.z.ZodUnion && json.anyOf) {
for (let i = 0; i < inner.options.length; i++) {
applyAnnotations(inner.options[i], json.anyOf[i]);
}
} else if (inner instanceof import_zod.z.ZodIntersection && json.allOf) {
const schemas = [];
const collect = (s) => {
if (s instanceof import_zod.z.ZodIntersection) {
collect(s._def.left);
collect(s._def.right);
} else {
schemas.push(s);
}
};
collect(inner);
if (schemas.length === json.allOf.length) {
for (let i = 0; i < schemas.length; i++) {
applyAnnotations(schemas[i], json.allOf[i]);
}
}
} else if (inner instanceof import_zod.z.ZodRecord && json.additionalProperties) {
applyAnnotations(inner.valueSchema, json.additionalProperties);
} else if (inner instanceof import_zod.z.ZodTuple && Array.isArray(json.items)) {
for (let i = 0; i < inner.items.length; i++) {
applyAnnotations(inner.items[i], json.items[i]);
}
} else if (inner instanceof import_zod.z.ZodDiscriminatedUnion && json.anyOf) {
for (let i = 0; i < inner.options.length; i++) {
applyAnnotations(inner.options[i], json.anyOf[i]);
}
}
return json;
}
function ajvErrorToValidationErrorDetail(error) {
return {
path: error.instancePath.substring(1).replace(/\//g, ".") || "(root)",
message: error.message
};
}
function cfWorkerErrorToValidationErrorDetail(error) {
const path = error.instanceLocation.startsWith("#/") ? error.instanceLocation.substring(2) : "";
return {
path: path.replace(/\//g, ".") || "(root)",
message: error.error
};
}
function validateSchema(data, options) {
const toValidate = toJsonSchema(options);
if (!toValidate) {
return { valid: true, schema: toValidate };
}
const validationMode = (0, import_config.getGenkitRuntimeConfig)().jsonSchemaMode;
if (validationMode === "interpret") {
let validator2 = cfWorkerValidators.get(toValidate);
if (!validator2) {
validator2 = new import_json_schema.Validator(toValidate);
cfWorkerValidators.set(toValidate, validator2);
}
const result = validator2.validate(sanitizeForJsonSchema(data));
if (!result.valid) {
return {
valid: false,
errors: result.errors.map(cfWorkerErrorToValidationErrorDetail),
schema: toValidate
};
}
return {
valid: result.valid,
schema: toValidate
};
}
let validator = ajvValidators.get(toValidate);
if (!validator) {
validator = ajv.compile(toValidate);
ajvValidators.set(toValidate, validator);
}
const valid = validator(data);
if (!valid) {
return {
valid: false,
errors: (validator.errors ?? []).map(ajvErrorToValidationErrorDetail),
schema: toValidate
};
}
return { valid, schema: toValidate };
}
function parseSchema(data, options) {
const result = validateSchema(data, options);
if (!result.valid) {
throw new ValidationError({
data,
errors: result.errors,
schema: result.schema
});
}
return data;
}
function defineSchema(registry, name, schema) {
registry.registerSchema(name, { schema });
return schema;
}
function defineJsonSchema(registry, name, jsonSchema) {
registry.registerSchema(name, { jsonSchema });
return jsonSchema;
}
function sanitizeForJsonSchema(data) {
if (Array.isArray(data)) {
return data.map(sanitizeForJsonSchema);
} else if (data !== null && typeof data === "object") {
const out = {};
for (const key in data) {
if (data[key] !== void 0) {
out[key] = sanitizeForJsonSchema(data[key]);
}
}
return out;
}
return data;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ValidationError,
annotateSchema,
defineJsonSchema,
defineSchema,
parseSchema,
toJsonSchema,
validateSchema,
z
});
//# sourceMappingURL=schema.js.map