@bufbuild/protovalidate
Version:
Protocol Buffer Validation for ECMAScript
197 lines (196 loc) • 8.08 kB
JavaScript
"use strict";
// Copyright 2024-2025 Buf Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRuleScalarType = getRuleScalarType;
exports.getRuleDescriptor = getRuleDescriptor;
exports.getListRules = getListRules;
exports.getMapRules = getMapRules;
exports.getEnumRules = getEnumRules;
exports.getMessageRules = getMessageRules;
exports.getScalarRules = getScalarRules;
const protobuf_1 = require("@bufbuild/protobuf");
const wkt_1 = require("@bufbuild/protobuf/wkt");
const validate_pb_js_1 = require("./gen/buf/validate/validate_pb.js");
const error_js_1 = require("./error.js");
const messageToRuleType = new Map([
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
]);
const scalarToRuleType = new Map([
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
]);
const ruleMessageTypeToScalarType = new Map([
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
]);
/**
* Get the ScalarType for one of the buf.validate.*Rules messages.
*/
function getRuleScalarType(rule) {
return ruleMessageTypeToScalarType.get(rule.$typeName);
}
/**
* Get the descriptor for one of the buf.validate.*Rules messages.
*/
function getRuleDescriptor(typeName) {
for (const d of [
validate_pb_js_1.FloatRulesSchema,
validate_pb_js_1.DoubleRulesSchema,
validate_pb_js_1.Int32RulesSchema,
validate_pb_js_1.Int64RulesSchema,
validate_pb_js_1.UInt32RulesSchema,
validate_pb_js_1.UInt64RulesSchema,
validate_pb_js_1.SInt32RulesSchema,
validate_pb_js_1.SInt64RulesSchema,
validate_pb_js_1.Fixed32RulesSchema,
validate_pb_js_1.Fixed64RulesSchema,
validate_pb_js_1.SFixed32RulesSchema,
validate_pb_js_1.SFixed64RulesSchema,
validate_pb_js_1.BoolRulesSchema,
validate_pb_js_1.StringRulesSchema,
validate_pb_js_1.BytesRulesSchema,
validate_pb_js_1.EnumRulesSchema,
validate_pb_js_1.RepeatedRulesSchema,
validate_pb_js_1.MapRulesSchema,
validate_pb_js_1.AnyRulesSchema,
validate_pb_js_1.DurationRulesSchema,
validate_pb_js_1.TimestampRulesSchema,
]) {
if (typeName == d.typeName) {
return d;
}
}
throw new Error(`unable to find descriptor for ${typeName}`);
}
/**
* Get buf.validate.RepeatedRules from FieldRules.
* Returns a tuple with rules, and path to the rules.
* Throws an error if the FieldRules has incompatible rules.
*/
function getListRules(rulePath, fieldRules, fieldContext) {
const listRules = getRulePath(rulePath, "repeated");
return [
getRules(fieldRules, "repeated", fieldContext),
listRules,
listRules.clone().field(validate_pb_js_1.RepeatedRulesSchema.field.items),
];
}
/**
* Get buf.validate.MapRules from FieldRules.
* Returns a tuple with rules, and path to the rules.
* Throws an error if the FieldRules has incompatible rules.
*/
function getMapRules(rulePath, fieldRules, fieldContext) {
const mapRules = getRulePath(rulePath, "map");
return [
getRules(fieldRules, "map", fieldContext),
mapRules,
mapRules.clone().field(validate_pb_js_1.MapRulesSchema.field.keys),
mapRules.clone().field(validate_pb_js_1.MapRulesSchema.field.values),
];
}
/**
* Get buf.validate.EnumRules from FieldRules.
* Returns a tuple with rules, and path to the rules.
* Throws an error if the FieldRules has incompatible rules.
*/
function getEnumRules(rulePath, fieldRules, fieldContext) {
return [
getRules(fieldRules, "enum", fieldContext),
getRulePath(rulePath, "enum"),
];
}
/**
* Get buf.validate.*Rules for the given message type from FieldRules.
* Returns a tuple with rules, and path to the rules.
* Throws an error if the FieldRules has incompatible rules.
*/
function getMessageRules(descMessage, rulePath, fieldRules, fieldContext) {
const type = messageToRuleType.get(descMessage.typeName);
return [
getRules(fieldRules, type, fieldContext),
getRulePath(rulePath, type),
];
}
/**
* Get buf.validate.*Rules for the given scalar type from FieldRules.
* Returns a tuple with rules, and path to the rules.
* Throws an error if the FieldRules has incompatible rules.
*/
function getScalarRules(scalar, rulePath, fieldRules, fieldContext) {
const type = scalarToRuleType.get(scalar);
return [
getRules(fieldRules, type, fieldContext),
getRulePath(rulePath, type),
];
}
function getRulePath(base, type) {
if (type == undefined) {
return base;
}
const field = validate_pb_js_1.FieldRulesSchema.fields.find((f) => f.name === type);
if (field == undefined) {
throw new error_js_1.CompilationError(`cannot find rule "${type}"`);
}
return base.clone().field(field);
}
function getRules(fieldRules, want, context) {
const got = fieldRules?.type.case;
if (fieldRules == undefined || got == undefined) {
return undefined;
}
if (got != want) {
throw new error_js_1.CompilationError(want == undefined
? `rule "${got}" cannot be used on ${context.toString()}`
: `expected rule "${want}", got "${got}" on ${context.toString()}`);
}
return fieldRules.type.value;
}