@bufbuild/cel
Version:
A CEL evaluator for ECMAScript
167 lines (166 loc) • 4.66 kB
JavaScript
;
// 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.DURATION = exports.TIMESTAMP = exports.CelScalar = void 0;
exports.mapType = mapType;
exports.listType = listType;
exports.typeType = typeType;
exports.objectType = objectType;
exports.celType = celType;
exports.isCelType = isCelType;
exports.isObjectCelType = isObjectCelType;
const list_js_1 = require("./list.js");
const map_js_1 = require("./map.js");
const uint_js_1 = require("./uint.js");
const reflect_1 = require("@bufbuild/protobuf/reflect");
const wkt_1 = require("@bufbuild/protobuf/wkt");
const privateSymbol = Symbol.for("@bufbuild/cel/type");
/**
* Scalar CEL value types.
*/
// biome-ignore format: indented for readability
exports.CelScalar = {
INT: celScalarType("int"),
UINT: celScalarType("uint"),
BOOL: celScalarType("bool"),
STRING: celScalarType("string"),
BYTES: celScalarType("bytes"),
DOUBLE: celScalarType("double"),
NULL: celScalarType("null_type"),
DYN: celScalarType("dyn"),
TYPE: celScalarType("type"),
};
/**
* Represents the CEL type google.protobuf.Timestamp.
*/
exports.TIMESTAMP = objectType(wkt_1.TimestampSchema);
/**
* Represents the CEL type google.protobuf.Duration.
*/
exports.DURATION = objectType(wkt_1.DurationSchema);
/**
* Creates a new CelMapType.
*/
function mapType(key, value) {
return {
[privateSymbol]: {},
kind: "map",
key,
value,
name: "map",
toString() {
return `map(${key}, ${value})`;
},
};
}
/**
* Creates a new CelListType.
*/
function listType(element) {
return {
[privateSymbol]: {},
kind: "list",
element,
name: "list",
toString() {
return `list(${element})`;
},
};
}
/**
* Creates a new CelTypeType
*/
function typeType(type) {
return {
[privateSymbol]: {},
kind: "type",
type,
name: "type",
toString() {
return "type";
},
};
}
/**
* Creates a new CelObjectType.
*/
function objectType(desc) {
return {
[privateSymbol]: {},
kind: "object",
desc,
name: desc.typeName,
toString() {
return desc.name;
},
};
}
function celScalarType(scalar) {
return {
[privateSymbol]: {},
kind: "scalar",
scalar,
name: scalar,
toString() {
return scalar;
},
};
}
/**
* Get the CelType of a CelValue.
*/
function celType(v) {
switch (typeof v) {
case "bigint":
return exports.CelScalar.INT;
case "boolean":
return exports.CelScalar.BOOL;
case "number":
return exports.CelScalar.DOUBLE;
case "string":
return exports.CelScalar.STRING;
case "object":
switch (true) {
case v === null:
return exports.CelScalar.NULL;
case v instanceof Uint8Array:
return exports.CelScalar.BYTES;
case (0, reflect_1.isReflectMessage)(v):
return objectType(v.desc);
case (0, list_js_1.isCelList)(v):
return listType(exports.CelScalar.DYN);
case (0, map_js_1.isCelMap)(v):
return mapType(exports.CelScalar.DYN, exports.CelScalar.DYN);
case (0, uint_js_1.isCelUint)(v):
return exports.CelScalar.UINT;
default:
// This can also be a case statement, but TS fails to
// narrow the type.
if (isObjectCelType(v)) {
return typeType(v);
}
}
}
throw new Error(`Not a CEL value: ${v}`);
}
/**
* Returns true if the given value is a CelType.
*/
function isCelType(v) {
return typeof v === "object" && v !== null && isObjectCelType(v);
}
function isObjectCelType(v) {
return privateSymbol in v;
}